Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 63.2% 999 / 0 / 1580
Functions: -% 0 / 1 / 1
Branches: 49.3% 450 / 0 / 912

OMCompiler/Compiler/BackEnd/BackendDAEOptimize.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 BackendDAEOptimize
37 " file: BackendDAEOptimize.mo
38 package: BackendDAEOptimize
39 description: BackendDAEOptimize contains functions that do some kind of
40 optimization on the BackendDAE datatype:
41 - removing simpleEquations
42 - Tearing/Relaxation
43 - Linearization
44 - Inline Integration
45 - and so on ..."
46
47 public import Absyn;
48 public import AbsynUtil;
49 public import BackendDAE;
50 public import DAE;
51 public import HashTable2;
52
53 protected
54 import AdjacencyMatrix;
55 import Algorithm;
56 import Array;
57 import BackendDAETransform;
58 import BackendDAEUtil;
59 import BackendDump;
60 import BackendEquation;
61 import BackendDAEEXT;
62 import BackendInline;
63 import BackendVarTransform;
64 import BackendVariable;
65 import BaseHashTable;
66 import CheckModel;
67 import ClassInf;
68 import ComponentReference;
69 import ComponentReferenceBasics;
70 import DAEUtil;
71 import DAEDump;
72 import DoubleEnded;
73 import Differentiate;
74 import ElementSource;
75 import ExpandableArray;
76 import Expression;
77 protected import ExpressionBasics;
78 import ExpressionDump;
79 import ExpressionSolve;
80 import ExpressionSimplify;
81 import Error;
82 import Flags;
83 import GCExt;
84 import HashSet;
85 import HashTableExpToIndex;
86 import HpcOmTaskGraph;
87 import Inline;
88 import List;
89 import Matching;
90 import MetaModelica.Dangerous;
91 import Mutable;
92 import RewriteRules;
93 import SCode;
94 import SynchronousFeatures;
95 import Tearing;
96 import Types;
97 import UnorderedMap;
98 import Util;
99 import Values;
100
101 public function simplifyAllExpressions "author: lochel"
102 input BackendDAE.BackendDAE inDAE;
103 output BackendDAE.BackendDAE outDAE = inDAE;
104 protected
105 list<BackendDAE.Equation> removedEqsList = {};
106 BackendDAE.Shared shared;
107 algorithm
108 2190 BackendDAEUtil.traverseBackendDAEExpsNoCopyWithUpdate(outDAE, ExpressionSimplify.simplify1TraverseHelper, 0);
109
110 // filter empty algorithms
111 2190 shared := outDAE.shared;
112
2/2
✓ Branch 1 taken 1656 times.
✓ Branch 2 taken 2190 times.
3846 for eq in BackendEquation.equationList(shared.removedEqs) loop
113 removedEqsList := match eq
114 case BackendDAE.ALGORITHM(alg=DAE.ALGORITHM_STMTS(statementLst={})) then removedEqsList;
115 else eq::removedEqsList;
116 end match;
117 end for;
118 2190 shared.removedEqs := BackendEquation.listEquation(MetaModelica.Dangerous.listReverseInPlace(removedEqsList));
119 2190 outDAE.shared := shared;
120 end simplifyAllExpressions;
121
122 // =============================================================================
123 // simplifyInStream
124 //
125 // OM introduces $OMC$PositiveMax which can simplified using min or max attribute
126 // see Modelica spec for inStream
127 // author: Vitalij Ruge
128 // see. #3885, 4441, 5104
129 // =============================================================================
130
131 public function simplifyInStream
132 input output BackendDAE.BackendDAE dae;
133 protected
134 BackendDAE.Shared shared = dae.shared;
135 BackendDAE.EqSystems eqs = dae.eqs;
136 list<BackendDAE.Variables> vars = list(eq.orderedVars for eq in eqs);
137 algorithm
138 // from the description inputs are part of globalKnownVars and localKnownVars :(
139 16 vars := shared.globalKnownVars :: vars; // need inputs with min = 0 or max = 0
140 16 vars := shared.localKnownVars :: vars;
141 16 BackendDAEUtil.traverseBackendDAEExpsNoCopyWithUpdate(dae, simplifyInStreamWork, vars);
142 end simplifyInStream;
143
144 protected function simplifyInStreamWork
145 input DAE.Exp inExp;
146 input list<BackendDAE.Variables> inVars;
147 output DAE.Exp outExp;
148 output list<BackendDAE.Variables> outVars = inVars;
149 algorithm
150 49374 outExp := Expression.traverseExpBottomUp(inExp, simplifyInStreamWork2, outVars);
151
152 // with #5104 we remove max(x, eps)
153 // so in case max(x,eps)*y/max(x,eps) => x*y/x
154 // now x can be equal 0, so we need simplify x*y/x = y
155 // it's seem no other models silplyfied it
156
2/2
✓ Branch 1 taken 49256 times.
✓ Branch 2 taken 118 times.
49374 if not ExpressionBasics.expEqual(outExp, inExp) then
157 118 outExp := ExpressionSimplify.simplify(outExp);
158 end if;
159 end simplifyInStreamWork;
160
161 protected function simplifyInStreamWork2
162 input DAE.Exp inExp;
163 input list<BackendDAE.Variables> inVars;
164 output DAE.Exp outExp;
165 output list<BackendDAE.Variables> outVars = inVars;
166 algorithm
167 outExp := match inExp
168 local
169 DAE.Type tp;
170 DAE.ComponentRef cr;
171 DAE.Exp e, expr, ret;
172 Option<DAE.Exp> eMin, eMax;
173
174 // positiveMax(cref, eps) = 0 if variable(cref).max <= 0
175 // positiveMax(cref, eps) = cref if variable(cref).min >= eps
176 case DAE.CALL(path = Absyn.IDENT("$OMC$PositiveMax"), expLst = {e as DAE.CREF(componentRef = cr), expr}) algorithm
177 294 (eMin, eMax) := simplifyInStreamGetMinMaxAttributes(cr, outVars);
178 294 tp := ComponentReference.crefTypeFull(cr);
179
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 294 times.
✓ Branch 7 taken 294 times.
✗ Branch 8 not taken.
588 ret := if Util.applyOptionOrDefault(eMax, Expression.isNegativeOrZero, false) then Expression.createZeroExpression(tp)
180 elseif Util.applyOptionOrDefault(eMin, function Expression.isGreaterOrEqual(exp2 = expr), false) then e
181 else Expression.makePureBuiltinCall("max", {e, expr}, tp);
182 then ret;
183
184 // positiveMax(-cref, eps) = 0 if variable(cref).min >= 0
185 // positiveMax(-cref, eps) = -cref if variable(cref).max <= -eps
186 case DAE.CALL(path = Absyn.IDENT("$OMC$PositiveMax"), expLst = {e as DAE.UNARY(DAE.UMINUS(tp), DAE.CREF(componentRef = cr)), expr}) algorithm
187 274 (eMin, eMax) := simplifyInStreamGetMinMaxAttributes(cr, outVars);
188
3/4
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 270 times.
✓ Branch 8 taken 270 times.
✗ Branch 9 not taken.
544 ret := if Util.applyOptionOrDefault(eMin, Expression.isPositiveOrZero, false) then Expression.createZeroExpression(tp)
189 elseif Util.applyOptionOrDefault(eMax, function Expression.isGreaterOrEqual(exp1 = Expression.negate(expr)), false) then e
190 else Expression.makePureBuiltinCall("max", {e, expr}, tp);
191 then ret;
192
193 // positiveMax(cref, eps) = max(cref,eps) in the general case
194 case DAE.CALL(path = Absyn.IDENT("$OMC$PositiveMax"), expLst = {e, expr})
195 ✗ then Expression.makePureBuiltinCall("max", {e, expr}, Expression.typeof(e));
196
197 case DAE.CALL(path = Absyn.IDENT("$OMC$inStreamDiv"), expLst = {e, expr}) algorithm
198 123 e := ExpressionSimplify.simplify(e);
199 ret := match e
200 local
201 DAE.Exp a,b;
202 case DAE.BINARY(a, DAE.DIV(), b) guard Expression.isZero(a) and Expression.isZero(b)
203 then expr;
204 else e;
205 end match;
206 then ret;
207
208 else inExp;
209 end match;
210 end simplifyInStreamWork2;
211
212 protected function simplifyInStreamGetMinMaxAttributes
213 input DAE.ComponentRef cr;
214 input list<BackendDAE.Variables> inVars;
215 output Option<DAE.Exp> outMin = NONE();
216 output Option<DAE.Exp> outMax = NONE();
217 protected
218 BackendDAE.Var v;
219 algorithm
220
2/2
✓ Branch 0 taken 1784 times.
✓ Branch 1 taken 568 times.
2352 for vars in inVars loop
221 try
222 1784 (v, _) := BackendVariable.getVarSingle(cr, vars);
223 568 (outMin, outMax) := BackendVariable.getMinMaxAttribute(v);
224 break;
225 else
226 // search
227 end try;
228 end for;
229 end simplifyInStreamGetMinMaxAttributes;
230
231 // =============================================================================
232 // simplify time independent function calls
233 //
234 // public functions:
235 // - simplifyTimeIndepFuncCalls
236 // =============================================================================
237
238 public function simplifyTimeIndepFuncCalls "author: Frenkel TUD 2012-06
239 pre(param) -> param
240 der(param) -> 0.0
241 change(param) -> false
242 edge(param) -> false"
243 input BackendDAE.BackendDAE inDAE;
244 output BackendDAE.BackendDAE outDAE;
245 algorithm
246 2824 (outDAE, _) := BackendDAEUtil.mapEqSystemAndFold(inDAE, simplifyTimeIndepFuncCalls0, false);
247 2824 outDAE := simplifyTimeIndepFuncCallsShared(outDAE);
248 end simplifyTimeIndepFuncCalls;
249
250 protected function simplifyTimeIndepFuncCalls0 "author: Frenkel TUD 2012-06"
251 input BackendDAE.EqSystem isyst;
252 input BackendDAE.Shared inShared;
253 input Boolean inChanged;
254 output BackendDAE.EqSystem osyst;
255 output BackendDAE.Shared outShared;
256 output Boolean outChanged;
257 algorithm
258 (osyst, outShared, outChanged) := matchcontinue (isyst, inShared)
259 local
260 BackendDAE.Shared shared;
261 BackendDAE.EqSystem syst;
262
263 case (syst, shared)
264 algorithm
265
2/2
✓ Branch 3 taken 5679 times.
✓ Branch 4 taken 13 times.
5692 (_, (_, _, true)) := BackendDAEUtil.traverseBackendDAEExpsEqns (
266 syst.orderedEqs, Expression.traverseSubexpressionsHelper, (traverserExpsimplifyTimeIndepFuncCalls,
267 (shared.globalKnownVars, shared.aliasVars, false))
268 );
269
1/2
✓ Branch 3 taken 13 times.
✗ Branch 4 not taken.
13 (_, (_, _, true)) := BackendDAEUtil.traverseBackendDAEExpsEqns (
270 syst.removedEqs, Expression.traverseSubexpressionsHelper, (traverserExpsimplifyTimeIndepFuncCalls,
271 (shared.globalKnownVars, shared.aliasVars, false))
272 );
273 then (isyst, inShared, true);
274
275 else (isyst, inShared, inChanged);
276 end matchcontinue;
277 end simplifyTimeIndepFuncCalls0;
278
279 protected function traverserExpsimplifyTimeIndepFuncCalls
280 input DAE.Exp inExp;
281 input tuple<BackendDAE.Variables, BackendDAE.Variables, Boolean> inTpl;
282 output DAE.Exp outExp;
283 output tuple<BackendDAE.Variables, BackendDAE.Variables, Boolean> outTpl;
284 algorithm
285 (outExp, outTpl) := matchcontinue (inExp, inTpl)
286 local
287 BackendDAE.Variables globalKnownVars, aliasvars;
288 DAE.Type tp;
289 DAE.Exp e, zero;
290 DAE.ComponentRef cr;
291 BackendDAE.Var var;
292 DAE.CallAttributes attr;
293 Boolean negate;
294 String idn;
295
296 case (DAE.CALL(path=Absyn.IDENT(name="der"), expLst={DAE.CREF(componentRef=cr, ty=tp)}), (globalKnownVars, aliasvars, _)) algorithm
297 9422 (var, _) := BackendVariable.getVarSingle(cr, globalKnownVars);
298 ✗ false := BackendVariable.isVarOnTopLevelAndInput(var);
299 ✗ (zero, _) := Expression.makeZeroExpression(Expression.arrayDimension(tp));
300 ✗ then (zero, (globalKnownVars, aliasvars, true));
301
302 case (DAE.CALL(path=Absyn.IDENT(name=idn), expLst={e as DAE.CREF(componentRef=cr)}), (globalKnownVars, aliasvars, _)) guard idn=="pre" or idn=="previous"
303 algorithm
304 2561 (var, _) := BackendVariable.getVarSingle(cr, globalKnownVars);
305 /* https://github.com/OpenModelica/OpenModelica/issues/13811
306 * check if var is a top level input and keep the expression as it pre(param) = pre(param)
307 * for parameter and constat apply pre(param) = param
308 */
309
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 43 times.
43 false := BackendVariable.isInput(var);
310 43 then(e, (globalKnownVars, aliasvars, true));
311
312 case (DAE.CALL(path=Absyn.IDENT(name=idn), expLst={e as DAE.CREF(componentRef=DAE.CREF_IDENT(ident="time"))}), (globalKnownVars, aliasvars, _)) guard idn=="pre" or idn=="previous"
313 ✗ then (e, (globalKnownVars, aliasvars, true));
314
315 case (DAE.CALL(path=Absyn.IDENT(name=idn), expLst={e as DAE.UNARY(DAE.UMINUS(_), DAE.CREF(componentRef=DAE.CREF_IDENT(ident="time")))}), (globalKnownVars, aliasvars, _)) guard idn=="pre" or idn=="previous"
316 ✗ then (e, (globalKnownVars, aliasvars, true));
317
318 case (DAE.CALL(path=Absyn.IDENT(name=idn), expLst={DAE.CREF(componentRef=cr, ty=tp)}, attr=attr), (globalKnownVars, aliasvars, _)) guard idn=="pre" or idn=="previous" algorithm
319 2518 (var, _) := BackendVariable.getVarSingle(cr, aliasvars);
320 ✗ (cr, negate) := BackendVariable.getAlias(var);
321 ✗ e := DAE.CREF(cr, tp);
322 ✗ e := if negate then Expression.negate(e) else e;
323 ✗ (e, _) := ExpressionSimplify.simplify(DAE.CALL(Absyn.IDENT(idn), {e}, attr));
324 ✗ (e, _) := Expression.traverseExpBottomUp(e, traverserExpsimplifyTimeIndepFuncCalls, (globalKnownVars, aliasvars, false));
325 ✗ then (e, (globalKnownVars, aliasvars, true));
326
327 case (DAE.CALL(path=Absyn.IDENT(name=idn), expLst={DAE.CREF(componentRef=cr, ty=tp)}), (globalKnownVars, aliasvars, _)) guard idn=="change" or idn=="edge" algorithm
328 ✗ (_::_, _) := BackendVariable.getVar(cr, globalKnownVars);
329 ✗ zero := Expression.arrayFill(Expression.arrayDimension(tp), DAE.BCONST(false));
330 ✗ then (zero, (globalKnownVars, aliasvars, true));
331
332 case (DAE.CALL(path=Absyn.IDENT(name=idn), expLst={DAE.CREF(componentRef=cr, ty=tp)}), (globalKnownVars, aliasvars, _)) guard idn=="change" or idn=="edge" algorithm
333 ✗ (_::_, _) := BackendVariable.getVar(cr, aliasvars);
334 ✗ zero := Expression.arrayFill(Expression.arrayDimension(tp), DAE.BCONST(false));
335 ✗ then (zero, (globalKnownVars, aliasvars, true));
336
337 case (DAE.CALL(path=Absyn.IDENT(name=idn), expLst={DAE.CREF(componentRef=DAE.CREF_IDENT(ident="time"))}), (globalKnownVars, aliasvars, _)) guard idn=="change" or idn=="edge"
338 ✗ then (DAE.BCONST(false), (globalKnownVars, aliasvars, true));
339
340 case (DAE.CALL(path=Absyn.IDENT(name=idn), expLst={DAE.CREF(componentRef=cr, ty=tp)}, attr=attr), (globalKnownVars, aliasvars, _)) guard idn=="change" or idn=="edge" algorithm
341 ✗ (var, _) := BackendVariable.getVarSingle(cr, aliasvars);
342 ✗ (cr, negate) := BackendVariable.getAlias(var);
343 ✗ e := DAE.CREF(cr, tp);
344 ✗ e := if negate then Expression.negate(e) else e;
345 ✗ (e, _) := ExpressionSimplify.simplify(DAE.CALL(Absyn.IDENT(idn), {e}, attr));
346 ✗ (e, _) := Expression.traverseExpBottomUp(e, traverserExpsimplifyTimeIndepFuncCalls, (globalKnownVars, aliasvars, false));
347 ✗ then (e, (globalKnownVars, aliasvars, true));
348
349 else (inExp, inTpl);
350 end matchcontinue;
351 end traverserExpsimplifyTimeIndepFuncCalls;
352
353 protected function simplifyTimeIndepFuncCallsShared "pre(param) -> param
354 der(param) -> 0.0
355 change(param) -> false
356 edge(param) -> false
357 author: Frenkel TUD 2012-06"
358 input BackendDAE.BackendDAE inDAE;
359 output BackendDAE.BackendDAE outDAE;
360 protected
361 BackendDAE.Shared shared;
362 algorithm
363 2824 shared := inDAE.shared;
364 2824 BackendDAEUtil.traverseBackendDAEExpsVarsWithUpdate(shared.globalKnownVars, Expression.traverseSubexpressionsHelper, (traverserExpsimplifyTimeIndepFuncCalls, (shared.globalKnownVars, shared.aliasVars, false)));
365 2824 BackendDAEUtil.traverseBackendDAEExpsEqns(shared.initialEqs, Expression.traverseSubexpressionsHelper, (traverserExpsimplifyTimeIndepFuncCalls, (shared.globalKnownVars, shared.aliasVars, false)));
366 2824 BackendDAEUtil.traverseBackendDAEExpsEqns(shared.removedEqs, Expression.traverseSubexpressionsHelper, (traverserExpsimplifyTimeIndepFuncCalls, (shared.globalKnownVars, shared.aliasVars, false)));
367 5648 (shared.eventInfo, _) := traverseEventInfoExps(shared.eventInfo, Expression.traverseSubexpressionsHelper, (traverserExpsimplifyTimeIndepFuncCalls, (shared.globalKnownVars, shared.aliasVars, false)));
368 2824 outDAE := BackendDAE.DAE(inDAE.eqs, shared);
369 end simplifyTimeIndepFuncCallsShared;
370
371 protected function traverseEventInfoExps<T>
372 input output BackendDAE.EventInfo eventInfo;
373 input FuncExpType func;
374 input output T arg;
375 partial function FuncExpType
376 input DAE.Exp inExp;
377 input T inTypeA;
378 output DAE.Exp outExp;
379 output T outA;
380 end FuncExpType;
381 algorithm
382 2824 arg := DoubleEnded.mapFoldNoCopy(eventInfo.zeroCrossings.zc, function traverseZeroCrossingExps(func=func), arg);
383 2824 arg := DoubleEnded.mapFoldNoCopy(eventInfo.samples.zc, function traverseZeroCrossingExps(func=func), arg);
384 2824 arg := DoubleEnded.mapFoldNoCopy(eventInfo.relations.zc, function traverseZeroCrossingExps(func=func), arg);
385 end traverseEventInfoExps;
386
387 protected function traverseZeroCrossingExps<T>
388 input output BackendDAE.ZeroCrossing zc;
389 input FuncExpType func;
390 input output T arg;
391 partial function FuncExpType
392 input DAE.Exp inExp;
393 input T inTypeA;
394 output DAE.Exp outExp;
395 output T outA;
396 end FuncExpType;
397 protected
398 DAE.Exp relation;
399 algorithm
400 ✗ (relation, arg) := Expression.traverseExpBottomUp(zc.relation_, func, arg);
401 ✗ if not referenceEq(relation, zc.relation_) then
402 ✗ zc.relation_ := relation;
403 end if;
404 end traverseZeroCrossingExps;
405
406 protected function toplevelInputOrUnfixed
407 input BackendDAE.Var inVar;
408 output Boolean b;
409 algorithm
410 ✗ b := BackendVariable.isVarOnTopLevelAndInput(inVar) or
411 BackendVariable.isParam(inVar) and not BackendVariable.varFixed(inVar);
412 end toplevelInputOrUnfixed;
413
414 protected function traversingTimeEqnsFinder "author: Frenkel 2010-12"
415 input DAE.Exp inExp;
416 input tuple<Boolean,BackendDAE.Variables,BackendDAE.Variables,Boolean,Boolean> inTpl;
417 output DAE.Exp outExp;
418 output Boolean cont;
419 output tuple<Boolean,BackendDAE.Variables,BackendDAE.Variables,Boolean,Boolean> outTpl;
420 algorithm
421 (outExp,cont,outTpl) := matchcontinue (inExp,inTpl)
422 local
423 DAE.Exp e;
424 Boolean b,b1,b2;
425 BackendDAE.Variables vars,globalKnownVars;
426 DAE.ComponentRef cr;
427 BackendDAE.Var var;
428 list<BackendDAE.Var> vlst;
429
430 case (e as DAE.CREF(DAE.CREF_IDENT(ident = "time",subscriptLst = {}),_), (_,vars,globalKnownVars,b1,b2))
431 ✗ then (e,false,(true,vars,globalKnownVars,b1,b2));
432 // inputs not constant and parameter(fixed=false) are constant but evaluated after konstant variables are evaluted
433 case (e as DAE.CREF(cr,_), (_,vars,globalKnownVars,b1,b2))
434 algorithm
435 ✗ (vlst,_::_):= BackendVariable.getVar(cr, globalKnownVars) "input variables stored in known variables are input on top level";
436 ✗ false := List.none(vlst, toplevelInputOrUnfixed);
437 ✗ then (e,false,(true,vars,globalKnownVars,b1,b2));
438 ✗ case (e as DAE.CALL(path = Absyn.IDENT(name = "sample"), expLst = {_,_,_}), (_,vars,globalKnownVars,b1,b2)) then (e,false,(true,vars,globalKnownVars,b1,b2));
439 ✗ case (e as DAE.CALL(path = Absyn.IDENT(name = "pre"), expLst = {_}), (_,vars,globalKnownVars,b1,b2)) then (e,false,(true,vars,globalKnownVars,b1,b2));
440 ✗ case (e as DAE.CALL(path = Absyn.IDENT(name = "previous"), expLst = {_}), (_,vars,globalKnownVars,b1,b2)) then (e,false,(true,vars,globalKnownVars,b1,b2));
441 ✗ case (e as DAE.CALL(path = Absyn.IDENT(name = "change"), expLst = {_}), (_,vars,globalKnownVars,b1,b2)) then (e,false,(true,vars,globalKnownVars,b1,b2));
442 ✗ case (e as DAE.CALL(path = Absyn.IDENT(name = "edge"), expLst = {_}), (_,vars,globalKnownVars,b1,b2)) then (e,false,(true,vars,globalKnownVars,b1,b2));
443 // case for finding simple equation in jacobians
444 // there are all known variables mark as input
445 // and they are all time-depending
446 case (e as DAE.CREF(cr,_), (_,vars,globalKnownVars,true,b2))
447 algorithm
448 ✗ (var::_,_::_):= BackendVariable.getVar(cr, globalKnownVars);
449 ✗ DAE.INPUT() := BackendVariable.getVarDirection(var);
450 ✗ then (e,false,(true,vars,globalKnownVars,true,b2));
451 // unkown var
452 case (e as DAE.CREF(cr,_), (_,vars,globalKnownVars,b1,true))
453 algorithm
454 ✗ (_::_,_::_):= BackendVariable.getVar(cr, vars);
455 ✗ then (e,false,(true,vars,globalKnownVars,b1,true));
456 ✗ case (e,(b,_,_,_,_)) then (e,not b,inTpl);
457
458 end matchcontinue;
459 end traversingTimeEqnsFinder;
460
461 public function countSimpleEquations
462 "author: Frenkel TUD 2011-05
463 This function count the simple equations on the form a=b and a=const and a=f(not time)
464 in BackendDAE.BackendDAE. Note this functions does not use variable replacements, because
465 of this the number of simple equations is maybe smaller than using variable replacements."
466 input BackendDAE.BackendDAE inDlow;
467 input BackendDAE.AdjacencyMatrix inM;
468 output Integer outSimpleEqns;
469 algorithm
470 outSimpleEqns:=
471 match inDlow
472 local
473 BackendDAE.BackendDAE dlow;
474 Integer n;
475 case dlow
476 algorithm
477 // check equations
478 ✗ (_,(_,n)) := AdjacencyMatrix.traverseAdjacencyMatrix(inM,countSimpleEquationsFinder,(dlow,0));
479 then n;
480 end match;
481 end countSimpleEquations;
482
483 protected function countSimpleEquationsFinder
484 "author: Frenkel TUD 2011-05"
485 input BackendDAE.AdjacencyMatrixElement elem;
486 input Integer pos;
487 input tuple<BackendDAE.BackendDAE,Integer> inTpl;
488 output list<Integer> outList;
489 output tuple<BackendDAE.BackendDAE,Integer> outTpl;
490 algorithm
491 (outList,outTpl) :=
492 matchcontinue inTpl
493 local
494 Integer l,n,n_1;
495 BackendDAE.BackendDAE dae;
496 BackendDAE.EqSystem syst;
497 BackendDAE.Shared shared;
498
499 case (dae as BackendDAE.DAE({syst},shared),n)
500 algorithm
501 // check number of vars in eqns
502 ✗ l := listLength(elem);
503 ✗ true := intLt(l,3);
504 ✗ true := intGt(l,0);
505 ✗ countsimpleEquation(elem,l,pos,syst,shared);
506 ✗ n_1 := n+1;
507 ✗ then ({},(dae,n_1));
508 else ({},inTpl);
509 end matchcontinue;
510 end countSimpleEquationsFinder;
511
512 protected function countsimpleEquation
513 " author: Frenkel TUD 2011-05"
514 input BackendDAE.AdjacencyMatrixElement elem;
515 input Integer length;
516 input Integer pos;
517 input BackendDAE.EqSystem syst;
518 input BackendDAE.Shared shared;
519 algorithm
520 () := matchcontinue(elem, shared)
521 local
522 DAE.ComponentRef cr;
523 Integer i;
524 DAE.Exp cre,e1,e2;
525 BackendDAE.Variables vars,globalKnownVars;
526 BackendDAE.Var var;
527 BackendDAE.EquationArray eqns;
528 BackendDAE.Equation eqn;
529 // a = const
530 // wbraun:
531 // speacial case for Jacobains, since there are all known variablen
532 // time depending input variables
533 case ({i}, BackendDAE.SHARED(backendDAEType = BackendDAE.JACOBIAN()))
534 algorithm
535 ✗ vars := BackendVariable.daeVars(syst);
536 ✗ var := BackendVariable.getVarAt(vars,intAbs(i));
537 // no State
538 ✗ false := BackendVariable.isStateorStateDerVar(var);
539 // try to solve the equation
540 ✗ eqns := BackendEquation.getEqnsFromEqSystem(syst);
541 ✗ eqn := BackendEquation.get(eqns,pos);
542 ✗ BackendDAE.EQUATION(exp=e1,scalar=e2) := eqn;
543 // variable time not there
544 ✗ globalKnownVars := BackendVariable.daeGlobalKnownVars(shared);
545 ✗ (_,(false,_,_,_,_)) := Expression.traverseExpTopDown(e1, traversingTimeEqnsFinder, (false,vars,globalKnownVars,true,false));
546 ✗ (_,(false,_,_,_,_)) := Expression.traverseExpTopDown(e2, traversingTimeEqnsFinder, (false,vars,globalKnownVars,true,false));
547 ✗ cr := BackendVariable.varCref(var);
548 ✗ cre := Expression.crefExp(cr);
549 ✗ (_,{}) := ExpressionSolve.solve(e1,e2,cre, NONE());
550 then ();
551 // a = const
552 case ({i}, _)
553 algorithm
554 ✗ vars := BackendVariable.daeVars(syst);
555 ✗ var := BackendVariable.getVarAt(vars,intAbs(i));
556 // no State
557 ✗ false := BackendVariable.isStateorStateDerVar(var);
558 // try to solve the equation
559 ✗ eqns := BackendEquation.getEqnsFromEqSystem(syst);
560 ✗ eqn := BackendEquation.get(eqns,pos);
561 ✗ BackendDAE.EQUATION(exp=e1,scalar=e2) := eqn;
562 // variable time not there
563 ✗ globalKnownVars := BackendVariable.daeGlobalKnownVars(shared);
564 ✗ (_,(false,_,_,_,_)) := Expression.traverseExpTopDown(e1, traversingTimeEqnsFinder, (false,vars,globalKnownVars,false,false));
565 ✗ (_,(false,_,_,_,_)) := Expression.traverseExpTopDown(e2, traversingTimeEqnsFinder, (false,vars,globalKnownVars,false,false));
566 ✗ cr := BackendVariable.varCref(var);
567 ✗ cre := Expression.crefExp(cr);
568 ✗ (_,{}) := ExpressionSolve.solve(e1,e2,cre, NONE());
569 then ();
570 // a = der(b)
571 case ({_,_}, _)
572 algorithm
573 ✗ eqns := BackendEquation.getEqnsFromEqSystem(syst);
574 ✗ eqn := BackendEquation.get(eqns,pos);
575 ✗ (cr,_,_,_,_) := BackendEquation.derivativeEquation(eqn);
576 // select candidate
577 ✗ vars := BackendVariable.daeVars(syst);
578 ✗ ((_::_),(_::_)) := BackendVariable.getVar(cr,vars);
579 then ();
580 // a = b
581 case ({_,_}, _)
582 algorithm
583 ✗ eqns := BackendEquation.getEqnsFromEqSystem(syst);
584 ✗ eqn as BackendDAE.EQUATION() := BackendEquation.get(eqns,pos);
585 ✗ BackendEquation.aliasEquation(eqn);
586 then ();
587 end matchcontinue;
588 end countsimpleEquation;
589
590 // =============================================================================
591 // remove parameters stuff
592 //
593 // =============================================================================
594 public function removeParameters
595 "author wbraun"
596 input BackendDAE.BackendDAE inDAE;
597 output BackendDAE.BackendDAE outDAE;
598 algorithm
599 outDAE := match inDAE
600 local
601 BackendDAE.Variables globalKnownVars;
602 BackendVarTransform.VariableReplacements repl;
603 BackendDAE.EqSystems systs;
604 BackendDAE.Shared shared;
605 case BackendDAE.DAE(systs, shared as BackendDAE.SHARED(globalKnownVars=globalKnownVars))
606 algorithm
607 ✗ repl := BackendVarTransform.emptyReplacements();
608 ✗ (repl, _) := BackendVariable.traverseBackendDAEVars(globalKnownVars, removeParametersFinder, (repl, globalKnownVars));
609 ✗ (globalKnownVars, repl) := replaceFinalVars(1, globalKnownVars, repl);
610 ✗ (globalKnownVars, repl) := replaceFinalVars(1, globalKnownVars, repl);
611 ✗ if Flags.isSet(Flags.DUMP_PARAM_REPL) then
612 ✗ BackendVarTransform.dumpReplacements(repl);
613 end if;
614 ✗ systs := List.map1(systs,removeParameterswork, repl);
615 ✗ shared.globalKnownVars := globalKnownVars;
616 ✗ then
617 BackendDAE.DAE(systs, shared);
618 end match;
619 end removeParameters;
620
621 protected function removeParameterswork
622 "author wbraun"
623 input BackendDAE.EqSystem isyst;
624 input BackendVarTransform.VariableReplacements repl;
625 output BackendDAE.EqSystem osyst;
626 algorithm
627 osyst := match isyst
628 local
629 Option<BackendDAE.AdjacencyMatrix> m,mT;
630 BackendDAE.Variables vars;
631 BackendDAE.EquationArray eqns;
632 list<BackendDAE.Equation> lsteqns;
633 BackendDAE.EqSystem syst;
634
635 case syst as BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns)
636 algorithm
637 ✗ (vars, _) := replaceFinalVars(1, vars, repl); // replacing variable attributes (e.g start) in unknown vars
638 ✗ (lsteqns, _) := BackendVarTransform.replaceEquations(BackendEquation.equationList(eqns), repl, NONE());
639 ✗ syst.orderedVars := vars;
640 ✗ syst.orderedEqs := BackendEquation.listEquation(lsteqns);
641 ✗ syst.m := NONE(); syst.mT := NONE();
642 then
643 syst;
644 end match;
645 end removeParameterswork;
646
647 protected function removeParametersFinder
648 input BackendDAE.Var inVar;
649 input tuple<BackendVarTransform.VariableReplacements,BackendDAE.Variables> inTpl;
650 output BackendDAE.Var outVar;
651 output tuple<BackendVarTransform.VariableReplacements,BackendDAE.Variables> outTpl;
652 algorithm
653 (outVar,outTpl) := matchcontinue (inVar,inTpl)
654 local
655 BackendDAE.Variables vars;
656 BackendDAE.Var v;
657 BackendVarTransform.VariableReplacements repl,repl_1;
658 DAE.ComponentRef varName;
659 DAE.Exp exp,exp1;
660
661 case (v as BackendDAE.VAR(varName=varName,varKind=BackendDAE.PARAM(),bindExp=SOME(exp)),(repl,vars))
662 algorithm
663 ✗ (exp1, _) := Expression.traverseExpBottomUp(exp, BackendDAEUtil.replaceCrefsWithValues, (vars, varName));
664 ✗ repl_1 := BackendVarTransform.addReplacement(repl, varName, exp1,NONE());
665 ✗ then (v,(repl_1,vars));
666
667 else (inVar,inTpl);
668 end matchcontinue;
669 end removeParametersFinder;
670
671 protected function replaceFinalVars
672 " author: Frenkel TUD 2011-04"
673 input Integer inNumRepl;
674 input BackendDAE.Variables inVars;
675 input BackendVarTransform.VariableReplacements inRepl;
676 output BackendDAE.Variables outVars;
677 output BackendVarTransform.VariableReplacements outRepl;
678 protected
679 Integer numrepl;
680 BackendDAE.Variables globalKnownVars1;
681 BackendVarTransform.VariableReplacements repl1;
682 algorithm
683 ✗ if intEq(0,inNumRepl) then
684 ✗ (outVars,outRepl) := (inVars,inRepl);
685 else
686 ✗ (globalKnownVars1, (repl1,numrepl)) := BackendVariable.traverseBackendDAEVarsWithUpdate(inVars,replaceFinalVarTraverser,(inRepl,0));
687 ✗ (outVars,outRepl) := replaceFinalVars(numrepl,globalKnownVars1,repl1);
688 end if;
689 end replaceFinalVars;
690
691
692 protected function replaceFinalVarTraverser
693 input BackendDAE.Var inVar;
694 input tuple<BackendVarTransform.VariableReplacements,Integer> inTpl;
695 output BackendDAE.Var outVar;
696 output tuple<BackendVarTransform.VariableReplacements,Integer> outTpl;
697 algorithm
698 (outVar,outTpl) := matchcontinue (inVar,inTpl)
699 local
700 BackendDAE.Var v,v1;
701 BackendVarTransform.VariableReplacements repl,repl_1;
702 Integer numrepl;
703 DAE.Exp e,e1;
704 DAE.ComponentRef cr;
705 Option<DAE.VariableAttributes> attr,new_attr;
706
707 // Don't replace with function calls
708 case (BackendDAE.VAR(bindExp=SOME(DAE.CALL())),_)
709 then(inVar,inTpl);
710
711 case (v as BackendDAE.VAR(varName=cr,bindExp=SOME(e),values=attr),(repl,numrepl))
712 algorithm
713
1/2
✓ Branch 1 taken 191199 times.
✗ Branch 2 not taken.
191199 (e1,true) := BackendVarTransform.replaceExp(e, repl, NONE());
714 ✗ (e1,_) := ExpressionSimplify.simplify(e1);
715 ✗ v1 := BackendVariable.setBindExp(v, SOME(e1));
716 ✗ repl_1 := addConstExpReplacement(e1,cr,repl);
717 ✗ (attr,repl_1) := BackendDAEUtil.traverseBackendDAEVarAttr(attr,traverseExpVisitorWrapper,repl_1);
718 ✗ v1 := BackendVariable.setVarAttributes(v1,attr);
719 ✗ then (v1,(repl_1,numrepl+1));
720
721 case (v as BackendDAE.VAR(values=attr),(repl,numrepl))
722 algorithm
723 302669 (new_attr,repl) := BackendDAEUtil.traverseBackendDAEVarAttr(attr,traverseExpVisitorWrapper,repl);
724 302669 v1 := BackendVariable.setVarAttributes(v,new_attr);
725 302669 then (v1,(repl,numrepl));
726 end matchcontinue;
727 end replaceFinalVarTraverser;
728
729 protected function addConstExpReplacement
730 input DAE.Exp inExp;
731 input DAE.ComponentRef cr;
732 input BackendVarTransform.VariableReplacements inRepl;
733 output BackendVarTransform.VariableReplacements outRepl;
734 algorithm
735 outRepl := matchcontinue inRepl
736 case _
737 algorithm
738 ✗ true := Expression.isConst(inExp);
739 ✗ then
740 BackendVarTransform.addReplacement(inRepl, cr, inExp,NONE());
741 else
742 inRepl;
743 end matchcontinue;
744 end addConstExpReplacement;
745
746 protected function traverseExpVisitorWrapper "help function to replaceFinalVarTraverser"
747 input DAE.Exp inExp;
748 input BackendVarTransform.VariableReplacements inRepl;
749 output DAE.Exp exp;
750 output BackendVarTransform.VariableReplacements repl;
751 algorithm
752 (exp,repl) := match(inExp,inRepl)
753 local
754
755 case (exp as DAE.CREF(_,_),repl) algorithm
756 13410 (exp,_) := BackendVarTransform.replaceExp(exp,repl,NONE());
757 then (exp,repl);
758
759 else (inExp,inRepl);
760 end match;
761 end traverseExpVisitorWrapper;
762
763
764 // =============================================================================
765 // remove protected parameters stuff
766 //
767 // =============================================================================
768 public function removeProtectedParameters
769 "author Frenkel TUD"
770 input BackendDAE.BackendDAE inDAE;
771 output BackendDAE.BackendDAE outDAE;
772 algorithm
773 outDAE := match inDAE
774 local
775 BackendDAE.Variables globalKnownVars;
776 BackendVarTransform.VariableReplacements repl;
777 BackendDAE.EqSystems systs;
778 BackendDAE.Shared shared;
779 case BackendDAE.DAE(systs, shared as BackendDAE.SHARED(globalKnownVars=globalKnownVars))
780 algorithm
781 ✗ repl := BackendVarTransform.emptyReplacements();
782 ✗ repl := BackendVariable.traverseBackendDAEVars(globalKnownVars, protectedParametersFinder, repl);
783 ✗ if Flags.isSet(Flags.DUMP_PP_REPL) then
784 ✗ BackendVarTransform.dumpReplacements(repl);
785 end if;
786 ✗ systs := List.map1(systs, removeProtectedParameterswork, repl);
787 ✗ shared.globalKnownVars := globalKnownVars;
788 ✗ then
789 (BackendDAE.DAE(systs, shared));
790 end match;
791 end removeProtectedParameters;
792
793 protected function removeProtectedParameterswork
794 "author Frenkel TUD"
795 input BackendDAE.EqSystem isyst;
796 input BackendVarTransform.VariableReplacements repl;
797 output BackendDAE.EqSystem osyst;
798 algorithm
799 osyst := match isyst
800 local
801 BackendDAE.EqSystem syst;
802 BackendDAE.EquationArray eqns;
803 list<BackendDAE.Equation> lsteqns;
804 Boolean b;
805
806 case syst as BackendDAE.EQSYSTEM(orderedEqs=eqns)
807 algorithm
808 ✗ lsteqns := BackendEquation.equationList(eqns);
809 ✗ (lsteqns, b) := BackendVarTransform.replaceEquations(lsteqns, repl, NONE());
810 ✗ if b then
811 ✗ syst.orderedEqs := BackendEquation.listEquation(lsteqns);
812 ✗ syst := BackendDAEUtil.clearEqSyst(syst);
813 end if;
814 then
815 syst;
816 end match;
817 end removeProtectedParameterswork;
818
819 protected function protectedParametersFinder
820 input BackendDAE.Var inVar;
821 input BackendVarTransform.VariableReplacements inRepl;
822 output BackendDAE.Var outVar;
823 output BackendVarTransform.VariableReplacements outRepl;
824 algorithm
825 (outVar,outRepl) := matchcontinue (inVar,inRepl)
826 local
827 BackendDAE.Var v;
828 BackendVarTransform.VariableReplacements repl,repl_1;
829 DAE.ComponentRef varName;
830 Option< .DAE.VariableAttributes> values;
831 DAE.Exp exp;
832 case (v as BackendDAE.VAR(varName=varName,varKind=BackendDAE.PARAM(),bindExp=SOME(exp),values=values),repl)
833 algorithm
834 ✗ true := DAEUtil.getProtectedAttr(values);
835 ✗ repl_1 := BackendVarTransform.addReplacement(repl, varName, exp,NONE());
836 then (v,repl_1);
837
838 else (inVar,inRepl);
839 end matchcontinue;
840 end protectedParametersFinder;
841
842
843 // =============================================================================
844 // remove equal function calls equations stuff
845 //
846 // =============================================================================
847 protected type IntArray = array<Integer>;
848
849 public function removeEqualRHS "author: Frenkel TUD 2011-04
850 Detects equal expressions of the form a=<exp> and b=<exp> and substitutes
851 them to get speed up."
852 input BackendDAE.BackendDAE dae;
853 output BackendDAE.BackendDAE odae;
854 algorithm
855 2841 odae := BackendDAEUtil.mapEqSystem(dae,removeEqualFunctionCallsWork);
856 end removeEqualRHS;
857
858 protected function removeEqualFunctionCallsWork "author: Frenkel TUD 2011-04
859 This function detects equal function calls of the form a=f(b) and c=f(b) in
860 BackendDAE.BackendDAE to get speed up."
861 input BackendDAE.EqSystem isyst;
862 input BackendDAE.Shared ishared;
863 output BackendDAE.EqSystem osyst;
864 output BackendDAE.Shared oshared;
865 algorithm
866 (osyst,oshared) := match isyst
867 local
868 BackendDAE.AdjacencyMatrix m;
869 BackendDAE.AdjacencyMatrixT mT;
870 BackendDAE.Variables vars;
871 BackendDAE.EquationArray eqns;
872 list<Integer> changed;
873 array<Boolean> isChanged;
874 array<Integer> degree, varMark;
875 UnorderedMap<Integer, IntArray> ranks;
876 Boolean isInitial;
877 BackendDAE.EqSystem syst;
878 AvlTreePathFunction.Tree funcs;
879
880 case syst as BackendDAE.EQSYSTEM(orderedVars=vars,orderedEqs=eqns)
881 algorithm
882 20148 isInitial := BackendDAEUtil.isInitializationDAE(ishared);
883 20148 funcs := BackendDAEUtil.getFunctions(ishared);
884 20148 (syst, m, mT) := BackendDAEUtil.getAdjacencyMatrixfromOption(syst, BackendDAE.NORMAL(), SOME(funcs), isInitial);
885
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20148 times.
40296 degree := arrayCreate(arrayLength(mT), 0);
886
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 20148 times.
✓ Branch 2 taken 20124 times.
✓ Branch 3 taken 24 times.
263582 for v in 1:arrayLength(mT) loop
887 223286 arrayUpdate(degree, v, listLength(mT[v]));
888 end for;
889 20148 ranks := UnorderedMap.new<IntArray>(Util.id, intEq);
890
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20148 times.
40296 varMark := arrayCreate(arrayLength(mT), 0);
891
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20148 times.
40296 isChanged := arrayCreate(arrayLength(m), false);
892 20148 changed := {};
893
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 20148 times.
✓ Branch 2 taken 20124 times.
✓ Branch 3 taken 24 times.
253759 for pos in 1:arrayLength(m) loop
894 213463 (eqns, changed) := removeEqualFunctionCallFinder(pos, m, mT, degree, ranks, varMark, vars, eqns, changed, isChanged, isInitial);
895 end for;
896 // update arrayeqns and algorithms, collect info for wrappers
897 60444 syst.m := SOME(m); syst.mT := SOME(mT); syst.matching := BackendDAE.NO_MATCHING();
898 20148 syst := BackendDAEUtil.updateAdjacencyMatrix(syst, BackendDAE.NORMAL(), NONE(), changed, isInitial);
899 then (syst, ishared);
900 end match;
901 end removeEqualFunctionCallsWork;
902
903 protected function removeEqualFunctionCallFinder "author: Frenkel TUD 2010-12"
904 input Integer pos;
905 input BackendDAE.AdjacencyMatrix m;
906 input BackendDAE.AdjacencyMatrixT mT;
907 input array<Integer> degree "of the variables";
908 input UnorderedMap<Integer, IntArray> ranks;
909 input array<Integer> varMark;
910 input BackendDAE.Variables vars;
911 input output BackendDAE.EquationArray eqns;
912 input output list<Integer> changed;
913 input array<Boolean> isChanged;
914 input Boolean isInitial;
915 protected
916 DAE.Exp exp,e1,e2,ecr;
917 list<Integer> expvars, controleqns;
918 algorithm
919 try
920
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 213463 times.
213463 _::_ := m[pos];
921
2/2
✓ Branch 1 taken 3010 times.
✓ Branch 2 taken 210453 times.
213463 BackendDAE.EQUATION(exp=e1,scalar=e2) := BackendEquation.get(eqns,pos);
922 210453 (ecr,exp) := functionCallEqn(e1,e2,vars);
923 // TODO: Handle this with alias-equations instead?; at least they don't replace back to the original expression...
924 89400 expvars := BackendDAEUtil.uniqueRow(BackendDAEUtil.adjacencyRowExp(exp,vars,{},NONE(),BackendDAE.NORMAL(),isInitial));
925
2/2
✓ Branch 0 taken 41637 times.
✓ Branch 1 taken 47763 times.
89400 _::_ := expvars;
926 47763 controleqns := controlEqns(expvars, pos, m, mT, degree, ranks, varMark);
927 47763 (eqns,changed) := removeEqualFunctionCall(controleqns,ecr,exp,eqns,changed,isChanged);
928 else
929 end try;
930 end removeEqualFunctionCallFinder;
931
932 protected function controlEqns
933 "The other equations containing every variable of the expression, in the
934 order of the first variable's row, collected from the least used one's row."
935 input list<Integer> expvars;
936 input Integer pos;
937 input BackendDAE.AdjacencyMatrix m;
938 input BackendDAE.AdjacencyMatrixT mT;
939 input array<Integer> degree;
940 input UnorderedMap<Integer, IntArray> ranks;
941 input array<Integer> varMark "pos for the variables of the expression";
942 output list<Integer> eqns = {};
943 protected
944 Integer first, least, eq, nvars = 0;
945 array<Integer> rank;
946 algorithm
947 47763 first := intAbs(listHead(expvars));
948 least := first;
949
2/2
✓ Branch 0 taken 120353 times.
✓ Branch 1 taken 47763 times.
168116 for v in expvars loop
950
2/2
✓ Branch 2 taken 11550 times.
✓ Branch 3 taken 108803 times.
120353 if degree[intAbs(v)] < degree[least] then
951 least := intAbs(v);
952 end if;
953
2/2
✓ Branch 1 taken 120248 times.
✓ Branch 2 taken 105 times.
120353 if varMark[intAbs(v)] <> pos then
954 120248 arrayUpdate(varMark, intAbs(v), pos);
955 120248 nvars := nvars + 1;
956 end if;
957 end for;
958
2/2
✓ Branch 1 taken 182907 times.
✓ Branch 2 taken 47763 times.
230670 for i in mT[least] loop
959 182907 eq := intAbs(i);
960
4/4
✓ Branch 0 taken 135599 times.
✓ Branch 1 taken 47308 times.
✓ Branch 4 taken 79253 times.
✓ Branch 5 taken 56346 times.
182907 if eq <> pos and rowContainsAll(m[eq], nvars, pos, varMark) then
961 eqns := eq :: eqns;
962 end if;
963 end for;
964 47763 eqns := listReverse(eqns);
965
4/4
✓ Branch 0 taken 37450 times.
✓ Branch 1 taken 10313 times.
✓ Branch 2 taken 7454 times.
✓ Branch 3 taken 2859 times.
47763 if least <> first and not listEmpty(eqns) then
966
2/2
✓ Branch 1 taken 2830 times.
✓ Branch 2 taken 29 times.
2859 if degree[first] <= 64 then
967
6/6
✓ Branch 2 taken 19658 times.
✓ Branch 3 taken 5635 times.
✓ Branch 4 taken 25293 times.
✓ Branch 5 taken 2830 times.
✓ Branch 6 taken 5635 times.
✓ Branch 7 taken 2830 times.
28123 eqns := list(intAbs(i) for i guard List.isMemberOnTrue(intAbs(i), eqns, intEq) in mT[first]);
968 else
969 29 rank := rowRanks(first, mT, arrayLength(m), ranks);
970 29 eqns := List.sort(eqns, function rankGt(rank = rank));
971 end if;
972 end if;
973 end controlEqns;
974
975 protected function rowContainsAll
976 "Whether row holds all nvars variables marked pos; a hit is marked -pos until
977 the row has been counted, so a variable in it twice counts once."
978 input list<Integer> row;
979 input Integer nvars;
980 input Integer pos;
981 input array<Integer> varMark;
982 output Boolean all;
983 protected
984 Integer hits = 0;
985 algorithm
986
2/2
✓ Branch 0 taken 567459 times.
✓ Branch 1 taken 135599 times.
703058 for v in row loop
987
2/2
✓ Branch 1 taken 235665 times.
✓ Branch 2 taken 331794 times.
567459 if varMark[intAbs(v)] == pos then
988 235665 arrayUpdate(varMark, intAbs(v), -pos);
989 235665 hits := hits + 1;
990 end if;
991 end for;
992
2/2
✓ Branch 0 taken 567459 times.
✓ Branch 1 taken 135599 times.
703058 for v in row loop
993
2/2
✓ Branch 1 taken 235665 times.
✓ Branch 2 taken 331794 times.
567459 if varMark[intAbs(v)] == -pos then
994 235665 arrayUpdate(varMark, intAbs(v), pos);
995 end if;
996 end for;
997 135599 all := hits == nvars;
998 end rowContainsAll;
999
1000 protected function rowRanks "the position of each equation in the row of var, built once per variable"
1001 input Integer var;
1002 input BackendDAE.AdjacencyMatrixT mT;
1003 input Integer numEqns;
1004 input UnorderedMap<Integer, IntArray> ranks;
1005 output array<Integer> rank;
1006 protected
1007 Integer i = 1;
1008 algorithm
1009 rank := match UnorderedMap.get(var, ranks)
1010 case SOME(rank) then rank;
1011 else
1012 algorithm
1013 1 rank := arrayCreate(numEqns, 0);
1014
2/2
✓ Branch 2 taken 71 times.
✓ Branch 3 taken 1 time.
72 for eq in mT[var] loop
1015 71 arrayUpdate(rank, intAbs(eq), i);
1016 71 i := i + 1;
1017 end for;
1018 1 UnorderedMap.add(var, rank, ranks);
1019 then rank;
1020 end match;
1021 end rowRanks;
1022
1023 protected function rankGt
1024 input Integer a, b;
1025 input array<Integer> rank;
1026 output Boolean gt = rank[a] > rank[b];
1027 end rankGt;
1028
1029 protected function functionCallEqn
1030 "author Frenkel TUD 2011-04"
1031 input DAE.Exp ie1;
1032 input DAE.Exp ie2;
1033 input BackendDAE.Variables inVars;
1034 output DAE.Exp outECr;
1035 output DAE.Exp outExp;
1036 algorithm
1037 (outECr,outExp) := match (ie1, ie2)
1038 local
1039 DAE.ComponentRef cr;
1040 DAE.Exp e1,e2;
1041 DAE.Operator op;
1042
1043 case (DAE.CREF(), DAE.UNARY(operator=DAE.UMINUS(),exp=DAE.CREF()))
1044 2081 then fail();
1045 case (DAE.CREF(), DAE.CREF())
1046 87171 then fail();
1047 case (DAE.UNARY(operator=DAE.UMINUS(),exp=DAE.CREF()), DAE.CREF())
1048 35 then fail();
1049 // a = -<exp>
1050 case (e1 as DAE.CREF(componentRef = cr), DAE.UNARY(operator=op as DAE.UMINUS(),exp=e2))
1051 algorithm
1052
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 111 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 111 times.
111 ((_::_),(_::_)) := BackendVariable.getVar(cr,inVars);
1053 111 then (DAE.UNARY(op,e1),e2);
1054 // a = <exp>;
1055 case (e1 as DAE.CREF(componentRef = cr), e2)
1056 algorithm
1057
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 87572 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 87572 times.
88009 ((_::_),(_::_)) := BackendVariable.getVar(cr,inVars);
1058 then (e1,e2);
1059 // -<exp> = a
1060 case (DAE.UNARY(operator=op as DAE.UMINUS(),exp=e1), e2 as DAE.CREF(componentRef = cr))
1061 algorithm
1062 ✗ ((_::_),(_::_)) := BackendVariable.getVar(cr,inVars);
1063 ✗ then (DAE.UNARY(op,e2),e1);
1064 // <exp> = a
1065 case (e1, e2 as DAE.CREF(componentRef = cr))
1066 algorithm
1067
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 1717 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1717 times.
1956 ((_::_),(_::_)) := BackendVariable.getVar(cr,inVars);
1068 then (e2,e1);
1069 end match;
1070 end functionCallEqn;
1071
1072 protected function removeEqualFunctionCall
1073 "author: Frenkel TUD 2011-04"
1074 input list<Integer> inEqsLst;
1075 input DAE.Exp inExp;
1076 input DAE.Exp inECr;
1077 input output BackendDAE.EquationArray eqns;
1078 input output list<Integer> changed;
1079 input array<Boolean> isChanged;
1080 protected
1081 BackendDAE.Equation eqn;
1082 Integer i;
1083 algorithm
1084
2/2
✓ Branch 0 taken 79265 times.
✓ Branch 1 taken 47763 times.
127028 for pos in inEqsLst loop
1085 try
1086 79265 eqn := BackendEquation.get(eqns,pos);
1087 79265 (eqn,(_,_,i)) := BackendDAETransform.traverseBackendDAEExpsEqnWithSymbolicOperation(eqn, replaceExp, (inECr,inExp,0));
1088
2/2
✓ Branch 0 taken 2338 times.
✓ Branch 1 taken 76927 times.
79265 if i > 0 then
1089 2338 eqns := BackendEquation.setAtIndex(eqns,pos,eqn);
1090
2/2
✓ Branch 1 taken 2304 times.
✓ Branch 2 taken 34 times.
2338 if not isChanged[pos] then
1091 2304 arrayUpdate(isChanged, pos, true);
1092 changed := pos::changed;
1093 end if;
1094 end if;
1095 else
1096 end try;
1097 end for;
1098 end removeEqualFunctionCall;
1099
1100 protected function replaceExp
1101 input DAE.Exp inExp;
1102 input tuple<list<DAE.SymbolicOperation>, tuple<DAE.Exp, DAE.Exp, Integer>> inTpl;
1103 output DAE.Exp e1;
1104 output tuple<list<DAE.SymbolicOperation>, tuple<DAE.Exp, DAE.Exp, Integer>> outTpl;
1105 protected
1106 DAE.Exp e, se, te;
1107 Integer i, j;
1108 list<DAE.SymbolicOperation> ops;
1109 algorithm
1110 e := inExp;
1111 159513 (ops, (se, te, i)) := inTpl;
1112 // BackendDump.debugStrExpStrExpStr(("Repalce ", se, " with ", te, "\n"));
1113 // use the noEvent-aware variant: a relation inside noEvent()/smooth() is
1114 // continuous and must not be substituted by an event-based variable
1115 159513 (e1, j) := Expression.replaceExpNoEvent(e, se, te);
1116
2/2
✓ Branch 0 taken 2339 times.
✓ Branch 1 taken 157174 times.
161852 ops := if j>0 then DAE.SUBSTITUTION({e1}, e)::ops else ops;
1117 // BackendDump.debugStrExpStrExpStr(("Old ", e, " new ", e1, "\n"));
1118 159513 outTpl := (ops, (se, te, i+j));
1119 end replaceExp;
1120
1121 // =============================================================================
1122 // remove unused parameter
1123 //
1124 // =============================================================================
1125 public function removeUnusedParameter
1126 "author: Frenkel TUD 2011-04
1127 This function remove unused parameters
1128 in BackendDAE.BackendDAE to get speed up for compilation of
1129 target code"
1130 input BackendDAE.BackendDAE inDlow;
1131 output BackendDAE.BackendDAE outDlow;
1132 algorithm
1133 outDlow := match inDlow
1134 local
1135 BackendDAE.Variables globalKnownVars, globalKnownVars1;
1136 BackendDAE.EqSystems eqs;
1137 BackendDAE.Shared shared;
1138
1139 case BackendDAE.DAE(eqs, shared)
1140 algorithm
1141 ✗ globalKnownVars1 := BackendVariable.emptyVars();
1142 ✗ globalKnownVars := shared.globalKnownVars;
1143 ✗ globalKnownVars1 := BackendVariable.traverseBackendDAEVars(globalKnownVars, copyNonParamVariables, globalKnownVars1);
1144 ✗ (_, globalKnownVars1) := List.fold1(eqs,BackendDAEUtil.traverseBackendDAEExpsEqSystem, checkUnusedVariables, (globalKnownVars,globalKnownVars1));
1145 ✗ (_, globalKnownVars1) := BackendDAEUtil.traverseBackendDAEExpsVars(globalKnownVars, checkUnusedParameter, (globalKnownVars,globalKnownVars1));
1146 ✗ (_, globalKnownVars1) := BackendDAEUtil.traverseBackendDAEExpsVars(shared.aliasVars, checkUnusedParameter, (globalKnownVars,globalKnownVars1));
1147 ✗ (_, globalKnownVars1) := BackendDAEUtil.traverseBackendDAEExpsEqns(shared.removedEqs, checkUnusedParameter, (globalKnownVars,globalKnownVars1));
1148 ✗ (_, globalKnownVars1) := BackendDAEUtil.traverseBackendDAEExpsEqns(shared.initialEqs, checkUnusedParameter, (globalKnownVars,globalKnownVars1));
1149 ✗ shared.globalKnownVars := globalKnownVars1;
1150 ✗ then
1151 BackendDAE.DAE(eqs, shared);
1152 end match;
1153 end removeUnusedParameter;
1154
1155 protected function copyNonParamVariables
1156 input BackendDAE.Var inVar;
1157 input BackendDAE.Variables inVars;
1158 output BackendDAE.Var outVar;
1159 output BackendDAE.Variables outVars;
1160 algorithm
1161 (outVar,outVars) := match inVar
1162 local
1163 BackendDAE.Var v;
1164 BackendDAE.Variables vars1;
1165 case v as BackendDAE.VAR(varKind = BackendDAE.PARAM())
1166 then (v,inVars);
1167 else
1168 algorithm
1169 ✗ vars1 := BackendVariable.addVar(inVar,inVars);
1170 then (inVar,vars1);
1171 end match;
1172 end copyNonParamVariables;
1173
1174 protected function checkUnusedParameter
1175 input DAE.Exp inExp;
1176 input tuple<BackendDAE.Variables,BackendDAE.Variables> inTpl;
1177 output DAE.Exp outExp;
1178 output tuple<BackendDAE.Variables,BackendDAE.Variables> outTpl;
1179 algorithm
1180 (outExp,outTpl) := matchcontinue (inExp,inTpl)
1181 local
1182 DAE.Exp exp;
1183 BackendDAE.Variables vars,vars1;
1184 case (exp,(vars,_))
1185 algorithm
1186 ✗ (_,(_,vars1)) := Expression.traverseExpBottomUp(exp,checkUnusedParameterExp,inTpl);
1187 ✗ then (exp,(vars,vars1));
1188 else (inExp,inTpl);
1189 end matchcontinue;
1190 end checkUnusedParameter;
1191
1192 protected function checkUnusedParameterExp
1193 input DAE.Exp inExp;
1194 input tuple<BackendDAE.Variables,BackendDAE.Variables> inTuple;
1195 output DAE.Exp outExp;
1196 output tuple<BackendDAE.Variables,BackendDAE.Variables> outTuple;
1197 algorithm
1198 (outExp,outTuple) := matchcontinue (inExp,inTuple)
1199 local
1200 DAE.Exp e,e1;
1201 BackendDAE.Variables vars,vars1;
1202 DAE.ComponentRef cr;
1203 list<DAE.Exp> expl;
1204 list<DAE.Var> varLst;
1205 BackendDAE.Var var;
1206 tuple<BackendDAE.Variables,BackendDAE.Variables> tp;
1207
1208 // special case for time, it is never part of the equation system
1209 case (e as DAE.CREF(componentRef = DAE.CREF_IDENT(ident="time")),_)
1210 then (e, inTuple);
1211
1212 // Special Case for Records
1213 case (e as DAE.CREF(componentRef = cr,ty= DAE.T_COMPLEX(varLst=varLst,complexClassType=ClassInf.RECORD(_))),tp)
1214 algorithm
1215 ✗ expl := List.map1(varLst,Expression.generateCrefsExpFromExpVar,cr);
1216 ✗ (_,tp) := Expression.traverseExpList(expl,checkUnusedParameterExp,tp);
1217 ✗ then (e, tp);
1218
1219 // Special Case for Arrays
1220 case (e as DAE.CREF(ty = DAE.T_ARRAY()),tp)
1221 algorithm
1222 ✗ (e1,true) := Expression.extendArrExp(e,false);
1223 ✗ (_,tp) := Expression.traverseExpBottomUp(e1,checkUnusedParameterExp,tp);
1224 ✗ then (e, tp);
1225
1226 // case for functionpointers
1227 case (e as DAE.CREF(ty=DAE.T_FUNCTION_REFERENCE_FUNC()),_)
1228 then (e, inTuple);
1229
1230 // already there
1231 case (e as DAE.CREF(componentRef = cr),(_,vars1))
1232 algorithm
1233 ✗ BackendVariable.getVar(cr, vars1);
1234 then (e, inTuple);
1235
1236 // add it
1237 case (e as DAE.CREF(componentRef = cr),(vars,vars1))
1238 algorithm
1239 ✗ (var::_,_) := BackendVariable.getVar(cr, vars);
1240 ✗ vars1 := BackendVariable.addVar(var,vars1);
1241 ✗ then (e, (vars,vars1));
1242
1243 else (inExp,inTuple);
1244 end matchcontinue;
1245 end checkUnusedParameterExp;
1246
1247 // =============================================================================
1248 // remove unused variables
1249 //
1250 // =============================================================================
1251 public function removeUnusedVariables
1252 "author: Frenkel TUD 2011-04
1253 This function removes unused variables
1254 from BackendDAE.BackendDAE to get speed up for compilation of
1255 target code"
1256 input BackendDAE.BackendDAE inDlow;
1257 output BackendDAE.BackendDAE outDlow;
1258 algorithm
1259 outDlow := match inDlow
1260 local
1261 BackendDAE.Variables globalKnownVars, globalKnownVars1;
1262 BackendDAE.EqSystems eqs;
1263 BackendDAE.Shared shared;
1264 tuple<BackendDAE.Variables,BackendDAE.Variables> tpl;
1265
1266 case BackendDAE.DAE(eqs, shared)
1267 algorithm
1268 14 globalKnownVars1 := BackendVariable.emptyVars();
1269 14 globalKnownVars := shared.globalKnownVars;
1270 14 tpl := List.fold1(eqs,BackendDAEUtil.traverseBackendDAEExpsEqSystem, checkUnusedVariables, (globalKnownVars, globalKnownVars1));
1271 14 tpl := BackendDAEUtil.traverseBackendDAEExpsVars(globalKnownVars, checkUnusedVariables, tpl);
1272 14 tpl := BackendDAEUtil.traverseBackendDAEExpsVars(shared.aliasVars, checkUnusedVariables, tpl);
1273 14 tpl := BackendDAEUtil.traverseBackendDAEExpsEqns(shared.removedEqs, checkUnusedVariables, tpl);
1274 14 (_, globalKnownVars1) := BackendDAEUtil.traverseBackendDAEExpsEqns(shared.initialEqs, checkUnusedVariables, tpl);
1275 14 shared.globalKnownVars := globalKnownVars1;
1276 14 then
1277 BackendDAE.DAE(eqs, shared);
1278 end match;
1279 end removeUnusedVariables;
1280
1281 protected function checkUnusedVariables
1282 input DAE.Exp inExp;
1283 input tuple<BackendDAE.Variables,BackendDAE.Variables> inTpl;
1284 output DAE.Exp outExp;
1285 output tuple<BackendDAE.Variables,BackendDAE.Variables> outTpl;
1286 algorithm
1287 (outExp,outTpl) := matchcontinue inExp
1288 local
1289 DAE.Exp exp;
1290 tuple<BackendDAE.Variables,BackendDAE.Variables> tpl;
1291 case exp
1292 algorithm
1293 7343 (_,tpl) := Expression.traverseExpBottomUp(exp,checkUnusedVariablesExp,inTpl);
1294 7343 then (exp,tpl);
1295 else (inExp,inTpl);
1296 end matchcontinue;
1297 end checkUnusedVariables;
1298
1299 protected function checkUnusedVariablesExp
1300 input DAE.Exp inExp;
1301 input tuple<BackendDAE.Variables,BackendDAE.Variables> inTuple;
1302 output DAE.Exp outExp;
1303 output tuple<BackendDAE.Variables,BackendDAE.Variables> outTuple;
1304 algorithm
1305 (outExp,outTuple) := matchcontinue (inExp,inTuple)
1306 local
1307 DAE.Exp e,e1;
1308 BackendDAE.Variables vars,vars1;
1309 DAE.ComponentRef cr;
1310 list<DAE.Exp> expl;
1311 list<DAE.Var> varLst;
1312 BackendDAE.Var var;
1313 tuple<BackendDAE.Variables,BackendDAE.Variables> tp;
1314
1315 // special case for time, it is never part of the equation system
1316 case (e as DAE.CREF(componentRef = DAE.CREF_IDENT(ident="time")),tp)
1317 then (e, tp);
1318
1319 // Special Case for Records
1320 case (e as DAE.CREF(componentRef = cr,ty= DAE.T_COMPLEX(varLst=varLst,complexClassType=ClassInf.RECORD(_))),tp)
1321 algorithm
1322 18 expl := List.map1(varLst,Expression.generateCrefsExpFromExpVar,cr);
1323 18 (_,tp) := Expression.traverseExpList(expl,checkUnusedVariablesExp,tp);
1324 18 then (e, tp);
1325
1326 // Special Case for Arrays
1327 case (e as DAE.CREF(ty = DAE.T_ARRAY()),tp)
1328 algorithm
1329 ✗ (e1,true) := Expression.extendArrExp(e,false);
1330 ✗ (_,tp) := Expression.traverseExpBottomUp(e1,checkUnusedVariablesExp,tp);
1331 ✗ then (e, tp);
1332
1333 // case for functionpointers
1334 case (DAE.CREF(ty=DAE.T_FUNCTION_REFERENCE_FUNC()),_)
1335 then (inExp, inTuple);
1336
1337 // already there
1338 case (DAE.CREF(componentRef = cr),(_,vars1))
1339 algorithm
1340 2400 BackendVariable.getVar(cr, vars1);
1341 then (inExp, inTuple);
1342
1343 // add it
1344 case (DAE.CREF(componentRef = cr),(vars,vars1))
1345 algorithm
1346
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 316 times.
2077 (var::_,_) := BackendVariable.getVar(cr, vars);
1347 316 vars1 := BackendVariable.addVar(var,vars1);
1348 316 then (inExp, (vars,vars1));
1349
1350 else (inExp,inTuple);
1351 end matchcontinue;
1352 end checkUnusedVariablesExp;
1353
1354 // =============================================================================
1355 // remove unused functions
1356 //
1357 // =============================================================================
1358 public function removeUnusedFunctions "author: Frenkel TUD 2012-03
1359 This function remove unused functions from AvlTreePathFunction.Tree to get speed up
1360 for compilation of target code."
1361 input BackendDAE.EqSystems inEqs;
1362 input BackendDAE.Shared inShared;
1363 input list<BackendDAE.Equation> inEquationLst;
1364 input AvlTreePathFunction.Tree inFunctionTree;
1365 input AvlTreePathFunction.Tree inusedFunctions;
1366 output AvlTreePathFunction.Tree outFunctionTree;
1367 protected
1368 partial function FuncType
1369 input DAE.Exp inExp;
1370 input AvlTreePathFunction.Tree inUnsedFunctions;
1371 output DAE.Exp outExp;
1372 output AvlTreePathFunction.Tree outUsedFunctions;
1373 end FuncType;
1374
1375 FuncType func;
1376 AvlTreePathFunction.Tree funcs, usedfuncs;
1377 algorithm
1378 funcs := inFunctionTree;
1379 usedfuncs := inusedFunctions;
1380 2493 func := function checkUnusedFunctions(inFunctions = funcs);
1381
1382 // equation system
1383 2493 usedfuncs := List.fold1(inEqs, BackendDAEUtil.traverseBackendDAEExpsEqSystem, func, usedfuncs);
1384 2493 usedfuncs := List.fold1(inEqs, BackendDAEUtil.traverseBackendDAEExpsEqSystemJacobians, func, usedfuncs);
1385
1386 // equation list
1387 2493 usedfuncs := List.fold1(inEquationLst, BackendEquation.traverseExpsOfEquationList_WithoutChange, func, usedfuncs);
1388
1389 // shared object
1390 2493 usedfuncs := BackendDAEUtil.traverseBackendDAEExpsVars(inShared.globalKnownVars, func, usedfuncs);
1391 2493 usedfuncs := BackendDAEUtil.traverseBackendDAEExpsVars(inShared.externalObjects, func, usedfuncs);
1392 2493 usedfuncs := BackendDAEUtil.traverseBackendDAEExpsVars(inShared.aliasVars, func, usedfuncs);
1393 2493 usedfuncs := BackendDAEUtil.traverseBackendDAEExpsEqns(inShared.removedEqs, func, usedfuncs);
1394 2493 usedfuncs := BackendDAEUtil.traverseBackendDAEExpsEqns(inShared.initialEqs, func, usedfuncs);
1395 2493 usedfuncs := removeUnusedFunctionsSymJacs(inShared, funcs, usedfuncs);
1396
1397 outFunctionTree := usedfuncs;
1398 end removeUnusedFunctions;
1399
1400 public function copyRecordConstructorAndExternalObjConstructorDestructor
1401 input AvlTreePathFunction.Tree inAllFunctionTree;
1402 output AvlTreePathFunction.Tree outUsedFunctionTree;
1403 protected
1404 list<DAE.Function> allfuncs_list;
1405 algorithm
1406 1076 outUsedFunctionTree := AvlTreePathFunction.Tree.EMPTY();
1407 1076 allfuncs_list := DAEUtil.getFunctionList(inAllFunctionTree);
1408
1409
2/2
✓ Branch 0 taken 17719 times.
✓ Branch 1 taken 1076 times.
18795 for func in allfuncs_list loop
1410 () := match func
1411 local
1412 Absyn.Path path;
1413 list<DAE.Var> var_list;
1414 Option<DAE.Exp> obind;
1415 DAE.Exp bind_exp;
1416
1417 case DAE.RECORD_CONSTRUCTOR(path=path) algorithm
1418 // Add the constructor function.
1419 4259 outUsedFunctionTree := AvlTreePathFunction.add(outUsedFunctionTree, path, SOME(func));
1420
1421 // Now we traverse the bindings of the record members and look for function calls.
1422 try
1423
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4259 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4259 times.
4259 DAE.T_FUNCTION(funcResultType = DAE.T_COMPLEX(varLst=var_list)) := func.type_;
1424 else
1425 ✗ Error.addSourceMessage(Error.INTERNAL_ERROR,
1426 {getInstanceName() + " got unxpected record constructor structure for " + AbsynUtil.pathString(path)},
1427 sourceInfo());
1428 ✗ fail();
1429 end try;
1430
1431
2/2
✓ Branch 0 taken 44396 times.
✓ Branch 1 taken 4259 times.
48655 for var in var_list loop
1432 44396 obind := Types.getBindingExpOptional(var);
1433
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 44396 times.
✓ Branch 2 taken 8194 times.
✓ Branch 3 taken 36202 times.
44396 if isSome(obind) then
1434 8194 SOME(bind_exp) := obind;
1435 8194 (_, outUsedFunctionTree) := checkUnusedFunctions(bind_exp,inAllFunctionTree,outUsedFunctionTree);
1436 end if;
1437 end for;
1438
1439 then
1440 ();
1441
1442 // copy external objects constructors/destructors
1443 case DAE.FUNCTION(path = path) algorithm
1444
8/8
✓ Branch 1 taken 419 times.
✓ Branch 2 taken 13041 times.
✓ Branch 5 taken 378 times.
✓ Branch 6 taken 41 times.
✓ Branch 8 taken 948 times.
✓ Branch 9 taken 12471 times.
✓ Branch 12 taken 41 times.
✓ Branch 13 taken 907 times.
13460 if stringEq(AbsynUtil.pathLastIdent(path), "constructor") or
1445 stringEq(AbsynUtil.pathLastIdent(path), "destructor") then
1446 82 outUsedFunctionTree := AvlTreePathFunction.add(outUsedFunctionTree, path, SOME(func));
1447 end if;
1448 then
1449 ();
1450
1451 end match;
1452
1453 end for;
1454
1455 end copyRecordConstructorAndExternalObjConstructorDestructor;
1456
1457 protected function removeUnusedFunctionsSymJacs
1458 input BackendDAE.Shared inShared;
1459 input AvlTreePathFunction.Tree inFunctions;
1460 input AvlTreePathFunction.Tree inUsedFunctions;
1461 output AvlTreePathFunction.Tree outUsedFunctions = inUsedFunctions;
1462 protected
1463 BackendDAE.BackendDAE bdae;
1464 AvlTreePathFunction.Tree usedfuncs;
1465 BackendDAE.Shared shared;
1466 algorithm
1467
2/2
✓ Branch 0 taken 4436 times.
✓ Branch 1 taken 2493 times.
6929 for sjac in inShared.symjacs loop
1468 () := match sjac
1469 case (SOME((bdae, _, _, _, _, _)), _, _, _)
1470 algorithm
1471 214 bdae := BackendDAEUtil.setFunctionTree(bdae, inFunctions);
1472 214 shared := bdae.shared;
1473 214 usedfuncs := removeUnusedFunctions(bdae.eqs, shared, {}, shared.functionTree, inUsedFunctions);
1474 214 outUsedFunctions := AvlTreePathFunction.join(outUsedFunctions, usedfuncs);
1475 then
1476 ();
1477
1478 else ();
1479 end match;
1480 end for;
1481
1482 // Collect function if there is a data recon structure.
1483 () := match inShared.dataReconciliationData
1484 case NONE() then ();
1485
1486 case SOME(BackendDAE.DATA_RECON(symbolicJacobian =
1487 BackendDAE.GENERIC_JACOBIAN(jacobian=SOME((bdae, _, _, _, _, _)))))
1488 algorithm
1489 25 bdae := BackendDAEUtil.setFunctionTree(bdae, inFunctions);
1490 25 shared := bdae.shared;
1491 25 usedfuncs := removeUnusedFunctions(bdae.eqs, shared, {}, shared.functionTree, inUsedFunctions);
1492 25 outUsedFunctions := AvlTreePathFunction.join(outUsedFunctions, usedfuncs);
1493 then ();
1494
1495 // If data isSome and we have non generic jacobian what do we do?
1496 else algorithm
1497 1 Error.addInternalError(getInstanceName()
1498 + ": Unexpected data reconciliation jacobian structure. ", sourceInfo());
1499 1 then fail();
1500 end match;
1501 end removeUnusedFunctionsSymJacs;
1502
1503 protected function checkUnusedFunctions
1504 input DAE.Exp inExp;
1505 input AvlTreePathFunction.Tree inFunctions;
1506 input AvlTreePathFunction.Tree inUsedFunctions;
1507 output DAE.Exp outExp;
1508 output AvlTreePathFunction.Tree outUsedFunctions;
1509 algorithm
1510 2094018 (outExp, outUsedFunctions) := Expression.traverseExpBottomUp(inExp,
1511 function checkUnusedFunctionsExp(inFunctions = inFunctions), inUsedFunctions);
1512 end checkUnusedFunctions;
1513
1514 protected function checkUnusedFunctionsExp
1515 input DAE.Exp inExp;
1516 input AvlTreePathFunction.Tree inFunctions;
1517 input AvlTreePathFunction.Tree inUsedFunctions;
1518 output DAE.Exp outExp = inExp;
1519 output AvlTreePathFunction.Tree outUsedFunctions;
1520 algorithm
1521 outUsedFunctions := match inExp
1522 local
1523 Absyn.Path path;
1524 DAE.ComponentRef cr;
1525 AvlTreePathFunction.Tree usedfuncs;
1526
1527 // If the expression is some kind of function call, add it to the used functions.
1528 case DAE.CALL(path = path)
1529 87170 then addUnusedFunction(path, inFunctions, inUsedFunctions);
1530
1531 case DAE.PARTEVALFUNCTION(path = path)
1532 250 then addUnusedFunction(path, inFunctions, inUsedFunctions);
1533
1534 case DAE.CREF(ty = DAE.T_FUNCTION_REFERENCE_FUNC(functionType =
1535 DAE.T_FUNCTION(path=path)))
1536 22 then addUnusedFunction(path, inFunctions, inUsedFunctions);
1537
1538 // If it's a cref, check the cref's dimensions for function calls.
1539 case DAE.CREF(componentRef = cr)
1540 algorithm
1541 1385203 (_, usedfuncs) := Expression.traverseExpCrefDims(cr,
1542 function checkUnusedFunctions(inFunctions = inFunctions), inUsedFunctions);
1543 1385203 then
1544 usedfuncs;
1545
1546 // Otherwise, do nothing.
1547 else inUsedFunctions;
1548 end match;
1549 end checkUnusedFunctionsExp;
1550
1551 protected function addUnusedFunction
1552 input Absyn.Path inPath;
1553 input AvlTreePathFunction.Tree inFunctions;
1554 input AvlTreePathFunction.Tree inUsedFunctions;
1555 output AvlTreePathFunction.Tree outUsedFunctions = inUsedFunctions;
1556 protected
1557 Option<DAE.Function> f;
1558 list<DAE.Element> body;
1559 algorithm
1560 try // Check if the function has already been added.
1561 87442 AvlTreePathFunction.get(inUsedFunctions, inPath);
1562 else // Otherwise, try to add it.
1563 52318 (f, body) := getFunctionAndBody(inPath, inFunctions);
1564
1565
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 52318 times.
✓ Branch 2 taken 7199 times.
✓ Branch 3 taken 45119 times.
52318 if isSome(f) then
1566 7199 outUsedFunctions := AvlTreePathFunction.add(outUsedFunctions, inPath, f);
1567 7199 (_, outUsedFunctions) := DAEUtil.traverseDAEElementList(body,
1568 function checkUnusedFunctions(inFunctions = inFunctions), outUsedFunctions);
1569 end if;
1570 end try;
1571 end addUnusedFunction;
1572
1573 protected function getFunctionAndBody
1574 "returns the body of a function"
1575 input Absyn.Path inPath;
1576 input AvlTreePathFunction.Tree fns;
1577 output Option<DAE.Function> outFn;
1578 output list<DAE.Element> outFnBody;
1579 protected
1580 DAE.Function fn;
1581 algorithm
1582 try
1583
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 7199 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7199 times.
52318 outFn as SOME(fn) := AvlTreePathFunction.get(fns, inPath);
1584 7199 outFnBody := DAEUtil.getFunctionElements(fn);
1585 else
1586 outFn := NONE();
1587 outFnBody := {};
1588 end try;
1589 end getFunctionAndBody;
1590
1591
1592 // =============================================================================
1593 // parallel back end stuff (TLM)
1594 //
1595 // =============================================================================
1596
1597 public function collapseIndependentBlocks
1598 input BackendDAE.BackendDAE inDAE;
1599 output BackendDAE.BackendDAE outDAE;
1600 protected
1601 BackendDAE.EqSystem syst;
1602 list<BackendDAE.EqSystem> systs;
1603 BackendDAE.Shared shared;
1604 BackendDAE.Variables vars;
1605 algorithm
1606 1477 BackendDAE.DAE(systs, shared) := inDAE;
1607
4/4
✓ Branch 0 taken 7892 times.
✓ Branch 1 taken 1477 times.
✓ Branch 2 taken 7892 times.
✓ Branch 3 taken 1477 times.
9369 vars := BackendVariable.emptyVarsSized(integer(sum(BackendVariable.varsSize(s.orderedVars) for s in systs)*1.4));
1608 // We can use listReduce as if there is no eq-system something went terribly wrong
1609 1477 syst := List.fold(listReverse(systs), mergeIndependentBlocks, BackendDAEUtil.createEqSystem(vars));
1610 1477 outDAE := BackendDAE.DAE({syst}, shared);
1611 end collapseIndependentBlocks;
1612
1613 public function collapseIndependentContinuousBlocks
1614 "Like collapseIndependentBlocks, but leaves out the clocked partitions.
1615 The Jacobian of the ODE is taken with respect to the continuous states only,
1616 a clocked partition does not change between clock ticks and contributes
1617 nothing to it. Merged with the continuous partitions, a loop that is closed
1618 over a sample/hold pair looks like an algebraic loop and cannot be sorted."
1619 input BackendDAE.BackendDAE inDAE;
1620 output BackendDAE.BackendDAE outDAE;
1621 algorithm
1622 1061 outDAE := collapseIndependentBlocks(BackendDAE.DAE(
1623 List.filterOnFalse(inDAE.eqs, BackendDAEUtil.isClockedSyst), inDAE.shared));
1624 end collapseIndependentContinuousBlocks;
1625
1626 protected function mergeIndependentBlocks
1627 input BackendDAE.EqSystem syst1;
1628 input BackendDAE.EqSystem syst2;
1629 output BackendDAE.EqSystem syst;
1630 protected
1631 BackendDAE.Variables vars;
1632 BackendDAE.EquationArray eqs, removedEqs;
1633 BackendDAE.StateSets stateSets;
1634 algorithm
1635 7892 vars := BackendVariable.addVariables(syst1.orderedVars, syst2.orderedVars);
1636 7892 eqs := BackendEquation.addList(BackendEquation.equationList(syst1.orderedEqs), syst2.orderedEqs);
1637 7892 removedEqs := BackendEquation.addList(BackendEquation.equationList(syst1.removedEqs), syst2.removedEqs);
1638 7892 stateSets := listAppend(syst1.stateSets, syst2.stateSets);
1639 7892 syst := BackendDAEUtil.createEqSystem(vars, eqs, stateSets, BackendDAE.UNKNOWN_PARTITION(), removedEqs);
1640 end mergeIndependentBlocks;
1641
1642 public function partitionIndependentBlocks
1643 "Finds independent partitions of the equation system by "
1644 input BackendDAE.BackendDAE dlow;
1645 output BackendDAE.BackendDAE outDlow;
1646 algorithm
1647 outDlow := match dlow
1648 local
1649 BackendDAE.EqSystem syst;
1650 list<BackendDAE.EqSystem> systs;
1651 BackendDAE.Shared shared;
1652
1653 case BackendDAE.DAE({syst},shared)
1654 algorithm
1655 ✗ (systs,shared) := partitionIndependentBlocksHelper(syst,shared,Error.getNumErrorMessages(),false);
1656 ✗ then BackendDAE.DAE(systs,shared);
1657 else // TODO: Improve support for partitioned systems of equations
1658 algorithm
1659 ✗ BackendDAE.DAE({syst},shared) := collapseIndependentBlocks(dlow);
1660 ✗ (systs,shared) := partitionIndependentBlocksHelper(syst,shared,Error.getNumErrorMessages(),false);
1661 ✗ then BackendDAE.DAE(systs,shared);
1662 end match;
1663 end partitionIndependentBlocks;
1664
1665 public function partitionIndependentBlocksHelper
1666 "Finds independent partitions of the equation system by "
1667 input BackendDAE.EqSystem isyst;
1668 input BackendDAE.Shared ishared;
1669 input Integer numErrorMessages;
1670 input Boolean throwNoError;
1671 output list<BackendDAE.EqSystem> systs;
1672 output BackendDAE.Shared oshared;
1673 algorithm
1674 (systs,oshared) := matchcontinue (isyst, ishared)
1675 local
1676 BackendDAE.AdjacencyMatrix m, mT, rm, rmT;
1677 array<Integer> eqPartMap, varPartMap, rixs;
1678 array<Boolean> vars, rvars;
1679 Boolean b, isInitial;
1680 Integer i;
1681 BackendDAE.Shared shared;
1682 BackendDAE.EqSystem syst;
1683 AvlTreePathFunction.Tree funcs;
1684 case (syst, shared)
1685 algorithm
1686 1120 isInitial := BackendDAEUtil.isInitializationDAE(ishared);
1687 1120 funcs := BackendDAEUtil.getFunctions(ishared);
1688 1120 (syst, m, mT) := BackendDAEUtil.getAdjacencyMatrixfromOption(syst, BackendDAE.NORMAL(), SOME(funcs), isInitial);
1689 1120 (rm, rmT) := BackendDAEUtil.removedAdjacencyMatrix(syst, BackendDAE.NORMAL(), SOME(funcs), isInitial);
1690
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1120 times.
2240 eqPartMap := arrayCreate(arrayLength(m), 0);
1691
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1120 times.
2240 varPartMap := arrayCreate(arrayLength(mT), 0);
1692 1120 rixs := arrayCreate(arrayLength(rm), 0);
1693
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1120 times.
2240 vars := arrayCreate(arrayLength(mT), false);
1694
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1120 times.
2240 rvars := arrayCreate(arrayLength(rmT), false);
1695 // ixsT = arrayCreate(arrayLength(mT),0);
1696 1120 i := SynchronousFeatures.partitionIndependentBlocks0(m, mT, rm, rmT, eqPartMap, varPartMap, rixs, vars, rvars);
1697 // i2 = SynchronousFeatures.partitionIndependentBlocks0(mT,m,ixsT);
1698 b := i > 1;
1699 // bcall2(b,BackendDump.dumpBackendDAE,BackendDAE.DAE({syst},shared), "partitionIndependentBlocksHelper");
1700 // printPartition(b,ixs);
1701
2/2
✓ Branch 0 taken 762 times.
✓ Branch 1 taken 358 times.
1120 systs := if b then SynchronousFeatures.partitionIndependentBlocksSplitBlocks(i, syst, eqPartMap, rixs, mT, rmT, throwNoError, funcs, isInitial) else {syst};
1702 // print("Number of partitioned systems: " + intString(listLength(systs)) + "\n");
1703 // List.map1_0(systs, BackendDump.dumpEqSystem, "System");
1704 1120 GCExt.free(eqPartMap);
1705 1120 GCExt.free(varPartMap);
1706 1120 GCExt.free(rixs);
1707 then (systs,shared);
1708 else
1709 algorithm
1710 ✗ Error.assertion(not (numErrorMessages==Error.getNumErrorMessages()),"BackendDAEOptimize.partitionIndependentBlocks failed without good error message",Absyn.dummyInfo);
1711 ✗ then fail();
1712 end matchcontinue;
1713 end partitionIndependentBlocksHelper;
1714
1715
1716 // =============================================================================
1717 // residual stuff ... for whatever reason
1718 //
1719 // =============================================================================
1720
1721 public function residualForm
1722 "Puts equations like x=y in the form of 0=x-y"
1723 input BackendDAE.BackendDAE dlow;
1724 output BackendDAE.BackendDAE odlow;
1725 algorithm
1726 ✗ odlow := BackendDAEUtil.mapEqSystem1(dlow,residualForm1,1);
1727 end residualForm;
1728
1729 protected function residualForm1
1730 "Puts equations like x=y in the form of 0=x-y"
1731 input BackendDAE.EqSystem syst;
1732 input Integer i;
1733 input BackendDAE.Shared shared;
1734 output BackendDAE.EqSystem osyst = syst;
1735 output BackendDAE.Shared oshared = shared;
1736 protected
1737 BackendDAE.EquationArray eqs;
1738 algorithm
1739 ✗ BackendDAE.EQSYSTEM(orderedEqs=eqs) := syst;
1740 ✗ BackendEquation.traverseEquationArray_WithUpdate(eqs, residualForm2, 1);
1741 end residualForm1;
1742
1743 protected function residualForm2
1744 input BackendDAE.Equation inEq;
1745 input Integer ii;
1746 output BackendDAE.Equation outEq;
1747 output Integer oi;
1748 algorithm
1749 (outEq,oi) := matchcontinue (inEq,ii)
1750 local
1751 DAE.Exp e1,e2,e;
1752 DAE.ElementSource source;
1753 Integer i;
1754 BackendDAE.EquationAttributes eqAttr;
1755
1756 case (BackendDAE.EQUATION(e1,e2,source,eqAttr),i)
1757 algorithm
1758 // This is ok, because EQUATION is not an array equation :D
1759 ✗ DAE.T_REAL() := Expression.typeof(e1);
1760 ✗ false := Expression.isZero(e1) or Expression.isZero(e2);
1761 ✗ e := DAE.BINARY(e1,DAE.SUB(DAE.T_REAL_DEFAULT),e2);
1762 ✗ (e,_) := ExpressionSimplify.simplify(e);
1763 ✗ source := ElementSource.addSymbolicTransformation(source, DAE.OP_RESIDUAL(e1,e2,e));
1764 ✗ then (BackendDAE.EQUATION(DAE.RCONST(0.0),e,source,eqAttr),i);
1765 else (inEq,ii);
1766 end matchcontinue;
1767 end residualForm2;
1768
1769 // =============================================================================
1770 // countOperations
1771 //
1772 // =============================================================================
1773
1774 public function countOperations "author: Frenkel TUD 2011-05"
1775 input BackendDAE.BackendDAE inDAE;
1776 output BackendDAE.BackendDAE outDAE;
1777 algorithm
1778 ✗ if Flags.isSet(Flags.COUNT_OPERATIONS) then
1779 ✗ (outDAE, _) := BackendDAEUtil.mapEqSystemAndFold(inDAE, countOperations0, false);
1780 else
1781 outDAE := inDAE;
1782 end if;
1783 end countOperations;
1784
1785 protected function countOperations0 "author: Frenkel TUD 2011-05"
1786 input BackendDAE.EqSystem isyst;
1787 input BackendDAE.Shared inShared;
1788 input Boolean inChanged;
1789 output BackendDAE.EqSystem osyst = isyst;
1790 output BackendDAE.Shared outShared = inShared;
1791 output Boolean outChanged = inChanged;
1792 protected
1793 list<BackendDAE.CompInfo> compInfos;
1794 BackendDAE.StrongComponents comps;
1795 algorithm
1796 ✗ BackendDAE.EQSYSTEM(matching=BackendDAE.MATCHING(comps=comps)) := isyst;
1797 ✗ compInfos := countOperationstraverseComps(comps, isyst, inShared,{});
1798 end countOperations0;
1799
1800 public function countOperationstraverseComps "author: Frenkel TUD 2012-05"
1801 input BackendDAE.StrongComponents inComps;
1802 input BackendDAE.EqSystem isyst;
1803 input BackendDAE.Shared ishared;
1804 input list<BackendDAE.CompInfo> compInfosIn;
1805 output list<BackendDAE.CompInfo> compInfosOut;
1806 algorithm
1807 compInfosOut := matchcontinue (inComps, ishared)
1808 local
1809 Integer eqIdx, numAdd,numMul,numDiv,numTrig,numRel,numOth, numFuncs, numLog, size, jacEntries;
1810 Real density;
1811 list<Integer> eqs, tornEqs,otherEqs;
1812 BackendDAE.StrongComponent comp;
1813 BackendDAE.StrongComponents rest;
1814 BackendDAE.EquationArray eqns;
1815 BackendDAE.Variables vars;
1816 BackendDAE.Equation eqn;
1817 BackendDAE.CompInfo compInfo, allOps, torn,other;
1818 list<BackendDAE.Equation> eqnlst;
1819 BackendDAE.Jacobian jac;
1820 AvlTreePathFunction.Tree funcs;
1821 list<BackendDAE.Var> varlst;
1822 list<DAE.Exp> explst;
1823 BackendDAE.InnerEquations innerEquations;
1824 list<Integer> vlst;
1825 list<list<Integer>> vLstLst;
1826 case ({}, _) then compInfosIn;
1827 case (BackendDAE.SINGLEEQUATION(eqn=eqIdx)::rest, _)
1828 algorithm
1829 1428 eqns := BackendEquation.getEqnsFromEqSystem(isyst);
1830 1428 eqn := BackendEquation.get(eqns, eqIdx);
1831 //BackendDump.dumpBackendDAEEqnList({eqn},"AN EQUATION",true);
1832 //BackendDump.dumpEquationList({eqn},"");
1833 1428 (_,(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs)) := BackendEquation.traverseExpsOfEquation(eqn,function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0));
1834 1428 compInfo := BackendDAE.COUNTER(listHead(inComps),numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs);
1835
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1428 times.
1428 if Flags.isSet(Flags.COUNT_OPERATIONS) then BackendDump.dumpCompInfo(compInfo); end if;
1836 1428 then countOperationstraverseComps(rest,isyst,ishared,compInfo::compInfosIn);
1837
1838 case (BackendDAE.SINGLEWHENEQUATION(eqn=eqIdx)::rest, _)
1839 algorithm
1840 27 eqn := BackendEquation.get(BackendEquation.getEqnsFromEqSystem(isyst), eqIdx);
1841 //BackendDump.printEquation(eqn);
1842 27 (_,(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs)) := BackendEquation.traverseExpsOfEquation(eqn,function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0));
1843 27 compInfo := BackendDAE.COUNTER(listHead(inComps),numAdd,numMul,numDiv,numTrig,numRel,numLog+1,numOth,numFuncs);
1844
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 27 times.
27 if Flags.isSet(Flags.COUNT_OPERATIONS) then BackendDump.dumpCompInfo(compInfo); end if;
1845 27 then countOperationstraverseComps(rest,isyst,ishared,compInfo::compInfosIn);
1846
1847 case ((comp as BackendDAE.EQUATIONSYSTEM(eqns=eqs,jac=jac,jacType=BackendDAE.JAC_LINEAR()))::rest, _)
1848 algorithm
1849 ✗ BackendDAETransform.getEquationAndSolvedVar(comp, BackendEquation.getEqnsFromEqSystem(isyst), BackendVariable.daeVars(isyst));
1850 ✗ size := listLength(eqs);
1851 ✗ density := realDiv(intReal(getNumJacEntries(jac)),intReal(size*size ));
1852 ✗ allOps := BackendDAE.COUNTER(comp,0,0,0,0,0,0,0,0);
1853 ✗ allOps := countOperationsJac(jac,ishared,allOps);
1854 ✗ compInfo := BackendDAE.SYSTEM(comp,allOps,size,density);
1855 ✗ then countOperationstraverseComps(rest,isyst,ishared,compInfo::compInfosIn);
1856
1857 case ((comp as BackendDAE.EQUATIONSYSTEM(jac=jac))::rest, _)
1858 algorithm
1859 22 (eqnlst,_,_) := BackendDAETransform.getEquationAndSolvedVar(comp, BackendEquation.getEqnsFromEqSystem(isyst), BackendVariable.daeVars(isyst));
1860 22 size := listLength(eqnlst);
1861 22 (numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs) := BackendDAEUtil.traverseBackendDAEExpsEqns(BackendEquation.listEquation(eqnlst),function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0));
1862 22 allOps := BackendDAE.COUNTER(comp,numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs);
1863 22 jacEntries := getNumJacEntries(jac);
1864
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
22 if intEq(jacEntries,-1) then jacEntries := size*size; end if; // a non linear system that is too small and too dense (usually 2x2) to be torn
1865
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
22 density := realDiv(intReal(jacEntries),intReal(size*size));
1866 22 compInfo := BackendDAE.SYSTEM(comp,allOps,size,density);
1867 22 then
1868 countOperationstraverseComps(rest,isyst,ishared,compInfo::compInfosIn);
1869
1870 case ((comp as BackendDAE.SINGLEARRAY(eqn=eqIdx))::rest, _)
1871 algorithm
1872 ✗ eqn := BackendEquation.get(BackendEquation.getEqnsFromEqSystem(isyst), eqIdx);
1873 ✗ (_,(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs)) := BackendEquation.traverseExpsOfEquation(eqn,function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0));
1874 ✗ compInfo := BackendDAE.COUNTER(comp,numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs);
1875 ✗ then
1876 countOperationstraverseComps(rest,isyst,ishared,compInfo::compInfosIn);
1877
1878 case ((comp as BackendDAE.SINGLEIFEQUATION(eqn=eqIdx))::rest, _)
1879 algorithm
1880 ✗ eqn := BackendEquation.get(BackendEquation.getEqnsFromEqSystem(isyst), eqIdx);
1881 ✗ (_,(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs)) := BackendEquation.traverseExpsOfEquation(eqn,function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0));
1882 ✗ compInfo := BackendDAE.COUNTER(comp,numAdd,numMul,numDiv,numTrig,numRel,numLog+1,numOth,numFuncs);
1883 ✗ then
1884 countOperationstraverseComps(rest,isyst,ishared,compInfo::compInfosIn);
1885
1886 case ((comp as BackendDAE.SINGLEALGORITHM(eqn=eqIdx))::rest, _)
1887 algorithm
1888 1 eqn := BackendEquation.get(BackendEquation.getEqnsFromEqSystem(isyst), eqIdx);
1889 1 (_,(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs)) := BackendEquation.traverseExpsOfEquation(eqn,function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0));
1890 1 compInfo := BackendDAE.COUNTER(comp,numAdd,numMul,numDiv,numTrig,numRel,numLog+1,numOth,numFuncs);
1891 1 then
1892 countOperationstraverseComps(rest,isyst,ishared,compInfo::compInfosIn);
1893
1894 case ((comp as BackendDAE.SINGLECOMPLEXEQUATION(eqn=eqIdx))::rest, _)
1895 algorithm
1896 ✗ eqn := BackendEquation.get(BackendEquation.getEqnsFromEqSystem(isyst), eqIdx);
1897 ✗ (_,(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs)) := BackendEquation.traverseExpsOfEquation(eqn,function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0));
1898 ✗ compInfo := BackendDAE.COUNTER(comp,numAdd,numMul,numDiv,numTrig,numRel,numLog+1,numOth,numFuncs);
1899 ✗ then
1900 countOperationstraverseComps(rest,isyst,ishared,compInfo::compInfosIn);
1901
1902 case (BackendDAE.TORNSYSTEM(strictTearingSet=BackendDAE.TEARINGSET(tearingvars=vlst, residualequations=tornEqs, innerEquations= innerEquations), linear = true)::rest, BackendDAE.SHARED(functionTree=funcs))
1903 algorithm
1904 30 comp := listHead(inComps);
1905 30 eqns := BackendEquation.getEqnsFromEqSystem(isyst);
1906 30 vars := BackendVariable.daeVars(isyst);
1907 // the torn equations
1908 30 eqnlst := BackendEquation.getList(tornEqs,eqns);
1909 30 varlst := List.map1(vlst,BackendVariable.getVarAtIndexFirst, vars);
1910 30 (explst,_) := BackendDAEUtil.getEqnSysRhs(BackendEquation.listEquation(eqnlst),BackendVariable.listVar1(varlst),SOME(funcs));
1911 30 (_,(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs)) := Expression.traverseExpList(explst,function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0));
1912 30 torn := BackendDAE.COUNTER(comp,numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs);
1913 // the other eqs
1914 30 (otherEqs,vLstLst,_) := List.map_3(innerEquations, BackendDAEUtil.getEqnAndVarsFromInnerEquation);
1915 30 vlst := List.flatten(vLstLst);
1916 30 eqnlst := BackendEquation.getList(otherEqs,eqns);
1917 30 varlst := List.map1(vlst,BackendVariable.getVarAtIndexFirst, vars);
1918 30 (explst,_) := BackendDAEUtil.getEqnSysRhs(BackendEquation.listEquation(eqnlst),BackendVariable.listVar1(varlst),SOME(funcs));
1919 30 (_,(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs)) := Expression.traverseExpList(explst,function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0));
1920 30 other := BackendDAE.COUNTER(comp,numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs);
1921 30 compInfo := BackendDAE.TORN_ANALYSE(comp,torn,other,listLength(tornEqs));
1922 30 then
1923 countOperationstraverseComps(rest,isyst,ishared,compInfo::compInfosIn);
1924 case (BackendDAE.TORNSYSTEM(strictTearingSet=BackendDAE.TEARINGSET(residualequations=tornEqs, innerEquations = innerEquations), linear = false)::rest, BackendDAE.SHARED())
1925 algorithm
1926 23 comp := listHead(inComps);
1927 23 eqns := BackendEquation.getEqnsFromEqSystem(isyst);
1928 // the torn equations
1929 23 eqnlst := BackendEquation.getList(tornEqs,eqns);
1930 23 explst := List.map(eqnlst,BackendEquation.getEquationRHS);
1931 23 (_,(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs)) := Expression.traverseExpList(explst,function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0));
1932 23 torn := BackendDAE.COUNTER(comp,numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs);
1933 // the other eqs
1934 23 (otherEqs,_,_) := List.map_3(innerEquations, BackendDAEUtil.getEqnAndVarsFromInnerEquation);
1935 23 eqnlst := BackendEquation.getList(otherEqs,eqns);
1936 23 explst := List.map(eqnlst,BackendEquation.getEquationRHS);
1937 23 (_,(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs)) := Expression.traverseExpList(explst,function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0));
1938 23 other := BackendDAE.COUNTER(comp,numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs);
1939 23 compInfo := BackendDAE.TORN_ANALYSE(comp,torn,other,listLength(tornEqs));
1940 23 then
1941 countOperationstraverseComps(rest,isyst,ishared,compInfo::compInfosIn);
1942 case (comp::rest, _)
1943 algorithm
1944 ✗ print("not supported component: "+BackendDump.strongComponentString(comp)+"\n");
1945 ✗ then
1946 countOperationstraverseComps(rest,isyst,ishared,compInfosIn);
1947 end matchcontinue;
1948 end countOperationstraverseComps;
1949
1950 protected function getNumJacEntries
1951 input BackendDAE.Jacobian inJac;
1952 output Integer numEntries;
1953 algorithm
1954 numEntries := match inJac
1955 local
1956 list<tuple<Integer, Integer, BackendDAE.Equation>> jac;
1957 list<BackendDAE.Var> vars1, vars2;
1958 case BackendDAE.FULL_JACOBIAN(NONE())
1959 then -1;
1960 case BackendDAE.FULL_JACOBIAN(SOME(jac))
1961 ✗ then listLength(jac);
1962 case BackendDAE.EMPTY_JACOBIAN()
1963 then -1;
1964 /* TODO: implement/check for GENERIC_JACOBIAN */
1965 case BackendDAE.GENERIC_JACOBIAN(jacobian=NONE())
1966 then -1;
1967 case BackendDAE.GENERIC_JACOBIAN(jacobian=SOME((_,_,vars1,vars2,_,_)))
1968 guard
1969 listLength(vars1) == listLength(vars2)
1970 ✗ then listLength(vars1);
1971 else
1972 algorithm
1973 //print(BackendDump.jacobianString(inJac));
1974 ✗ print("another JAC\n");
1975 then -1;
1976 end match;
1977 end getNumJacEntries;
1978
1979
1980 protected function countOperationsJac
1981 input BackendDAE.Jacobian inJac;
1982 input BackendDAE.Shared shared;
1983 input BackendDAE.CompInfo compInfoIn;
1984 output BackendDAE.CompInfo compInfoOut;
1985 algorithm
1986 compInfoOut := match(inJac, compInfoIn)
1987 local
1988 Integer numAdd,numMul,numDiv,numOth,numTrig,numRel,numLog, numFuncs;
1989 list<tuple<Integer, Integer, BackendDAE.Equation>> jac;
1990 BackendDAE.StrongComponent comp;
1991 case (BackendDAE.FULL_JACOBIAN(NONE()), _) then compInfoIn;
1992 case (BackendDAE.FULL_JACOBIAN(SOME(jac)), BackendDAE.COUNTER(comp=comp,numAdds=numAdd,numMul=numMul,numDiv=numDiv,numTrig=numTrig,numRelations=numRel,numLog=numLog,numOth=numOth,funcCalls=numFuncs))
1993 algorithm
1994 ✗ (numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs) := List.fold(jac,function countOperationsJac1(shared=shared),((numAdd,numMul,numDiv,numOth,numTrig,numRel,numLog,numFuncs)));
1995 ✗ then BackendDAE.COUNTER(comp,numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs);
1996 /* TODO: implement for GENERIC_JACOBIAN */
1997 case (_, _) then compInfoIn;
1998 end match;
1999 end countOperationsJac;
2000
2001 protected function countOperationsJac1
2002 input tuple<Integer, Integer, BackendDAE.Equation> inJac;
2003 input BackendDAE.Shared shared;
2004 input tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> inTpl;
2005 output tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> outTpl;
2006 algorithm
2007 ✗ (_,outTpl) := BackendEquation.traverseExpsOfEquation(Util.tuple33(inJac),function countOperationsExp(shared=shared),inTpl);
2008 end countOperationsJac1;
2009
2010 public function countOperationsExp
2011 input DAE.Exp inExp;
2012 input BackendDAE.Shared shared;
2013 input tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> inTpl;
2014 output DAE.Exp outExp;
2015 output tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> outTpl;
2016 algorithm
2017 13923 (outExp,outTpl) := Expression.traverseExpBottomUp(inExp,function traversecountOperationsExp(shared=shared),inTpl);
2018 end countOperationsExp;
2019
2020 protected function traversecountOperationsExp
2021 input DAE.Exp inExp;
2022 input BackendDAE.Shared shared;
2023 input tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> inTuple;
2024 output DAE.Exp outExp;
2025 output tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> outTuple;
2026 algorithm
2027 (outExp,outTuple) := matchcontinue (inExp, inTuple)
2028 local
2029 Absyn.Path path;
2030 DAE.Exp e,cond,exp1,exp2;
2031 DAE.Function func;
2032 Integer i1,i2,i3,i4,i5,i6,i7,i8;
2033 tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> tpl;
2034 DAE.Operator op;
2035 String opName;
2036 Absyn.Path path;
2037 list<DAE.Exp> expLst;
2038 list<DAE.Element> elemLst;
2039 //case (e as DAE.BINARY(operator=DAE.POW(),exp2=DAE.RCONST(rexp2)),_,(i1,i2,i3,i4,i5,i6)) equation
2040 // iexp2 = realInt(rexp2);
2041 // true = realEq(rexp2, intReal(iexp2));
2042 // i2_1 = i2+intAbs(iexp2)-1;
2043 // then (e, (i1,i2_1,i3,i4,i5,i6));
2044
2045 case (e as DAE.BINARY(operator=op), _) algorithm
2046 11407 tpl := countOperator(op,inTuple);
2047 then (e, tpl);
2048
2049 case (e as DAE.UNARY(operator=op), _) algorithm
2050 771 tpl := countOperator(op,inTuple);
2051 then (e, tpl);
2052
2053 case (e as DAE.LBINARY(operator=op), _) algorithm
2054 331 tpl := countOperator(op,inTuple);
2055 then (e, tpl);
2056
2057 case (e as DAE.LUNARY(operator=op), _) algorithm
2058 433 tpl := countOperator(op,inTuple);
2059 then (e, tpl);
2060
2061 case (e as DAE.RELATION(operator=op), _) algorithm
2062 1935 tpl := countOperator(op,inTuple);
2063 then (e, tpl);
2064
2065 case (e as DAE.IFEXP(expCond=cond,expThen=exp1,expElse=exp2), _) algorithm
2066 //count all branches, use the complete count for the condition and one additional logical count
2067 938 (_,tpl) := traversecountOperationsExp(exp1,shared,inTuple);
2068 938 (_,tpl) := traversecountOperationsExp(exp2,shared,tpl);
2069 938 (_,(i1,i2,i3,i4,i5,i6,i7,i8)) := traversecountOperationsExp(cond,shared,tpl);
2070 938 then (e, (i1,i2,i3,i4,i5,i6+1,i7,i8));
2071
2072 case (e as DAE.RECORD(exps=expLst), _) algorithm
2073 120 (_,tpl) := Expression.traverseExpList(expLst,function countOperationsExp(shared=shared),inTuple);
2074 120 then (e, tpl);
2075
2076 case (e as DAE.ARRAY(array=expLst), _) algorithm
2077 352 (_,tpl) := Expression.traverseExpList(expLst,function countOperationsExp(shared=shared),inTuple);
2078 352 then (e, tpl);
2079
2080 case (e as DAE.TUPLE(PR=expLst), _) algorithm
2081 154 (_,tpl) := Expression.traverseExpList(expLst,function countOperationsExp(shared=shared),inTuple);
2082 154 then (e, tpl);
2083
2084 case (e as DAE.CALL(path=Absyn.IDENT(name=opName)), (i1,i2,i3,i4,i5,i6,i7,i8))
2085 guard stringEq(opName,"sin") or stringEq(opName,"cos") or stringEq(opName,"tan")
2086 151 then (e, (i1,i2,i3,i4+1,i5,i6,i7,i8));
2087
2088 case (e as DAE.CALL(path=Absyn.IDENT(name="der")), (i1,i2,i3,i4,i5,i6,i7,i8))
2089 1159 then (e, (i1,i2,i3,i4,i5,i6,i7,i8));
2090
2091 case (e as DAE.CALL(path=Absyn.IDENT(name="exp")), (i1,i2,i3,i4,i5,i6,i7,i8))
2092 59 then (e, (i1,i2,i3,i4,i5,i6,i7+1,i8));
2093
2094 case (e as DAE.CALL(path=Absyn.IDENT(name="pre")), (i1,i2,i3,i4,i5,i6,i7,i8))
2095 245 then (e, (i1,i2,i3,i4,i5,i6,i7,i8+1));
2096
2097 case (e as DAE.CALL(path=Absyn.IDENT(name="previous")), (i1,i2,i3,i4,i5,i6,i7,i8))
2098 ✗ then (e, (i1,i2,i3,i4,i5,i6,i7,i8+1));
2099
2100 case (e as DAE.CALL(path=path), _) algorithm
2101 2024 func := DAEUtil.getNamedFunction(path,BackendDAEUtil.getFunctions(shared));
2102 1135 elemLst := DAEUtil.getFunctionElements(func);
2103 //print(ExpressionDump.dumpExpStr(e,0)+"\n");
2104 //print("THE FUNCTION CALL\n "+DAEDump.dumpElementsStr(elemLst)+"\n");
2105 1135 (i1,i2,i3,i4,i5,i6,i7,i8) := countOperationsInFunction(elemLst,shared,inTuple);
2106 1135 then (e, (i1,i2,i3,i4,i5,i6,i7,i8+1));
2107 else
2108 algorithm
2109 //print(ExpressionDump.dumpExpStr(inExp,0)+"\n");
2110 then (inExp,inTuple);
2111 end matchcontinue;
2112 end traversecountOperationsExp;
2113
2114 protected function countOperationsInFunction
2115 input list<DAE.Element> elemLst;
2116 input BackendDAE.Shared shared;
2117 input tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> inTpl;
2118 output tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> outTpl;
2119 algorithm
2120 outTpl := matchcontinue elemLst
2121 local
2122 tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> tpl;
2123 DAE.Exp exp1, exp2;
2124 list<DAE.Statement> stmts;
2125 list<DAE.Element> rest;
2126 case {}
2127 algorithm
2128 then inTpl;
2129 case DAE.ALGORITHM(algorithm_=DAE.ALGORITHM_STMTS(statementLst=stmts))::rest
2130 algorithm
2131 878 (_,tpl) := DAEUtil.traverseDAEEquationsStmts(stmts,function traversecountOperationsExp(shared=shared),inTpl);
2132 878 then countOperationsInFunction(rest,shared,tpl);
2133 case DAE.EQUATION(exp=exp1, scalar=exp2)::rest
2134 algorithm
2135 ✗ (_,tpl) := traversecountOperationsExp(exp1,shared,inTpl);
2136 ✗ (_,tpl) := traversecountOperationsExp(exp2,shared,tpl);
2137 ✗ then countOperationsInFunction(rest,shared,tpl);
2138 case DAE.COMPLEX_EQUATION(lhs=exp1, rhs=exp2)::rest
2139 algorithm
2140 ✗ (_,tpl) := traversecountOperationsExp(exp1,shared,inTpl);
2141 ✗ (_,tpl) := traversecountOperationsExp(exp2,shared,tpl);
2142 ✗ then countOperationsInFunction(rest,shared,tpl);
2143 case _::rest
2144 algorithm
2145 8942 then countOperationsInFunction(rest,shared,inTpl);
2146 end matchcontinue;
2147 end countOperationsInFunction;
2148
2149 protected function countOperator
2150 input DAE.Operator op;
2151 input tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> inTpl; // add,mul,div,trig,relations,logical,other,funcCalls
2152 output tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> outTpl;
2153 algorithm
2154 outTpl := match(op, inTpl)
2155 local
2156 DAE.Type tp;
2157 Integer i,i1,i2,i3,i4,i5,i6,i7,i8;
2158 case (DAE.ADD(),(i1,i2,i3,i4,i5,i6,i7,i8))
2159 2225 then (i1+1,i2,i3,i4,i5,i6,i7,i8);
2160 case (DAE.SUB(),(i1,i2,i3,i4,i5,i6,i7,i8))
2161 2645 then (i1+1,i2,i3,i4,i5,i6,i7,i8);
2162 case (DAE.MUL(),(i1,i2,i3,i4,i5,i6,i7,i8))
2163 4629 then (i1,i2+1,i3,i4,i5,i6,i7,i8);
2164 case (DAE.DIV(),(i1,i2,i3,i4,i5,i6,i7,i8))
2165 1376 then (i1,i2,i3+1,i4,i5,i6,i7,i8);
2166 case (DAE.POW(),(i1,i2,i3,i4,i5,i6,i7,i8))
2167 532 then (i1,i2,i3,i4,i5,i6,i7+1,i8);
2168 case (DAE.UMINUS(),(i1,i2,i3,i4,i5,i6,i7,i8))
2169 771 then (i1+1,i2,i3,i4,i5,i6,i7,i8);
2170 case (DAE.UMINUS_ARR(ty=tp),(i1,i2,i3,i4,i5,i6,i7,i8)) algorithm
2171 ✗ i := Expression.sizeOf(tp);
2172 ✗ then (i1+i,i2,i3,i4,i5,i6,i7,i8);
2173 case (DAE.ADD_ARR(ty=tp),(i1,i2,i3,i4,i5,i6,i7,i8)) algorithm
2174 ✗ i := Expression.sizeOf(tp);
2175 ✗ then (i1+i,i2,i3,i4,i5,i6,i7,i8);
2176 case (DAE.SUB_ARR(ty=tp),(i1,i2,i3,i4,i5,i6,i7,i8)) algorithm
2177 ✗ i := Expression.sizeOf(tp);
2178 ✗ then (i1+i,i2,i3,i4,i5,i6,i7,i8);
2179 case (DAE.MUL_ARR(ty=tp),(i1,i2,i3,i4,i5,i6,i7,i8)) algorithm
2180 ✗ i := Expression.sizeOf(tp);
2181 ✗ then (i1,i2+i,i3,i4,i5,i6,i7,i8);
2182 case (DAE.DIV_ARR(ty=tp),(i1,i2,i3,i4,i5,i6,i7,i8)) algorithm
2183 ✗ i := Expression.sizeOf(tp);
2184 ✗ then (i1,i2,i3+i,i4,i5,i6,i7,i8);
2185 case (DAE.MUL_ARRAY_SCALAR(),(i1,i2,i3,i4,i5,i6,i7,i8))
2186 ✗ then (i1,i2+1,i3,i4,i5,i6,i7,i8);
2187 case (DAE.ADD_ARRAY_SCALAR(),(i1,i2,i3,i4,i5,i6,i7,i8))
2188 ✗ then (i1+1,i2,i3,i4,i5,i6,i7,i8);
2189 case (DAE.SUB_SCALAR_ARRAY(),(i1,i2,i3,i4,i5,i6,i7,i8))
2190 ✗ then (i1+1,i2,i3,i4,i5,i6,i7,i8);
2191 case (DAE.MUL_SCALAR_PRODUCT(),(i1,i2,i3,i4,i5,i6,i7,i8))
2192 ✗ then (i1,i2+1,i3,i4,i5,i6,i7,i8);
2193 case (DAE.MUL_MATRIX_PRODUCT(),(i1,i2,i3,i4,i5,i6,i7,i8))
2194 ✗ then (i1,i2+1,i3,i4,i5,i6,i7,i8);
2195 case (DAE.DIV_ARRAY_SCALAR(),(i1,i2,i3,i4,i5,i6,i7,i8))
2196 ✗ then (i1,i2,i3+1,i4,i5,i6,i7,i8);
2197 case (DAE.DIV_SCALAR_ARRAY(),(i1,i2,i3,i4,i5,i6,i7,i8))
2198 ✗ then (i1,i2,i3+1,i4,i5,i6,i7,i8);
2199 case (DAE.POW_ARRAY_SCALAR(),(i1,i2,i3,i4,i5,i6,i7,i8))
2200 ✗ then (i1,i2,i3,i4,i5,i6,i7+1,i8);
2201 case (DAE.POW_SCALAR_ARRAY(),(i1,i2,i3,i4,i5,i6,i7,i8))
2202 ✗ then (i1,i2,i3,i4,i5,i6,i7+1,i8);
2203 case (DAE.POW_ARR(),(i1,i2,i3,i4,i5,i6,i7,i8))
2204 ✗ then (i1,i2,i3,i4,i5,i6,i7+1,i8);
2205 case (DAE.POW_ARR2(),(i1,i2,i3,i4,i5,i6,i7,i8))
2206 ✗ then (i1,i2,i3,i4,i5,i6,i7+1,i8);
2207 case (DAE.AND(),(i1,i2,i3,i4,i5,i6,i7,i8))
2208 166 then (i1,i2,i3,i4,i5,i6+1,i7,i8);
2209 case (DAE.OR(),(i1,i2,i3,i4,i5,i6,i7,i8))
2210 165 then (i1,i2,i3,i4,i5,i6+1,i7,i8);
2211 case (DAE.NOT(),(i1,i2,i3,i4,i5,i6,i7,i8))
2212 433 then (i1,i2,i3,i4,i5,i6+1,i7,i8);
2213 case (DAE.LESS(),(i1,i2,i3,i4,i5,i6,i7,i8))
2214 522 then (i1,i2,i3,i4,i5+1,i6,i7,i8);
2215 case (DAE.LESSEQ(),(i1,i2,i3,i4,i5,i6,i7,i8))
2216 229 then (i1,i2,i3,i4,i5+1,i6,i7,i8);
2217 case (DAE.GREATER(),(i1,i2,i3,i4,i5,i6,i7,i8))
2218 524 then (i1,i2,i3,i4,i5+1,i6,i7,i8);
2219 case (DAE.GREATEREQ(),(i1,i2,i3,i4,i5,i6,i7,i8))
2220 289 then (i1,i2,i3,i4,i5+1,i6,i7,i8);
2221 case (DAE.EQUAL(),(i1,i2,i3,i4,i5,i6,i7,i8))
2222 369 then (i1,i2,i3,i4,i5+1,i6,i7,i8);
2223 case (DAE.NEQUAL(),(i1,i2,i3,i4,i5,i6,i7,i8))
2224 2 then (i1,i2,i3,i4,i5+1,i6,i7,i8);
2225 case (DAE.USERDEFINED(),(i1,i2,i3,i4,i5,i6,i7,i8))
2226 ✗ then (i1,i2,i3,i4,i5,i6+1,i7,i8);
2227 else
2228 algorithm
2229 ✗ print("not supported operator\n");
2230 then inTpl;
2231 end match;
2232 end countOperator;
2233
2234
2235 // =============================================================================
2236 // simplify if equations
2237 //
2238 // =============================================================================
2239
2240 public function simplifyIfEquations "author: Frenkel TUD 2012-07
2241 This function traveres all if equations and if expressions and tries to
2242 simplify it by using the information from evaluated parameters."
2243 input BackendDAE.BackendDAE dae;
2244 output BackendDAE.BackendDAE odae;
2245 algorithm
2246 1075 odae := BackendDAEUtil.mapEqSystem(dae, simplifyIfEquationsWork);
2247 end simplifyIfEquations;
2248
2249 protected function simplifyIfEquationsWork "author: Frenkel TUD 2012-07
2250 This function traveres all if equations and if expressions and tries to
2251 simplify it by using the information from evaluated parameters."
2252 input BackendDAE.EqSystem isyst;
2253 input BackendDAE.Shared ishared;
2254 output BackendDAE.EqSystem osyst;
2255 output BackendDAE.Shared oshared;
2256 algorithm
2257 (osyst,oshared) := matchcontinue (isyst, ishared)
2258 local
2259 BackendDAE.Variables globalKnownVars;
2260 BackendDAE.EquationArray eqns, initialEqs;
2261 list<BackendDAE.Equation> eqnslst, asserts, initial_asserts;
2262 BackendDAE.EqSystem syst;
2263 BackendDAE.Shared shared;
2264 Boolean systChanged;
2265
2266 case ( syst as BackendDAE.EQSYSTEM(orderedEqs=eqns),
2267 shared as BackendDAE.SHARED(globalKnownVars=globalKnownVars, initialEqs=initialEqs) )
2268 algorithm
2269 // traverse the equations
2270 1075 eqnslst := BackendEquation.equationList(eqns);
2271 // traverse equations in reverse order, than branch equations of if equaitions need no reverse
2272 1075 (eqnslst,asserts,systChanged) := List.fold31(listReverse(eqnslst), simplifyIfEquationsFinder, globalKnownVars, {},{},false);
2273 1075 syst.orderedEqs := BackendEquation.listEquation(eqnslst);
2274
2275 // traverse the initial equations
2276 1075 eqnslst := BackendEquation.equationList(initialEqs);
2277 // traverse equations in reverse order, than branch equations of if equaitions need no reverse
2278
4/4
✓ Branch 0 taken 1028 times.
✓ Branch 1 taken 47 times.
✓ Branch 4 taken 1025 times.
✓ Branch 5 taken 50 times.
2103 (eqnslst,initial_asserts,true) := List.fold31(listReverse(eqnslst), simplifyIfEquationsFinder, globalKnownVars, {},{},systChanged);
2279
2280 // ticket #5599
2281 // leave initial asserts in the initial equation block
2282 // this just removes the surrounding unnecessary if condition
2283 50 shared.initialEqs := BackendEquation.listEquation(listAppend(initial_asserts, eqnslst));
2284
2285 50 syst := BackendDAEUtil.clearEqSyst(syst);
2286 50 syst := BackendEquation.requationsAddDAE(asserts, syst);
2287 then (syst, shared);
2288
2289 else
2290 then (isyst, ishared);
2291 end matchcontinue;
2292 end simplifyIfEquationsWork;
2293
2294 protected function simplifyIfEquationsFinder
2295 "author: Frenkel TUD 2012-07
2296 helper for simplifyIfEquations"
2297 input BackendDAE.Equation inElem;
2298 input BackendDAE.Variables inConstArg;
2299 input output list<BackendDAE.Equation> acc;
2300 input output list<BackendDAE.Equation> asserts;
2301 input output Boolean b;
2302 algorithm
2303 (acc, asserts, b) := matchcontinue(inElem,inConstArg)
2304 local
2305 list<DAE.Exp> explst;
2306 list<BackendDAE.Equation> eqnslst,asserts1;
2307 list<list<BackendDAE.Equation>> eqnslstlst;
2308 DAE.ElementSource source;
2309 BackendDAE.Variables globalKnownVars;
2310 BackendDAE.Equation eqn;
2311 BackendDAE.EquationAttributes attr;
2312
2313 case (BackendDAE.IF_EQUATION(conditions=explst, eqnstrue=eqnslstlst, eqnsfalse=eqnslst, source=source, attr=attr), globalKnownVars)
2314 algorithm
2315 // check conditions
2316 166 (explst,_) := Expression.traverseExpList(explst, simplifyEvaluatedParamter, (globalKnownVars,false));
2317 166 explst := ExpressionSimplify.simplifyList(explst);
2318 // simplify if equation
2319 166 (acc,asserts1) := simplifyIfEquation(explst,eqnslstlst,eqnslst,{},{},source,globalKnownVars,acc,attr);
2320 166 asserts1 := listAppend(asserts,asserts1);
2321 then
2322 (acc, asserts1, true);
2323
2324 case (eqn,globalKnownVars)
2325 algorithm
2326
2/2
✓ Branch 0 taken 150986 times.
✓ Branch 1 taken 10652 times.
312624 (eqn,(_,b)) := BackendEquation.traverseExpsOfEquation(eqn, simplifyIfExpevaluatedParamter, (globalKnownVars,b));
2327 161638 then
2328 (eqn::acc,asserts,b);
2329 end matchcontinue;
2330 end simplifyIfEquationsFinder;
2331
2332 protected function simplifyIfExpevaluatedParamter
2333 input DAE.Exp inExp;
2334 input tuple<BackendDAE.Variables,Boolean> tpl1;
2335 output DAE.Exp outExp;
2336 output tuple<BackendDAE.Variables,Boolean> tpl2;
2337 algorithm
2338 (outExp,tpl2) := matchcontinue (inExp,tpl1)
2339 local
2340 BackendDAE.Variables globalKnownVars;
2341 DAE.Exp e1,e2,cond,expThen,expElse;
2342 Boolean b,b1;
2343 case (e1 as DAE.IFEXP(expCond=cond, expThen=expThen, expElse=expElse),(globalKnownVars,b))
2344 algorithm
2345 1688 (cond,(_,b1)) := Expression.traverseExpBottomUp(cond, simplifyEvaluatedParamter, (globalKnownVars,false));
2346
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1688 times.
1688 e2 := if b1 then DAE.IFEXP(cond,expThen,expElse) else e1;
2347 1688 (e2,_) := ExpressionSimplify.condsimplify(b1,e2);
2348
2/2
✓ Branch 0 taken 1524 times.
✓ Branch 1 taken 164 times.
3212 then (e2,(globalKnownVars,b or b1));
2349 else (inExp,tpl1);
2350 end matchcontinue;
2351 end simplifyIfExpevaluatedParamter;
2352
2353 protected function simplifyEvaluatedParamter
2354 input DAE.Exp inExp;
2355 input tuple<BackendDAE.Variables,Boolean> tpl1;
2356 output DAE.Exp outExp;
2357 output tuple<BackendDAE.Variables,Boolean> tpl2;
2358 algorithm
2359 (outExp,tpl2) := matchcontinue (inExp,tpl1)
2360 local
2361 BackendDAE.Variables globalKnownVars;
2362 DAE.ComponentRef cr;
2363 BackendDAE.Var v;
2364 DAE.Exp e;
2365 case (DAE.CREF(componentRef = cr),(globalKnownVars,_))
2366 algorithm
2367 4057 (v,_) := BackendVariable.getVarSingle(cr,globalKnownVars);
2368
3/10
✓ Branch 1 taken 466 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 466 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 466 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
466 true := BackendVariable.hasVarEvaluateAnnotationTrue(v)
2369 or (Flags.getConfigBool(Flags.EVALUATE_FINAL_PARAMS) and BackendVariable.isFinalVar(v))
2370 or (Flags.getConfigBool(Flags.EVALUATE_PROTECTED_PARAMS) and BackendVariable.isProtectedVar(v));
2371 ✗ e := BackendVariable.varBindExpStartValue(v);
2372 ✗ then (e,(globalKnownVars,true));
2373 else (inExp,tpl1);
2374 end matchcontinue;
2375 end simplifyEvaluatedParamter;
2376
2377 protected function simplifyIfEquation
2378 "author: Frenkel TUD 2012-07
2379 helper for simplifyIfEquations"
2380 input list<DAE.Exp> conditions;
2381 input list<list<BackendDAE.Equation>> theneqns;
2382 input list<BackendDAE.Equation> elseenqs;
2383 input list<DAE.Exp> conditions1;
2384 input list<list<BackendDAE.Equation>> theneqns1;
2385 input DAE.ElementSource source;
2386 input BackendDAE.Variables globalKnownVars;
2387 input list<BackendDAE.Equation> inEqns;
2388 input BackendDAE.EquationAttributes inEqAttr;
2389 output list<BackendDAE.Equation> outEqns;
2390 output list<BackendDAE.Equation> outAsserts;
2391 algorithm
2392 (outEqns,outAsserts) := match(conditions, theneqns, conditions1, theneqns1)
2393 local
2394 DAE.Exp e;
2395 list<DAE.Exp> explst;
2396 list<list<BackendDAE.Equation>> eqnslst;
2397 list<BackendDAE.Equation> eqns,elseenqs1,asserts;
2398
2399 // no true case left with condition<>false
2400 case ({}, {}, {}, {})
2401 algorithm
2402 // simplify nested if equations
2403 ✗ (eqns,asserts,_) := List.fold31(listReverse(elseenqs), simplifyIfEquationsFinder, globalKnownVars, {},{},false);
2404 ✗ then
2405 (listAppend(eqns,inEqns),asserts);
2406 // true case left with condition<>false
2407 case ({}, {}, _, _)
2408 algorithm
2409 166 explst := listReverse(conditions1);
2410 166 eqnslst := listReverse(theneqns1);
2411 // simplify nested if equations
2412 166 (elseenqs1,asserts,_) := List.fold31(listReverse(elseenqs), simplifyIfEquationsFinder, globalKnownVars, {},{},false);
2413 166 elseenqs1 := listAppend(elseenqs1,asserts) annotation(__OpenModelica_DisableListAppendWarning=true);
2414 166 (eqnslst,elseenqs1,asserts) := simplifyIfEquationAsserts(explst,eqnslst,elseenqs1,{},{},{});
2415 166 eqns := simplifyIfEquation1(explst,eqnslst,elseenqs1,source,globalKnownVars,inEqns,inEqAttr);
2416 166 then
2417 (eqns,asserts);
2418 // if true and first use it
2419 case(DAE.BCONST(true)::_, eqns::_, {}, _)
2420 algorithm
2421 // simplify nested if equations
2422 ✗ (eqns,asserts,_) := List.fold31(listReverse(eqns), simplifyIfEquationsFinder, globalKnownVars, {},{},false);
2423 ✗ then
2424 (listAppend(eqns,inEqns),asserts);
2425 // if true and not first use it as new else
2426 case(DAE.BCONST(true)::_, eqns::_, _, _)
2427 algorithm
2428 ✗ explst := listReverse(conditions1);
2429 ✗ eqnslst := listReverse(theneqns1);
2430 // simplify nested if equations
2431 ✗ (elseenqs1,asserts,_) := List.fold31(listReverse(eqns), simplifyIfEquationsFinder, globalKnownVars, {},{},false);
2432 ✗ elseenqs1 := listAppend(elseenqs1,asserts) annotation(__OpenModelica_DisableListAppendWarning=true);
2433 ✗ (eqnslst,elseenqs1,asserts) := simplifyIfEquationAsserts(explst,eqnslst,elseenqs1,{},{},{});
2434 ✗ eqns := simplifyIfEquation1(explst,eqnslst,elseenqs1,source,globalKnownVars,inEqns,inEqAttr);
2435 ✗ then
2436 (eqns,asserts);
2437 // if false skip it
2438 case(DAE.BCONST(false)::explst, _::eqnslst, _, _)
2439 algorithm
2440 441 (eqns,asserts) := simplifyIfEquation(explst,eqnslst,elseenqs,conditions1,theneqns1,source,globalKnownVars,inEqns,inEqAttr);
2441 then
2442 (eqns,asserts);
2443 // all other cases
2444 case(e::explst, eqns::eqnslst, _, _)
2445 algorithm
2446 // simplify nested if equations
2447 441 (eqns,asserts,_) := List.fold31(listReverse(eqns), simplifyIfEquationsFinder, globalKnownVars, {},{},false);
2448 441 eqns := listAppend(eqns,asserts) annotation(__OpenModelica_DisableListAppendWarning=true);
2449 441 (eqns,asserts) := simplifyIfEquation(explst,eqnslst,elseenqs,e::conditions1,eqns::theneqns1,source,globalKnownVars,inEqns,inEqAttr);
2450 then
2451 (eqns,asserts);
2452 end match;
2453 end simplifyIfEquation;
2454
2455 protected function simplifyIfEquation1
2456 "author: Frenkel TUD 2012-07
2457 helper for simplifyIfEquations"
2458 input list<DAE.Exp> conditions;
2459 input list<list<BackendDAE.Equation>> theneqns;
2460 input list<BackendDAE.Equation> elseenqs;
2461 input DAE.ElementSource source;
2462 input BackendDAE.Variables globalKnownVars;
2463 input list<BackendDAE.Equation> inEqns;
2464 input BackendDAE.EquationAttributes inEqAttr;
2465 output list<BackendDAE.Equation> outEqns;
2466 algorithm
2467 outEqns := matchcontinue inEqAttr
2468 local
2469 list<DAE.Exp> fbsExp;
2470 list<list<DAE.Exp>> tbsExp;
2471 list<BackendDAE.Equation> eqns;
2472 HashTable2.HashTable ht;
2473 list<tuple<DAE.ComponentRef,DAE.Exp>> crexplst;
2474
2475 // true case left with condition<>false
2476 case _
2477 algorithm
2478 166 countEquationsInBranches(theneqns,elseenqs,source);
2479 // simplify if eqution
2480 // if .. then a=.. elseif .. then a=... else a=.. end if;
2481 // to
2482 // a=if .. then .. else if .. then else ..;
2483 166 ht := HashTable2.emptyHashTable();
2484 166 ht := simplifySolvedIfEqnsElse(elseenqs,ht);
2485 157 ht := simplifySolvedIfEqns(listReverse(conditions),listReverse(theneqns),ht);
2486 127 crexplst := BaseHashTable.hashTableList(ht);
2487 127 eqns := simplifySolvedIfEqns2(crexplst, inEqns, inEqAttr);
2488 // ToDo: check if the same cref is not used more than once on the lhs, merge sources
2489 then
2490 eqns;
2491 case _
2492 algorithm
2493 39 countEquationsInBranches(theneqns,elseenqs,source);
2494 39 fbsExp := makeEquationLstToResidualExpLst(elseenqs);
2495 39 tbsExp := List.map(theneqns, makeEquationLstToResidualExpLst);
2496 39 eqns := makeEquationsFromResiduals(conditions, tbsExp, fbsExp, source, inEqAttr);
2497 39 then
2498 listAppend(eqns,inEqns);
2499
2500 ✗ else BackendDAE.IF_EQUATION(conditions,theneqns,elseenqs,source,inEqAttr)::inEqns;
2501 end matchcontinue;
2502 end simplifyIfEquation1;
2503
2504 protected function simplifySolvedIfEqns2
2505 input list<tuple<DAE.ComponentRef,DAE.Exp>> crexplst;
2506 input list<BackendDAE.Equation> inEqns;
2507 input BackendDAE.EquationAttributes inEqAttr;
2508 output list<BackendDAE.Equation> outEqns;
2509 algorithm
2510 outEqns := match crexplst
2511 local
2512 DAE.ComponentRef cr;
2513 DAE.Exp e,crexp;
2514 list<tuple<DAE.ComponentRef,DAE.Exp>> rest;
2515
2516 case {}
2517 then inEqns;
2518
2519 case (cr,e)::rest
2520 algorithm
2521 379 crexp := Expression.crefExp(cr);
2522 758 then
2523 simplifySolvedIfEqns2(rest, BackendDAE.EQUATION(crexp, e, DAE.emptyElementSource, inEqAttr)::inEqns, inEqAttr);
2524 end match;
2525 end simplifySolvedIfEqns2;
2526
2527 protected function simplifySolvedIfEqns
2528 "author: Frenkel TUD 2012-10
2529 helper for simplifyIfEquations"
2530 input list<DAE.Exp> conditions;
2531 input list<list<BackendDAE.Equation>> theneqns;
2532 input HashTable2.HashTable iHt;
2533 output HashTable2.HashTable oHt;
2534 algorithm
2535 oHt := match(conditions, theneqns)
2536 local
2537 HashTable2.HashTable ht;
2538 DAE.Exp c;
2539 list<DAE.Exp> explst;
2540 list<BackendDAE.Equation> eqns;
2541 list<list<BackendDAE.Equation>> rest;
2542 case ({}, {})
2543 then
2544 iHt;
2545 case (c::explst, eqns::rest)
2546 algorithm
2547 416 ht := simplifySolvedIfEqns1(c,eqns,iHt, HashSet.emptyHashSet());
2548 386 then
2549 simplifySolvedIfEqns(explst,rest,ht);
2550 end match;
2551 end simplifySolvedIfEqns;
2552
2553 protected function simplifySolvedIfEqns1
2554 "author: Frenkel TUD 2012-10
2555 helper for simplifyIfEquations"
2556 input DAE.Exp condition;
2557 input list<BackendDAE.Equation> brancheqns;
2558 input HashTable2.HashTable iHt;
2559 input HashSet.HashSet iHs;
2560 output HashTable2.HashTable oHt;
2561 algorithm
2562 // ticket #13927
2563 // Only proceed if `cr` was not already assigned within current branch.
2564 // This is checked by collecting all `cr` in `hs`.
2565 // Prevents errors like:
2566 // if b then a = r1; a = r2; else a = r3; c = r4; end if;
2567 // to
2568 // a = if b then r2 else if b then r1 else r3; c = r4;
2569
2570 oHt := match brancheqns
2571 local
2572 DAE.ComponentRef cr;
2573 DAE.Exp e,exp;
2574 HashTable2.HashTable ht;
2575 HashSet.HashSet hs;
2576 list<BackendDAE.Equation> rest;
2577 case {}
2578 then
2579 iHt;
2580 case BackendDAE.EQUATION(exp=DAE.CREF(componentRef=cr), scalar=e)::rest
2581 algorithm
2582
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1285 times.
1285 false := Expression.expHasCref(e, cr);
2583 1285 hs := BaseHashSet.addUnique(cr, iHs);
2584 1285 exp := BaseHashTable.get(cr, iHt);
2585 1259 exp := DAE.IFEXP(condition, e, exp);
2586 1259 ht := BaseHashTable.add((cr,exp), iHt);
2587 1259 then
2588 simplifySolvedIfEqns1(condition,rest,ht, hs);
2589 case BackendDAE.EQUATION(exp=DAE.UNARY(operator=DAE.UMINUS(), exp=DAE.CREF(componentRef=cr)), scalar=e)::rest
2590 algorithm
2591 ✗ false := Expression.expHasCref(e, cr);
2592 ✗ hs := BaseHashSet.addUnique(cr, iHs);
2593 ✗ exp := BaseHashTable.get(cr, iHt);
2594 ✗ e := Expression.negate(e);
2595 ✗ exp := DAE.IFEXP(condition, e, exp);
2596 ✗ ht := BaseHashTable.add((cr,exp), iHt);
2597 ✗ then
2598 simplifySolvedIfEqns1(condition,rest,ht, hs);
2599 end match;
2600 end simplifySolvedIfEqns1;
2601
2602 protected function simplifySolvedIfEqnsElse
2603 "author: Frenkel TUD 2012-10
2604 helper for simplifyIfEquations"
2605 input list<BackendDAE.Equation> elseenqs;
2606 input HashTable2.HashTable iHt;
2607 output HashTable2.HashTable oHt;
2608 algorithm
2609 oHt := match elseenqs
2610 local
2611 DAE.ComponentRef cr;
2612 DAE.Exp e;
2613 HashTable2.HashTable ht;
2614 list<BackendDAE.Equation> rest;
2615 case {}
2616 then
2617 iHt;
2618 case BackendDAE.EQUATION(exp=DAE.CREF(componentRef=cr), scalar=e)::rest guard not BaseHashTable.hasKey(cr, iHt)
2619 algorithm
2620
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 426 times.
426 false := Expression.expHasCref(e, cr);
2621 426 ht := BaseHashTable.add((cr,e), iHt);
2622 426 then
2623 simplifySolvedIfEqnsElse(rest,ht);
2624 case BackendDAE.EQUATION(exp=DAE.UNARY(operator=DAE.UMINUS(), exp=DAE.CREF(componentRef=cr)), scalar=e)::rest guard not BaseHashTable.hasKey(cr, iHt)
2625 algorithm
2626 ✗ false := Expression.expHasCref(e, cr);
2627 ✗ e := Expression.negate(e);
2628 ✗ ht := BaseHashTable.add((cr,e), iHt);
2629 ✗ then
2630 simplifySolvedIfEqnsElse(rest,ht);
2631 end match;
2632 end simplifySolvedIfEqnsElse;
2633
2634 protected function simplifyIfEquationAsserts
2635 "author: Frenkel TUD 2012-07
2636 helper for simplifyIfEquations"
2637 input list<DAE.Exp> conditions;
2638 input list<list<BackendDAE.Equation>> theneqns;
2639 input list<BackendDAE.Equation> elseenqs;
2640 input list<DAE.Exp> conditions1;
2641 input list<list<BackendDAE.Equation>> theneqns1;
2642 input list<BackendDAE.Equation> inEqns;
2643 output list<list<BackendDAE.Equation>> otheneqns;
2644 output list<BackendDAE.Equation> oelseenqs;
2645 output list<BackendDAE.Equation> outEqns;
2646 algorithm
2647 (otheneqns,oelseenqs,outEqns) := match(conditions, theneqns)
2648 local
2649 DAE.Exp e;
2650 list<DAE.Exp> explst;
2651 list<BackendDAE.Equation> eqns,eqns1,beqns;
2652 list<list<BackendDAE.Equation>> eqnslst,eqnslst1;
2653
2654 case (_, {})
2655 algorithm
2656 166 (beqns,eqns) := simplifyIfEquationAsserts1(elseenqs,NONE(),conditions1,{},inEqns);
2657
1/2
✓ Branch 1 taken 166 times.
✗ Branch 2 not taken.
166 then
2658 (listReverse(theneqns1),beqns,eqns);
2659 case (e::explst, eqns::eqnslst)
2660 algorithm
2661 441 (beqns,eqns) := simplifyIfEquationAsserts1(eqns,SOME(e),conditions1,{},inEqns);
2662 441 (eqnslst1,eqns1,eqns) := simplifyIfEquationAsserts(explst,eqnslst,elseenqs,e::conditions1,beqns::theneqns1,eqns);
2663 then
2664 (eqnslst1,eqns1,eqns);
2665 end match;
2666 end simplifyIfEquationAsserts;
2667
2668 protected function simplifyIfEquationAsserts1
2669 "author: Frenkel TUD 2012-07
2670 helper for simplifyIfEquationAsserts"
2671 input list<BackendDAE.Equation> brancheqns;
2672 input Option<DAE.Exp> condition;
2673 input list<DAE.Exp> conditions "reversed";
2674 input list<BackendDAE.Equation> brancheqns1;
2675 input list<BackendDAE.Equation> inEqns;
2676 output list<BackendDAE.Equation> obrancheqns;
2677 output list<BackendDAE.Equation> outEqns;
2678 algorithm
2679 (obrancheqns,outEqns) := match(brancheqns, condition)
2680 local
2681 DAE.Exp e,cond,msg,level;
2682 BackendDAE.Equation eqn;
2683 list<BackendDAE.Equation> eqns,beqns;
2684 Integer size;
2685 DAE.ElementSource source,source1;
2686 DAE.Expand crefExpand;
2687 BackendDAE.EquationAttributes eqAttr;
2688
2689 case ({}, _)
2690 607 then
2691 (listReverse(brancheqns1),inEqns);
2692
2693 case (BackendDAE.ALGORITHM(size=size,alg=DAE.ALGORITHM_STMTS({DAE.STMT_ASSERT(cond=cond,msg=msg,level=level,source=source1)}),source=source,expand=crefExpand,attr=eqAttr)::eqns, NONE())
2694 algorithm
2695 ✗ e := List.fold(conditions,makeIfExp,cond);
2696 ✗ (beqns,eqns) := simplifyIfEquationAsserts1(eqns,condition,conditions,brancheqns1,BackendDAE.ALGORITHM(size,DAE.ALGORITHM_STMTS({DAE.STMT_ASSERT(e,msg,level,source1)}),source,crefExpand,eqAttr)::inEqns);
2697 then
2698 (beqns,eqns);
2699
2700 case (BackendDAE.ALGORITHM(size=size,alg=DAE.ALGORITHM_STMTS({DAE.STMT_ASSERT(cond=cond,msg=msg,level=level,source=source1)}),source=source,expand=crefExpand,attr=eqAttr)::eqns, SOME(e))
2701 algorithm
2702 2 e := DAE.IFEXP(e,cond,DAE.BCONST(true));
2703 2 e := List.fold(conditions,makeIfExp,e);
2704 6 (beqns,eqns) := simplifyIfEquationAsserts1(eqns,condition,conditions,brancheqns1,BackendDAE.ALGORITHM(size,DAE.ALGORITHM_STMTS({DAE.STMT_ASSERT(e,msg,level,source1)}),source,crefExpand,eqAttr)::inEqns);
2705 then
2706 (beqns,eqns);
2707
2708 case (BackendDAE.ALGORITHM(size=size,alg=DAE.ALGORITHM_STMTS({DAE.STMT_TERMINATE(msg=msg,source=source1)}),source=source,expand=crefExpand,attr=eqAttr)::eqns, NONE())
2709 algorithm
2710 ✗ e := List.fold(conditions,makeIfExp,DAE.BCONST(true));
2711 ✗ (beqns,eqns) := simplifyIfEquationAsserts1(eqns,condition,conditions,brancheqns1,BackendDAE.ALGORITHM(size,DAE.ALGORITHM_STMTS({DAE.STMT_IF(e,{DAE.STMT_TERMINATE(msg,source1)},DAE.NOELSE(),source1)}),source,crefExpand,eqAttr)::inEqns);
2712 then
2713 (beqns,eqns);
2714
2715 case (BackendDAE.ALGORITHM(size=size,alg=DAE.ALGORITHM_STMTS({DAE.STMT_TERMINATE(msg=msg,source=source1)}),source=source,expand=crefExpand,attr=eqAttr)::eqns, SOME(e))
2716 algorithm
2717 1 e := List.fold(conditions,makeIfExp,e);
2718 4 (beqns,eqns) := simplifyIfEquationAsserts1(eqns,condition,conditions,brancheqns1,BackendDAE.ALGORITHM(size,DAE.ALGORITHM_STMTS({DAE.STMT_IF(e,{DAE.STMT_TERMINATE(msg,source1)},DAE.NOELSE(),source1)}),source,crefExpand,eqAttr)::inEqns);
2719 then
2720 (beqns,eqns);
2721
2722 case (eqn::eqns, _)
2723 algorithm
2724 1770 (beqns,eqns) := simplifyIfEquationAsserts1(eqns,condition,conditions,eqn::brancheqns1,inEqns);
2725 then
2726 (beqns,eqns);
2727 end match;
2728 end simplifyIfEquationAsserts1;
2729
2730 protected function makeIfExp
2731 input DAE.Exp cond;
2732 input DAE.Exp else_;
2733 output DAE.Exp oExp;
2734 algorithm
2735 ✗ oExp := DAE.IFEXP(cond,DAE.BCONST(true),else_);
2736 end makeIfExp;
2737
2738 protected function countEquationsInBranches "
2739 Checks that the number of equations is the same in all branches
2740 of an if-equation"
2741 input list<list<BackendDAE.Equation>> trueBranches;
2742 input list<BackendDAE.Equation> falseBranch;
2743 input DAE.ElementSource source;
2744 output Integer nrOfEquations;
2745 algorithm
2746 nrOfEquations := matchcontinue falseBranch
2747 local
2748 list<Boolean> b;
2749 list<String> strs;
2750 String str,eqstr;
2751 list<Integer> nrOfEquationsBranches;
2752
2753 case _
2754 algorithm
2755 205 nrOfEquations := BackendEquation.equationLstSize(falseBranch);
2756 205 nrOfEquationsBranches := List.map(trueBranches, BackendEquation.equationLstSize);
2757 205 b := List.map1(nrOfEquationsBranches, intEq, nrOfEquations);
2758
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 205 times.
205 true := List.reduce(b,boolAnd);
2759 then
2760 nrOfEquations;
2761
2762 // An if-equation with non-parameter conditions must have an else-clause.
2763 case {}
2764 algorithm
2765 ✗ Error.addSourceMessage(Error.IF_EQUATION_MISSING_ELSE, {},
2766 ElementSource.getElementSourceFileInfo(source));
2767 ✗ then
2768 fail();
2769
2770 // If if-equation with non-parameter conditions must have the same number of
2771 // equations in each branch.
2772 case _ :: _
2773 algorithm
2774 ✗ nrOfEquations := BackendEquation.equationLstSize(falseBranch);
2775 ✗ nrOfEquationsBranches := List.map(trueBranches, BackendEquation.equationLstSize);
2776 ✗ eqstr := stringDelimitList(List.map(listAppend(trueBranches,{falseBranch}),BackendDump.dumpEqnsStr),"\n");
2777 ✗ strs := List.map(nrOfEquationsBranches, intString);
2778 ✗ str := stringDelimitList(strs,",");
2779 ✗ str := "{" + str + "," + intString(nrOfEquations) + "}";
2780 ✗ Error.addSourceMessage(Error.IF_EQUATION_UNBALANCED_2,{str,eqstr},ElementSource.getElementSourceFileInfo(source));
2781 ✗ then
2782 fail();
2783
2784 end matchcontinue;
2785 end countEquationsInBranches;
2786
2787 protected function makeEquationLstToResidualExpLst
2788 input list<BackendDAE.Equation> eqLst;
2789 output list<DAE.Exp> oExpLst;
2790 algorithm
2791 oExpLst := matchcontinue eqLst
2792 local
2793 list<BackendDAE.Equation> rest;
2794 list<DAE.Exp> exps1,exps2,exps;
2795 BackendDAE.Equation eq;
2796 DAE.ElementSource source;
2797 String str;
2798 case {} then {};
2799 case (eq as BackendDAE.ALGORITHM(source = source))::rest
2800 algorithm
2801 ✗ str := BackendDump.equationString(eq);
2802 ✗ str := Util.stringReplaceChar(str,"\n","");
2803 ✗ Error.addSourceMessage(Error.IF_EQUATION_WARNING,{str},ElementSource.getElementSourceFileInfo(source));
2804 ✗ exps := makeEquationLstToResidualExpLst(rest);
2805 then exps;
2806 case eq::rest
2807 algorithm
2808 148 exps1 := makeEquationToResidualExpLst(eq);
2809 148 exps2 := makeEquationLstToResidualExpLst(rest);
2810 148 exps := listAppend(exps1,exps2);
2811 then
2812 exps;
2813 end matchcontinue;
2814 end makeEquationLstToResidualExpLst;
2815
2816 protected function makeEquationToResidualExpLst "
2817 If-equations with more than 1 equation in each branch cannot be transformed
2818 to a single equation with residual if-expression. This function translates such
2819 equations to a list of residual if-expressions. Normal equations are translated
2820 to a list with a single residual expression."
2821 input BackendDAE.Equation eq;
2822 output list<DAE.Exp> oExpLst;
2823 algorithm
2824 oExpLst := matchcontinue eq
2825 local
2826 list<list<BackendDAE.Equation>> tbs;
2827 list<BackendDAE.Equation> fbs;
2828 list<DAE.Exp> conds, fbsExp,exps;
2829 list<list<DAE.Exp>> tbsExp;
2830 BackendDAE.Equation elt;
2831 DAE.Exp exp;
2832
2833 case BackendDAE.IF_EQUATION(conditions=conds,eqnstrue=tbs,eqnsfalse=fbs)
2834 algorithm
2835 ✗ fbsExp := makeEquationLstToResidualExpLst(fbs);
2836 ✗ tbsExp := List.map(tbs, makeEquationLstToResidualExpLst);
2837 ✗ exps := makeResidualIfExpLst(conds,tbsExp,fbsExp);
2838 then
2839 exps;
2840 case elt
2841 algorithm
2842 148 exp:=makeEquationToResidualExp(elt);
2843 then
2844 {exp};
2845 end matchcontinue;
2846 end makeEquationToResidualExpLst;
2847
2848 protected function makeResidualIfExpLst
2849 input list<DAE.Exp> inExp1;
2850 input list<list<DAE.Exp>> inExpLst2;
2851 input list<DAE.Exp> inExpLst3;
2852 output list<DAE.Exp> outExpLst;
2853 algorithm
2854 outExpLst := match (inExp1,inExpLst2,inExpLst3)
2855 local
2856 list<list<DAE.Exp>> tbs,tbsRest;
2857 list<DAE.Exp> tbsFirst,fbs,rest_res;
2858 list<DAE.Exp> conds;
2859 DAE.Exp ifexp,fb;
2860
2861 case (_,tbs,{})
2862 algorithm
2863 ✗ true := List.all(tbs, listEmpty);
2864 then {};
2865
2866 case (conds,tbs,fb::fbs)
2867 algorithm
2868 ✗ tbsRest := List.map(tbs, listRest);
2869 ✗ rest_res := makeResidualIfExpLst(conds, tbsRest, fbs);
2870
2871 ✗ tbsFirst := List.map(tbs,listHead);
2872
2873 ✗ ifexp := Expression.makeNestedIf(conds,tbsFirst,fb);
2874 then
2875 (ifexp :: rest_res);
2876 end match;
2877 end makeResidualIfExpLst;
2878
2879 public function makeEquationToResidualExp ""
2880 input BackendDAE.Equation eq;
2881 output DAE.Exp oExp;
2882 algorithm
2883 oExp := matchcontinue eq
2884 local
2885 DAE.Exp e1,e2, e;
2886 list<DAE.Exp> expl, expl1;
2887 DAE.ComponentRef cr1;
2888 String str;
2889 DAE.Type ty;
2890 Integer idx;
2891 list<Integer> idxs;
2892 // normal equation
2893 case BackendDAE.EQUATION(exp=e1,scalar=e2)
2894 algorithm
2895 167 ty := Expression.typeof(e1);
2896
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 167 times.
167 true := Types.isIntegerOrRealOrSubTypeOfEither(ty);
2897 167 oExp := Expression.expSub(e1,e2);
2898 then
2899 oExp;
2900 // equation from array TODO! check if this works!
2901 case BackendDAE.ARRAY_EQUATION(left=e1,right=e2)
2902 algorithm
2903 ✗ oExp := Expression.expSub(e1,e2);
2904 then
2905 oExp;
2906 // solved equation
2907 case BackendDAE.SOLVED_EQUATION(componentRef=cr1, exp=e2)
2908 algorithm
2909 ✗ e1 := Expression.crefExp(cr1);
2910 ✗ oExp := Expression.expSub(e1,e2);
2911 then
2912 oExp;
2913 // residual equation
2914 case BackendDAE.RESIDUAL_EQUATION(exp = oExp)
2915 then
2916 oExp;
2917 // complex equation
2918 // (x,_) = f(.)
2919 case BackendDAE.COMPLEX_EQUATION(left = DAE.TUPLE(expl), right = e2)
2920 algorithm
2921 expl1 := {};
2922 idxs := {};
2923 idx := 1;
2924 ✗ for elem in expl loop
2925 ✗ if Expression.isNotWild(elem) then
2926 idxs := idx :: idxs;
2927 expl1 := elem :: expl1;
2928 end if;
2929 ✗ idx := idx + 1;
2930 end for;
2931 ✗ {e} := expl1;
2932 ✗ {idx} := idxs;
2933 ✗ oExp := Expression.expSub(e, DAE.TSUB(e2,idx,Expression.typeof(e)));
2934 //print("\n" + ExpressionDump.dumpExpStr(oExp,0));
2935 then oExp;
2936 case BackendDAE.COMPLEX_EQUATION(left = e1, right = e2)
2937 algorithm
2938 ✗ oExp := Expression.expSub(e1,e2);
2939 then
2940 oExp;
2941 // failure
2942 case _
2943 algorithm
2944 ✗ str := "- BackendDAEOptimize.makeEquationToResidualExp failed to transform equation: " + BackendDump.equationString(eq) + " to residual form!";
2945 ✗ Error.addMessage(Error.INTERNAL_ERROR, {str});
2946 ✗ then fail();
2947 end matchcontinue;
2948 end makeEquationToResidualExp;
2949
2950 protected function makeEquationsFromResiduals
2951 input list<DAE.Exp> inExp1 "conds";
2952 input list<list<DAE.Exp>> inExpLst2 "tbs";
2953 input list<DAE.Exp> inExpLst3;
2954 input DAE.ElementSource inSource "the origin of the element";
2955 input BackendDAE.EquationAttributes inEqAttr;
2956 output list<BackendDAE.Equation> outExpLst;
2957 algorithm
2958 outExpLst := match inExpLst3
2959 local
2960 list<list<DAE.Exp>> tbsRest;
2961 list<DAE.Exp> tbsFirst, fbs;
2962 DAE.Exp ifexp, fb;
2963 BackendDAE.Equation eq;
2964 list<BackendDAE.Equation> rest_res;
2965 DAE.Exp zeroExp;
2966 Integer size;
2967
2968 case {}
2969 algorithm
2970
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
39 true := List.all(inExpLst2, listEmpty);
2971 then {};
2972
2973 case fb::fbs
2974 algorithm
2975 58 size := Expression.sizeOf(Expression.typeof(fb));
2976 58 tbsRest := List.map(inExpLst2, listRest);
2977 58 rest_res := makeEquationsFromResiduals(inExp1, tbsRest, fbs, inSource, inEqAttr);
2978 58 tbsFirst := List.map(inExpLst2, listHead);
2979 58 ifexp := Expression.makeNestedIf(inExp1,tbsFirst,fb);
2980
1/2
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
58 if size==1 then
2981 58 eq := BackendDAE.EQUATION(DAE.RCONST(0.0), ifexp, inSource, inEqAttr);
2982 else
2983 ✗ zeroExp := Expression.createZeroExpression(Expression.typeof(fb));
2984 ✗ eq := BackendDAE.COMPLEX_EQUATION(size, zeroExp, ifexp, inSource, inEqAttr);
2985 end if;
2986
2987 then (eq::rest_res);
2988 end match;
2989 end makeEquationsFromResiduals;
2990
2991
2992 // =============================================================================
2993 // simplify semiLinear calls
2994 //
2995 // =============================================================================
2996
2997 public function simplifysemiLinear "author: Frenkel TUD 2012-08
2998 This function traveres all equations and tries to simplify calls to semiLinear"
2999 input BackendDAE.BackendDAE dae;
3000 output BackendDAE.BackendDAE odae;
3001 algorithm
3002 1070 odae := BackendDAEUtil.mapEqSystem(dae,simplifysemiLinearWork);
3003 end simplifysemiLinear;
3004
3005 protected function simplifysemiLinearWork "author: Frenkel TUD 2012-08
3006 This function traveres all equations and tries to simplify calls to semiLinear"
3007 input BackendDAE.EqSystem isyst;
3008 input BackendDAE.Shared ishared;
3009 output BackendDAE.EqSystem osyst;
3010 output BackendDAE.Shared oshared;
3011 algorithm
3012 (osyst,oshared) := matchcontinue isyst
3013 local
3014 BackendDAE.EquationArray eqns;
3015 list<tuple<BackendDAE.Equation,Integer>> eqnslst;
3016 BackendDAE.EqSystem syst;
3017 array<list<tuple<BackendDAE.Equation,Integer>>> eqnsarray;
3018 BackendDAE.EqSystem syst;
3019
3020 case syst as BackendDAE.EQSYSTEM(orderedEqs=eqns)
3021 algorithm
3022 // traverse the equations and collect all semiLinear calls y=semiLinear(x,sa,sb)
3023
2/2
✓ Branch 1 taken 1543 times.
✓ Branch 2 taken 19 times.
1562 (eqns, (eqnslst,_,true)) := BackendEquation.traverseEquationArray_WithUpdate(eqns,simplifysemiLinearFinder,({},0,false));
3024 // sort for (y,x) pairs
3025 19 eqnsarray := semiLinearSort(eqnslst, HashTableExpToIndex.emptyHashTable(), 1, arrayCreate(5, {}));
3026 19 eqnsarray := semiLinearSort1(arrayList(eqnsarray), 1, arrayCreate(5, {}));
3027 // optimize
3028 // y = semiLinear(x,sa,s1)
3029 // y = semiLinear(x,s1,s2)
3030 // y = semiLinear(x,s2,s3)
3031 // ...
3032 // y = semiLinear(x,sn,sb)
3033 // ->
3034 // s1 = if (x>=0) then sa else sb
3035 // s2 = s1
3036 // s3 = s2
3037 // ..
3038 // sn = sn-1
3039 // y = semiLinear(x,sa,sb)
3040 19 eqnslst := Array.fold(eqnsarray, semiLinearOptimize, {});
3041 // replace the equations in the system
3042 19 syst.orderedEqs := List.fold(eqnslst, semiLinearReplaceEqns, eqns);
3043 19 then (BackendDAEUtil.clearEqSyst(syst), ishared);
3044
3045 else
3046 then (isyst,ishared);
3047 end matchcontinue;
3048 end simplifysemiLinearWork;
3049
3050 protected function semiLinearReplaceEqns "author: Frenkel TUD 2012-08
3051 helper for simplifysemiLinear"
3052 input tuple<BackendDAE.Equation, Integer /*zero-based*/> iTpl;
3053 input BackendDAE.EquationArray iEqns;
3054 output BackendDAE.EquationArray oEqns;
3055 protected
3056 BackendDAE.Equation eqn;
3057 Integer index;
3058 algorithm
3059 39 (eqn, index) := iTpl;
3060
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
39 if Flags.isSet(Flags.SEMILINEAR) then
3061 ✗ BackendDump.debugStrEqnStr("Replace with ", eqn, "\n");
3062 end if;
3063 39 oEqns := BackendEquation.setAtIndex(iEqns, index+1, eqn);
3064 end semiLinearReplaceEqns;
3065
3066 protected function semiLinearOptimize
3067 "author: Frenkel TUD 2012-08
3068 helper for simplifysemiLinear"
3069 input list<tuple<BackendDAE.Equation,Integer>> eqnslst;
3070 input list<tuple<BackendDAE.Equation,Integer>> iAcc;
3071 output list<tuple<BackendDAE.Equation,Integer>> oAcc;
3072 algorithm
3073 oAcc := matchcontinue eqnslst
3074 local
3075 HashTableExpToIndex.HashTable ht,ht1;
3076 array<tuple<BackendDAE.Equation,Integer>> eqnsarray;
3077 list<DAE.Exp> explst;
3078 case _::{} then iAcc;
3079 case _
3080 algorithm
3081 // get HashMab sa-> index
3082 62 ht := HashTableExpToIndex.emptyHashTable();
3083 62 ht1 := HashTableExpToIndex.emptyHashTable();
3084 62 (ht,ht1) := semiLinearOptimize1(eqnslst,1,ht,ht1);
3085 // get sa
3086 62 explst := List.fold1(BaseHashTable.hashTableKeyList(ht),semiLinearGetSA,ht1,{});
3087 62 eqnsarray := listArray(eqnslst);
3088 // optimize
3089 62 then
3090 semiLinearOptimize2(explst,ht,eqnsarray,iAcc);
3091 case _ then iAcc;
3092 end matchcontinue;
3093 end semiLinearOptimize;
3094
3095 protected function semiLinearOptimize2
3096 "author: Frenkel TUD 2012-08
3097 helper for simplifysemiLinear"
3098 input list<DAE.Exp> saLst;
3099 input HashTableExpToIndex.HashTable iHt;
3100 input array<tuple<BackendDAE.Equation,Integer>> IEqnsarray;
3101 input list<tuple<BackendDAE.Equation,Integer>> iAcc;
3102 output list<tuple<BackendDAE.Equation,Integer>> oAcc;
3103 algorithm
3104 oAcc := matchcontinue saLst
3105 local
3106 DAE.Exp sa,sb,s1,y,x;
3107 list<DAE.Exp> rest;
3108 list<tuple<DAE.Exp,Integer,DAE.ElementSource>> explst;
3109 list<tuple<BackendDAE.Equation,Integer>> acc;
3110 BackendDAE.Equation eqn,eqn1;
3111 Integer i1,index,index1;
3112 Absyn.Path path;
3113 DAE.CallAttributes attr;
3114 DAE.ElementSource source,source1;
3115 BackendDAE.EquationAttributes eqAttr;
3116 case {} then iAcc;
3117 case sa::rest
3118 algorithm
3119 15 i1 := BaseHashTable.get(sa,iHt);
3120
6/12
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 15 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 15 times.
15 (BackendDAE.EQUATION(exp=y,scalar=DAE.CALL(path=path,expLst = {x,_,s1},attr=attr),source=source,attr=eqAttr),index) := IEqnsarray[i1];
3121 // get Order of s1,s2,s3,..,sn,sb
3122 15 (sb,source1,index1,explst) := semiLinearOptimize3(s1,source,index,iHt,IEqnsarray,{});
3123 // generate optimized equations
3124 // s1 = if (x>=0) then sa else sb
3125 // s2 = s1
3126 // ..
3127 // sn = sn-1
3128 // y = semiLinear(x,sa,sb)
3129 30 eqn := BackendDAE.EQUATION(s1,DAE.IFEXP(DAE.CALL(Absyn.IDENT("noEvent"),{DAE.RELATION(x,DAE.GREATEREQ(DAE.T_REAL_DEFAULT),DAE.RCONST(0.0),-1,NONE())},DAE.callAttrBuiltinBool),sa,sb),source,eqAttr);
3130 15 eqn1 := BackendDAE.EQUATION(y,DAE.CALL(path,{x,sa,sb},attr),source1,eqAttr);
3131 30 acc := semiLinearOptimize4(explst,(eqn1,index1)::iAcc, eqAttr);
3132 30 then
3133 semiLinearOptimize2(rest,iHt,IEqnsarray,(eqn,index)::acc);
3134 case _::rest
3135 ✗ then
3136 semiLinearOptimize2(rest,iHt,IEqnsarray,iAcc);
3137 end matchcontinue;
3138 end semiLinearOptimize2;
3139
3140 protected function semiLinearOptimize4
3141 "author: Frenkel TUD 2012-08
3142 helper for simplifysemiLinear"
3143 input list<tuple<DAE.Exp,Integer,DAE.ElementSource>> explst;
3144 input list<tuple<BackendDAE.Equation,Integer>> iAcc;
3145 input BackendDAE.EquationAttributes inEqAttr;
3146 output list<tuple<BackendDAE.Equation,Integer>> oAcc;
3147 algorithm
3148 oAcc := match explst
3149 local
3150 DAE.Exp s1,s2;
3151 list<tuple<DAE.Exp,Integer,DAE.ElementSource>> rest;
3152 Integer index;
3153 BackendDAE.Equation eqn;
3154 DAE.ElementSource source;
3155 case {} then iAcc;
3156 case _::{} then iAcc;
3157 case (s2,index,source)::(rest as ((s1,_,_)::_))
3158 algorithm
3159 9 eqn := BackendDAE.EQUATION(s2, s1, source, inEqAttr);
3160 18 then
3161 semiLinearOptimize4(rest, (eqn, index)::iAcc, inEqAttr);
3162 end match;
3163 end semiLinearOptimize4;
3164
3165 protected function semiLinearOptimize3
3166 "author: Frenkel TUD 2012-08
3167 helper for simplifysemiLinear"
3168 input DAE.Exp exp;
3169 input DAE.ElementSource isource;
3170 input Integer iIndex;
3171 input HashTableExpToIndex.HashTable iHt;
3172 input array<tuple<BackendDAE.Equation,Integer>> IEqnsarray;
3173 input list<tuple<DAE.Exp,Integer,DAE.ElementSource>> iAcc;
3174 output DAE.Exp slast;
3175 output DAE.ElementSource osource;
3176 output Integer oIndex;
3177 output list<tuple<DAE.Exp,Integer,DAE.ElementSource>> oAcc;
3178 algorithm
3179 (slast,osource,oIndex,oAcc) := matchcontinue iAcc
3180 local
3181 DAE.Exp sb;
3182 Integer i,index;
3183 DAE.ElementSource source;
3184 case _
3185 algorithm
3186 39 i := BaseHashTable.get(exp,iHt);
3187
6/12
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 24 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 24 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 24 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 24 times.
24 (BackendDAE.EQUATION(scalar=DAE.CALL(expLst = {_,_,sb}),source=source),index) := IEqnsarray[i];
3188 48 (sb,source,index,oAcc) := semiLinearOptimize3(sb,source,index,iHt,IEqnsarray,(exp,iIndex,source)::iAcc);
3189 then
3190 (sb,source,index,oAcc);
3191 case _
3192 15 then
3193 (exp,isource,iIndex,iAcc);
3194 end matchcontinue;
3195 end semiLinearOptimize3;
3196
3197 protected function semiLinearGetSA
3198 "author: Frenkel TUD 2012-08
3199 helper for simplifysemiLinear"
3200 input DAE.Exp key;
3201 input HashTableExpToIndex.HashTable iHt1;
3202 input list<DAE.Exp> iAcc;
3203 output list<DAE.Exp> oAcc;
3204 algorithm
3205
2/2
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 24 times.
39 oAcc := if BaseHashTable.hasKey(key, iHt1) then iAcc else key::iAcc;
3206 end semiLinearGetSA;
3207
3208 protected function semiLinearOptimize1
3209 "author: Frenkel TUD 2012-08
3210 helper for simplifysemiLinear"
3211 input list<tuple<BackendDAE.Equation,Integer>> eqnslst;
3212 input Integer i;
3213 input HashTableExpToIndex.HashTable iHt;
3214 input HashTableExpToIndex.HashTable iHt1;
3215 output HashTableExpToIndex.HashTable oHt;
3216 output HashTableExpToIndex.HashTable oHt1;
3217 algorithm
3218 (oHt,oHt1) := match eqnslst
3219 local
3220 list<tuple<BackendDAE.Equation,Integer>> rest;
3221 HashTableExpToIndex.HashTable ht,ht1;
3222 DAE.Exp sa,sb;
3223 case {} then (iHt,iHt1);
3224 case (BackendDAE.EQUATION(scalar=DAE.CALL(expLst = {_,sa,sb})),_)::rest
3225 algorithm
3226 39 ht := BaseHashTable.add((sa,i), iHt);
3227 39 ht1 := BaseHashTable.add((sb,i), iHt1);
3228 39 (ht,ht1) := semiLinearOptimize1(rest,i+1,ht,ht1);
3229 then
3230 (ht,ht1);
3231 end match;
3232 end semiLinearOptimize1;
3233
3234 protected function semiLinearSort "author: Frenkel TUD 2012-08
3235 helper for simplifysemiLinear"
3236 input list<tuple<BackendDAE.Equation,Integer>> eqnslst;
3237 input HashTableExpToIndex.HashTable iHt;
3238 input Integer size;
3239 input array<list<tuple<BackendDAE.Equation,Integer>>> iEqnsarray;
3240 output array<list<tuple<BackendDAE.Equation,Integer>>> oEqnsarray;
3241 algorithm
3242 oEqnsarray := matchcontinue eqnslst
3243 local
3244 BackendDAE.Equation eqn;
3245 Integer index,i;
3246 list<tuple<BackendDAE.Equation,Integer>> rest,eqns;
3247 HashTableExpToIndex.HashTable ht;
3248 DAE.Exp y;
3249 array<list<tuple<BackendDAE.Equation,Integer>>> eqnsarray;
3250 case {} then iEqnsarray;
3251 case (eqn as BackendDAE.EQUATION(exp=y),index)::rest
3252 algorithm
3253 367 i := BaseHashTable.get(y,iHt);
3254 24 eqns := iEqnsarray[i];
3255 48 eqnsarray := arrayUpdate(iEqnsarray,i,(eqn,index)::eqns);
3256 24 then
3257 semiLinearSort(rest,iHt,size,eqnsarray);
3258 case (eqn as BackendDAE.EQUATION(exp=y),index)::rest
3259 algorithm
3260 343 ht := BaseHashTable.add((y,size), iHt);
3261 // expand if necesarray
3262
2/2
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 284 times.
343 eqnsarray := if intGt(size,arrayLength(iEqnsarray)) then Array.expand(5, iEqnsarray, {}) else iEqnsarray;
3263 686 eqnsarray := arrayUpdate(eqnsarray,size,{(eqn,index)});
3264 343 then
3265 semiLinearSort(rest,ht,size+1,eqnsarray);
3266 end matchcontinue;
3267 end semiLinearSort;
3268
3269 protected function semiLinearSort1
3270 "author: Frenkel TUD 2012-08
3271 helper for simplifysemiLinear"
3272 input list<list<tuple<BackendDAE.Equation,Integer>>> eqnslstlst;
3273 input Integer size;
3274 input array<list<tuple<BackendDAE.Equation,Integer>>> iEqnsarray;
3275 output array<list<tuple<BackendDAE.Equation,Integer>>> oEqnsarray;
3276 algorithm
3277 oEqnsarray := match eqnslstlst
3278 local
3279 Integer size1;
3280 tuple<BackendDAE.Equation,Integer> tpl;
3281 list<tuple<BackendDAE.Equation,Integer>> eqns;
3282 list<list<tuple<BackendDAE.Equation,Integer>>> rest;
3283 HashTableExpToIndex.HashTable ht;
3284 array<list<tuple<BackendDAE.Equation,Integer>>> eqnsarray;
3285 case {} then iEqnsarray;
3286 case (tpl::{})::rest
3287 algorithm
3288 // expand if necesarray
3289
2/2
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 269 times.
328 eqnsarray := if intGt(size,arrayLength(iEqnsarray)) then Array.expand(5, iEqnsarray, {}) else iEqnsarray;
3290 328 eqnsarray := arrayUpdate(eqnsarray,size,{tpl});
3291 328 then
3292 semiLinearSort1(rest,size+1,eqnsarray);
3293 case eqns::rest
3294 algorithm
3295 62 ht := HashTableExpToIndex.emptyHashTable();
3296 62 (size1,eqnsarray) := semiLinearSort2(eqns,ht,size,iEqnsarray);
3297 62 then
3298 semiLinearSort1(rest,size1,eqnsarray);
3299 end match;
3300 end semiLinearSort1;
3301
3302 protected function semiLinearSort2
3303 "author: Frenkel TUD 2012-08
3304 helper for simplifysemiLinear"
3305 input list<tuple<BackendDAE.Equation,Integer>> eqnslst;
3306 input HashTableExpToIndex.HashTable iHt;
3307 input Integer size;
3308 input array<list<tuple<BackendDAE.Equation,Integer>>> iEqnsarray;
3309 output Integer osize;
3310 output array<list<tuple<BackendDAE.Equation,Integer>>> oEqnsarray;
3311 algorithm
3312 (osize,oEqnsarray) := matchcontinue eqnslst
3313 local
3314 BackendDAE.Equation eqn;
3315 Integer index,i;
3316 list<tuple<BackendDAE.Equation,Integer>> rest,eqns;
3317 HashTableExpToIndex.HashTable ht;
3318 DAE.Exp x;
3319 array<list<tuple<BackendDAE.Equation,Integer>>> eqnsarray;
3320 62 case {} then (size,iEqnsarray);
3321 case (eqn as BackendDAE.EQUATION(scalar=DAE.CALL(expLst = x::_)),index)::rest
3322 algorithm
3323 39 i := BaseHashTable.get(x,iHt);
3324 24 eqns := iEqnsarray[i];
3325 48 eqnsarray := arrayUpdate(iEqnsarray,i,(eqn,index)::eqns);
3326 24 (i,eqnsarray) := semiLinearSort2(rest,iHt,size,eqnsarray);
3327 then
3328 (i,eqnsarray);
3329 case (eqn as BackendDAE.EQUATION(scalar=DAE.CALL(expLst = x::_)),index)::rest
3330 algorithm
3331 15 ht := BaseHashTable.add((x,size), iHt);
3332 // expand if necesarray
3333
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 eqnsarray := if intGt(size,arrayLength(iEqnsarray)) then Array.expand(5, iEqnsarray, {}) else iEqnsarray;
3334 30 eqnsarray := arrayUpdate(eqnsarray,size,{(eqn,index)});
3335 15 (i,eqnsarray) := semiLinearSort2(rest,ht,size+1,eqnsarray);
3336 then
3337 (i,eqnsarray);
3338 end matchcontinue;
3339 end semiLinearSort2;
3340
3341 protected function simplifysemiLinearFinder
3342 "helper for simplifysemiLinear"
3343 input BackendDAE.Equation inEq;
3344 input tuple<list<tuple<BackendDAE.Equation,Integer>>,Integer,Boolean> inTpl;
3345 output BackendDAE.Equation outEq;
3346 output tuple<list<tuple<BackendDAE.Equation,Integer>>,Integer,Boolean> outTpl;
3347 algorithm
3348 (outEq,outTpl) := matchcontinue (inEq,inTpl)
3349 local
3350 BackendDAE.Equation eqn;
3351 list<tuple<BackendDAE.Equation,Integer>> eqnslst;
3352 Integer index;
3353 Boolean b;
3354 DAE.Exp x,y,sa,sb;
3355 DAE.ElementSource source;
3356 Absyn.Path path;
3357 DAE.CallAttributes attr;
3358 BackendDAE.EquationAttributes eqAttr;
3359
3360 // 0 = semiLinear(0,sa,sb) -> sa=sb
3361 case (BackendDAE.EQUATION(exp=y,scalar=DAE.CALL(path=Absyn.IDENT("semiLinear"),expLst={x,sa,sb}),source=source,attr=eqAttr),(eqnslst,index,_))
3362 algorithm
3363
1/2
✓ Branch 1 taken 367 times.
✗ Branch 2 not taken.
367 true := Expression.isZero(y);
3364 ✗ true := Expression.isZero(x);
3365 ✗ then (BackendDAE.EQUATION(sa,sb,source,eqAttr),(eqnslst,index+1,true));
3366 case (BackendDAE.EQUATION(exp=DAE.CALL(path=Absyn.IDENT("semiLinear"),expLst={x,sa,sb}),scalar=y,source=source,attr=eqAttr),(eqnslst,index,_))
3367 algorithm
3368 ✗ true := Expression.isZero(y);
3369 ✗ true := Expression.isZero(x);
3370 ✗ then (BackendDAE.EQUATION(sa,sb,source,eqAttr),(eqnslst,index+1,true));
3371 case (BackendDAE.EQUATION(exp=y,scalar=DAE.UNARY(exp=DAE.CALL(path=Absyn.IDENT("semiLinear"),expLst={x,sa,sb})),source=source,attr=eqAttr),(eqnslst,index,_))
3372 algorithm
3373 ✗ true := Expression.isZero(y);
3374 ✗ true := Expression.isZero(x);
3375 ✗ then (BackendDAE.EQUATION(sa,sb,source,eqAttr),(eqnslst,index+1,true));
3376 case (BackendDAE.EQUATION(exp=DAE.UNARY(exp=DAE.CALL(path=Absyn.IDENT("semiLinear"),expLst={x,sa,sb})),scalar=y,source=source,attr=eqAttr),(eqnslst,index,_))
3377 algorithm
3378 ✗ true := Expression.isZero(y);
3379 ✗ true := Expression.isZero(x);
3380 ✗ then (BackendDAE.EQUATION(sa,sb,source,eqAttr),(eqnslst,index+1,true));
3381 // y = -semiLinear(-x,sb,sa) -> y = semiLinear(x,sa,sb)
3382 case (BackendDAE.EQUATION(exp=y,scalar=DAE.UNARY(exp=DAE.CALL(path=path as Absyn.IDENT("semiLinear"),expLst={DAE.UNARY(exp=x),sb,sa},attr=attr)),source=source,attr=eqAttr),(eqnslst,index,_))
3383 algorithm
3384 ✗ eqn := BackendDAE.EQUATION(y,DAE.CALL(path,{x,sa,sb},attr),source,eqAttr);
3385 ✗ if Flags.isSet(Flags.SEMILINEAR) then
3386 ✗ BackendDump.debugStrEqnStr("Found semiLinear ",eqn,"\n");
3387 end if;
3388 ✗ then (eqn,((eqn,index)::eqnslst,index+1,true));
3389 case (BackendDAE.EQUATION(exp=DAE.UNARY(exp=DAE.CALL(path=path as Absyn.IDENT("semiLinear"),expLst={DAE.UNARY(exp=x),sb,sa},attr=attr)),scalar=y,source=source,attr=eqAttr),(eqnslst,index,_))
3390 algorithm
3391 ✗ eqn := BackendDAE.EQUATION(y,DAE.CALL(path,{x,sa,sb},attr),source,eqAttr);
3392 ✗ if Flags.isSet(Flags.SEMILINEAR) then
3393 ✗ BackendDump.debugStrEqnStr("Found semiLinear ",eqn,"\n");
3394 end if;
3395 ✗ then (eqn,((eqn,index)::eqnslst,index+1,true));
3396 // -y = semiLinear(-x,sb,sa) -> y = semiLinear(x,sa,sb)
3397 case (BackendDAE.EQUATION(exp=DAE.UNARY(exp=y),scalar=DAE.CALL(path = path as Absyn.IDENT("semiLinear"), expLst = {DAE.UNARY(exp=x),sb,sa},attr=attr),source=source,attr=eqAttr),(eqnslst,index,_))
3398 algorithm
3399 14 eqn := BackendDAE.EQUATION(y,DAE.CALL(path,{x,sa,sb},attr),source,eqAttr);
3400
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
14 if Flags.isSet(Flags.SEMILINEAR) then
3401 ✗ BackendDump.debugStrEqnStr("Found semiLinear ",eqn,"\n");
3402 end if;
3403 28 then (eqn,((eqn,index)::eqnslst,index+1,true));
3404 case (BackendDAE.EQUATION(exp=DAE.CALL(path = path as Absyn.IDENT("semiLinear"), expLst = {DAE.UNARY(exp=x),sb,sa},attr=attr),scalar=DAE.UNARY(exp=y),source=source,attr=eqAttr),(eqnslst,index,_))
3405 algorithm
3406 ✗ eqn := BackendDAE.EQUATION(y,DAE.CALL(path,{x,sa,sb},attr),source,eqAttr);
3407 ✗ if Flags.isSet(Flags.SEMILINEAR) then
3408 ✗ BackendDump.debugStrEqnStr("Found semiLinear ",eqn,"\n");
3409 end if;
3410 ✗ then (eqn,((eqn,index)::eqnslst,index+1,true));
3411 // y = semiLinear(-x,sb,sa) -> -y = semiLinear(x,sa,sb)
3412 case (BackendDAE.EQUATION(exp=y,scalar=DAE.CALL(path = path as Absyn.IDENT("semiLinear"), expLst = {DAE.UNARY(exp=x),sb,sa},attr=attr),source=source,attr=eqAttr),(eqnslst,index,_))
3413 algorithm
3414 8 y := Expression.negate(y);
3415 8 eqn := BackendDAE.EQUATION(y,DAE.CALL(path,{x,sa,sb},attr),source,eqAttr);
3416
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 if Flags.isSet(Flags.SEMILINEAR) then
3417 ✗ BackendDump.debugStrEqnStr("Found semiLinear ",eqn,"\n");
3418 end if;
3419 16 then (eqn,((eqn,index)::eqnslst,index+1,true));
3420 case (BackendDAE.EQUATION(exp=DAE.CALL(path = path as Absyn.IDENT("semiLinear"), expLst = {DAE.UNARY(exp=x),sb,sa},attr=attr),scalar=y,source=source,attr=eqAttr),(eqnslst,index,_))
3421 algorithm
3422 ✗ y := Expression.negate(y);
3423 ✗ eqn := BackendDAE.EQUATION(y,DAE.CALL(path,{x,sa,sb},attr),source,eqAttr);
3424 ✗ if Flags.isSet(Flags.SEMILINEAR) then
3425 ✗ BackendDump.debugStrEqnStr("Found semiLinear ",eqn,"\n");
3426 end if;
3427 ✗ then (eqn,((eqn,index)::eqnslst,index+1,true));
3428 // y = semiLinear(x,sa,sb)
3429 case (eqn as BackendDAE.EQUATION(scalar=DAE.CALL(path =Absyn.IDENT("semiLinear"))),(eqnslst,index,_))
3430 algorithm
3431
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 345 times.
345 if Flags.isSet(Flags.SEMILINEAR) then
3432 ✗ BackendDump.debugStrEqnStr("Found semiLinear ",eqn,"\n");
3433 end if;
3434 690 then (eqn,((eqn,index)::eqnslst,index+1,true));
3435 case (eqn as BackendDAE.EQUATION(exp=DAE.CALL(path =Absyn.IDENT("semiLinear"))),(eqnslst,index,_))
3436 algorithm
3437 ✗ if Flags.isSet(Flags.SEMILINEAR) then
3438 ✗ BackendDump.debugStrEqnStr("Found semiLinear ",eqn,"\n");
3439 end if;
3440 ✗ then (eqn,((eqn,index)::eqnslst,index+1,true));
3441 case (BackendDAE.EQUATION(exp=y,scalar=DAE.UNARY(exp= x as DAE.CALL(path = Absyn.IDENT("semiLinear"))),source=source,attr=eqAttr),(eqnslst,index,_))
3442 algorithm
3443 ✗ y := Expression.negate(y);
3444 ✗ eqn := BackendDAE.EQUATION(y,x,source,eqAttr);
3445 ✗ if Flags.isSet(Flags.SEMILINEAR) then
3446 ✗ BackendDump.debugStrEqnStr("Found semiLinear ",eqn,"\n");
3447 end if;
3448 ✗ then (eqn,((eqn,index)::eqnslst,index+1,true));
3449 case (BackendDAE.EQUATION(exp=DAE.UNARY(exp= x as DAE.CALL(path = Absyn.IDENT("semiLinear"))),scalar=y,source=source,attr=eqAttr),(eqnslst,index,_))
3450 algorithm
3451 ✗ y := Expression.negate(y);
3452 ✗ eqn := BackendDAE.EQUATION(y,x,source,eqAttr);
3453 ✗ if Flags.isSet(Flags.SEMILINEAR) then
3454 ✗ BackendDump.debugStrEqnStr("Found semiLinear ",eqn,"\n");
3455 end if;
3456 ✗ then (eqn,((eqn,index)::eqnslst,index+1,true));
3457
3458
2/2
✓ Branch 0 taken 50274 times.
✓ Branch 1 taken 7157 times.
107705 case (eqn,(eqnslst,index,b)) then (eqn,(eqnslst,index+1,b));
3459 end matchcontinue;
3460 end simplifysemiLinearFinder;
3461
3462 // =============================================================================
3463 // remove constants stuff
3464 //
3465 // =============================================================================
3466
3467 public function removeConstants "author: Frenkel TUD"
3468 input BackendDAE.BackendDAE inDAE;
3469 output BackendDAE.BackendDAE outDAE;
3470 algorithm
3471 outDAE := match inDAE
3472 local
3473 BackendDAE.Variables globalKnownVars;
3474 BackendVarTransform.VariableReplacements repl;
3475 BackendDAE.EqSystems systs;
3476 BackendDAE.Shared shared;
3477 list<BackendDAE.Equation> lsteqns;
3478 Boolean b;
3479 case BackendDAE.DAE(systs, shared as BackendDAE.SHARED(globalKnownVars=globalKnownVars))
3480 algorithm
3481 2824 repl := BackendVarTransform.emptyReplacements();
3482 2824 repl := BackendVariable.traverseBackendDAEVars(globalKnownVars, removeConstantsFinder, repl);
3483
3484 2824 (globalKnownVars, (repl, _)) := BackendVariable.traverseBackendDAEVarsWithUpdate(globalKnownVars, replaceFinalVarTraverser, (repl, 0));
3485
3486
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2824 times.
2824 if Flags.isSet(Flags.DUMP_CONST_REPL) then
3487 ✗ BackendVarTransform.dumpReplacements(repl);
3488 end if;
3489
3490 2824 lsteqns := BackendEquation.equationList(shared.initialEqs);
3491 2824 (lsteqns, b) := BackendVarTransform.replaceEquations(lsteqns, repl, NONE());
3492
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2824 times.
2824 shared.initialEqs := if b then BackendEquation.listEquation(lsteqns) else shared.initialEqs;
3493
3494 2824 lsteqns := BackendEquation.equationList(shared.removedEqs);
3495 2824 (lsteqns, b) := BackendVarTransform.replaceEquations(lsteqns, repl, NONE());
3496
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2824 times.
2824 shared.removedEqs := if b then BackendEquation.listEquation(lsteqns) else shared.removedEqs;
3497
3498
3499 2824 systs := List.map1(systs, removeConstantsWork, repl);
3500
3501 2824 then BackendDAE.DAE(systs, shared);
3502 end match;
3503 end removeConstants;
3504
3505 protected function removeConstantsWork "author: Frenkel TUD"
3506 input BackendDAE.EqSystem inEqSystem;
3507 input BackendVarTransform.VariableReplacements repl;
3508 output BackendDAE.EqSystem outEqSystem;
3509 algorithm
3510 outEqSystem := match inEqSystem
3511 local
3512 BackendDAE.Variables vars;
3513 list<BackendDAE.Equation> lsteqns;
3514 Boolean b;
3515 BackendDAE.EqSystem syst;
3516 case syst as BackendDAE.EQSYSTEM(orderedVars=vars)
3517 algorithm
3518 5692 BackendVariable.traverseBackendDAEVarsWithUpdate(vars, replaceFinalVarTraverser, (repl, 0));
3519
3520 5692 (lsteqns, b) := BackendVarTransform.replaceEquations(BackendEquation.equationList(syst.orderedEqs), repl, NONE());
3521
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5692 times.
5692 if b then
3522 ✗ syst.orderedEqs := BackendEquation.listEquation(lsteqns);
3523 ✗ syst := BackendDAEUtil.clearEqSyst(syst);
3524 end if;
3525
3526 5692 (lsteqns, b) := BackendVarTransform.replaceEquations(BackendEquation.equationList(syst.removedEqs), repl, NONE());
3527
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5692 times.
5692 if b then
3528 ✗ syst.removedEqs := BackendEquation.listEquation(lsteqns);
3529 end if;
3530
3531 then syst;
3532 end match;
3533 end removeConstantsWork;
3534
3535 protected function removeConstantsFinder
3536 input BackendDAE.Var inVar;
3537 input BackendVarTransform.VariableReplacements inRepl;
3538 output BackendDAE.Var outVar;
3539 output BackendVarTransform.VariableReplacements outRepl;
3540 algorithm
3541 (outVar,outRepl) := matchcontinue (inVar,inRepl)
3542 local
3543 BackendDAE.Var v;
3544 BackendVarTransform.VariableReplacements repl, repl_1;
3545 DAE.ComponentRef varName;
3546 DAE.Exp exp;
3547
3548 case (v as BackendDAE.VAR(varName=varName, varKind=BackendDAE.CONST(), bindExp=SOME(exp)), repl)
3549 algorithm
3550 8092 repl_1 := BackendVarTransform.addReplacement(repl, varName, exp, NONE());
3551 then (v, repl_1);
3552
3553 else (inVar,inRepl);
3554 end matchcontinue;
3555 end removeConstantsFinder;
3556
3557
3558 // =============================================================================
3559 // reaplace edge and change with (b and not pre(b)) and (v <> pre(v))
3560 //
3561 // =============================================================================
3562
3563 public function replaceEdgeChange "author: Frenkel TUD 2012-11
3564 edge(b) = b and not pre(b)
3565 change(b) = v <> pre(v)"
3566 input BackendDAE.BackendDAE inDAE;
3567 output BackendDAE.BackendDAE outDAE;
3568 algorithm
3569 1074 (outDAE,_) := BackendDAEUtil.mapEqSystemAndFold(inDAE, replaceEdgeChange0, false);
3570 1074 outDAE := replaceEdgeChangeShared(outDAE);
3571 end replaceEdgeChange;
3572
3573 protected function replaceEdgeChange0 "author: Frenkel TUD 2012-11"
3574 input BackendDAE.EqSystem isyst;
3575 input BackendDAE.Shared inShared;
3576 input Boolean inChanged;
3577 output BackendDAE.EqSystem osyst;
3578 output BackendDAE.Shared outShared = inShared;
3579 output Boolean outChanged;
3580 algorithm
3581 (osyst, outChanged) := matchcontinue isyst
3582 local
3583 BackendDAE.EquationArray orderedEqs, removedEqs;
3584
3585 case BackendDAE.EQSYSTEM(orderedEqs=orderedEqs, removedEqs=removedEqs)
3586 algorithm
3587 18375 BackendDAEUtil.traverseBackendDAEExpsEqns(orderedEqs, traverserreplaceEdgeChange, false);
3588 18375 BackendDAEUtil.traverseBackendDAEExpsEqns(removedEqs, traverserreplaceEdgeChange, false);
3589 then (isyst, true);
3590
3591 else (isyst, inChanged);
3592 end matchcontinue;
3593 end replaceEdgeChange0;
3594
3595 protected function traverserreplaceEdgeChange "author: Frenkel TUD 2012-11"
3596 input DAE.Exp e;
3597 input Boolean b;
3598 output DAE.Exp oe;
3599 output Boolean ob;
3600 algorithm
3601
3/4
✓ Branch 0 taken 323654 times.
✓ Branch 1 taken 1645 times.
✓ Branch 3 taken 325299 times.
✗ Branch 4 not taken.
648953 (oe,ob) := Expression.traverseExpBottomUp(e,traverserExpreplaceEdgeChange,b);
3602 end traverserreplaceEdgeChange;
3603
3604 protected function traverserExpreplaceEdgeChange "author: Frenkel TUD 2012-11"
3605 input DAE.Exp inExp;
3606 input Boolean inB;
3607 output DAE.Exp outExp;
3608 output Boolean outB;
3609 algorithm
3610 (outExp,outB) := matchcontinue inExp
3611 local
3612 DAE.Exp e;
3613 DAE.Type ty;
3614
3615 // change(v) -> v <> pre(v)
3616 case DAE.CALL(path=Absyn.IDENT(name = "change"), expLst={e})
3617 algorithm
3618 48 ty := Expression.typeof(e);
3619 96 then (DAE.RELATION(e, DAE.NEQUAL(ty), DAE.CALL(Absyn.IDENT("pre"), {e}, DAE.CALL_ATTR(ty, false, true, false, false, DAE.NO_INLINE(), DAE.NO_TAIL(), DAE.NoReturn.RETURNS)), -1, NONE()), true);
3620
3621 // edge(b) = b and not pre(b)
3622 case DAE.CALL(path=Absyn.IDENT(name = "edge"), expLst={e})
3623 algorithm
3624 40 ty := Expression.typeof(e);
3625 80 then (DAE.LBINARY(e, DAE.AND(ty), DAE.LUNARY(DAE.NOT(ty), DAE.CALL(Absyn.IDENT("pre"), {e}, DAE.CALL_ATTR(ty, false, true, false, false, DAE.NO_INLINE(), DAE.NO_TAIL(), DAE.NoReturn.RETURNS)))), true);
3626
3627 else (inExp,inB);
3628 end matchcontinue;
3629 end traverserExpreplaceEdgeChange;
3630
3631 protected function replaceEdgeChangeShared "author: Frenkel TUD 2012-11"
3632 input BackendDAE.BackendDAE inDAE;
3633 output BackendDAE.BackendDAE outDAE;
3634 algorithm
3635 outDAE := match inDAE
3636 local
3637 BackendDAE.EquationArray remeqns;
3638 BackendDAE.EqSystems systs;
3639 BackendDAE.Shared shared;
3640 case BackendDAE.DAE(systs, shared as BackendDAE.SHARED(removedEqs=remeqns))
3641 algorithm
3642 1074 BackendDAEUtil.traverseBackendDAEExpsEqns(remeqns, traverserreplaceEdgeChange, false);
3643 1074 then BackendDAE.DAE(systs, shared);
3644 end match;
3645 end replaceEdgeChangeShared;
3646
3647
3648 // =============================================================================
3649 // section for preOptModule >>removeLocalKnownVars<<
3650 //
3651 // =============================================================================
3652
3653 public function removeLocalKnownVars "Looks for equations only depending on one variable and save them in localKnownVars."
3654 input BackendDAE.BackendDAE inDAE;
3655 output BackendDAE.BackendDAE outDAE;
3656 algorithm
3657 1 outDAE := BackendDAEUtil.mapEqSystem(inDAE, removeLocalKnownVars2);
3658 end removeLocalKnownVars;
3659
3660
3661 public function removeLocalKnownVars2
3662 input output BackendDAE.EqSystem syst;
3663 input output BackendDAE.Shared shared;
3664 protected
3665 BackendDAE.AdjacencyMatrix m;
3666 BackendDAE.Var potentialLocalKnownVar;
3667 BackendDAE.Equation potentialGlobalKnownEquation;
3668 BackendDAE.Variables orderedVars = syst.orderedVars;
3669 BackendDAE.EquationArray orderedEqs = syst.orderedEqs;
3670 DAE.Exp lhs;
3671 DAE.Exp rhs;
3672 DAE.Exp crefExp;
3673 DAE.Exp binding;
3674 list<Integer> localKnownVars={};
3675 list<Integer> localKnownEqns={};
3676 Integer eindex=0;
3677 Integer vindex;
3678 algorithm
3679 1 (_,m,_,_,_) := BackendDAEUtil.getAdjacencyMatrixScalar(syst, BackendDAE.NORMAL(),NONE(), BackendDAEUtil.isInitializationDAE(shared));
3680
3681 // Delete negative entries from adjacency matrix
3682 1 m := Array.map(m,Tearing.deleteNegativeEntries);
3683
3684
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 1 time.
7 for row in m loop
3685 5 eindex := eindex+1;
3686
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 3 times.
5 if listLength(row) == 1 then
3687
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
2 {vindex} := row;
3688 //print("Variable: " + intString(vindex) + "\n");
3689 //print("Equation: " + intString(eindex) + "\n\n");
3690
3691 2 potentialLocalKnownVar := BackendVariable.getVarAt(orderedVars,vindex);
3692 2 potentialGlobalKnownEquation := BackendEquation.get(orderedEqs,eindex);
3693
3694 try
3695
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 BackendDAE.EQUATION(exp = lhs, scalar = rhs) := potentialGlobalKnownEquation;
3696 2 crefExp := BackendVariable.varExp(potentialLocalKnownVar);
3697 2 (binding,_) := ExpressionSolve.solve(lhs,rhs,crefExp, NONE());
3698 2 potentialLocalKnownVar := BackendVariable.setBindExp(potentialLocalKnownVar, SOME(binding));
3699 2 localKnownVars := vindex::localKnownVars;
3700 2 localKnownEqns := eindex::localKnownEqns;
3701 2 shared.localKnownVars := BackendVariable.addVar(potentialLocalKnownVar, shared.localKnownVars);
3702 else
3703 end try;
3704 end if;
3705 end for;
3706 1 localKnownVars := List.sort(localKnownVars, intLt);
3707 1 localKnownEqns := listReverse(localKnownEqns);
3708
3709
3710
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 time.
3 for var in localKnownVars loop
3711 2 orderedVars := BackendVariable.removeVar(var, orderedVars);
3712 end for;
3713
3714
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 time.
3 for eqn in localKnownEqns loop
3715 2 orderedEqs := BackendEquation.delete(eqn, orderedEqs);
3716 end for;
3717
3718 // delete adjacency matrix
3719 1 syst.m := NONE();
3720 syst.mT := NONE();
3721 syst.matching := BackendDAE.NO_MATCHING();
3722
3723 // TODO: remove this
3724 syst.orderedVars := BackendVariable.listVar(BackendVariable.varList(orderedVars));
3725 syst.orderedEqs := orderedEqs;
3726 end removeLocalKnownVars2;
3727
3728
3729 // =============================================================================
3730 // section for postOptModule >>addInitialStmtsToAlgorithms<<
3731 //
3732 // Real a[3];
3733 // algorithm --> algorithm
3734 // a[1] := 1.0; a[1] := $START.a[1];
3735 // a[2] := $START.a[2];
3736 // a[3] := $START.a[3];
3737 // a[1] := 1.0;
3738 // =============================================================================
3739
3740 public function addInitialStmtsToAlgorithms "
3741 section are executed in the order of appearance. Whenever an algorithm section is invoked, all variables appearing
3742 on the left hand side of the assignment operator := are initialized (at least conceptually):
3743 - A non-discrete variable is initialized with its start value (i.e. the value of the start-attribute).
3744 - A discrete variable v is initialized with pre(v)."
3745 input BackendDAE.BackendDAE inDAE;
3746 input Boolean isInitialSystem;
3747 output BackendDAE.BackendDAE outDAE;
3748 algorithm
3749
2/2
✓ Branch 0 taken 1085 times.
✓ Branch 1 taken 1120 times.
3290 outDAE := BackendDAEUtil.mapEqSystem1(inDAE, addInitialStmtsToAlgorithms1, isInitialSystem);
3750 end addInitialStmtsToAlgorithms;
3751
3752 protected function addInitialStmtsToAlgorithms1 "Helper function to addInitialStmtsToAlgorithms."
3753 input BackendDAE.EqSystem syst;
3754 input Boolean isInitialSystem;
3755 input BackendDAE.Shared shared;
3756 output BackendDAE.EqSystem osyst = syst;
3757 output BackendDAE.Shared oshared = shared;
3758 protected
3759 BackendDAE.Variables ordvars;
3760 BackendDAE.EquationArray ordeqns;
3761 algorithm
3762 49146 BackendDAE.EQSYSTEM(orderedVars=ordvars, orderedEqs=ordeqns) := osyst;
3763
2/2
✓ Branch 0 taken 1583 times.
✓ Branch 1 taken 47563 times.
50729 BackendEquation.traverseEquationArray_WithUpdate(ordeqns, eaddInitialStmtsToAlgorithms1Helper, (ordvars, isInitialSystem));
3764 end addInitialStmtsToAlgorithms1;
3765
3766 protected function eaddInitialStmtsToAlgorithms1Helper "Helper function to addInitialStmtsToAlgorithms1."
3767 input BackendDAE.Equation inEq;
3768 input tuple<BackendDAE.Variables, Boolean> inTpl;
3769 output BackendDAE.Equation outEq;
3770 output tuple<BackendDAE.Variables, Boolean> outTpl = inTpl;
3771 algorithm
3772 outEq := match (inEq, inTpl)
3773 local
3774 DAE.Algorithm alg;
3775 list<DAE.Statement> statements;
3776 BackendDAE.Variables vars;
3777 Integer size;
3778 list<DAE.Exp> outputs;
3779 DAE.ElementSource source;
3780 list<DAE.ComponentRef> crlst;
3781 DAE.Expand crExpand;
3782 BackendDAE.EquationAttributes attr;
3783 Boolean isInitialEquations;
3784
3785 case (BackendDAE.ALGORITHM(size=size, alg=alg as DAE.ALGORITHM_STMTS(statements), source=source, expand=crExpand, attr=attr), (vars, isInitialEquations))
3786 algorithm
3787 512 crlst := CheckModel.checkAndGetAlgorithmOutputs(alg, source, crExpand);
3788 512 outputs := List.map(crlst, Expression.crefExp);
3789 512 statements := expandAlgorithmStmts(statements, outputs, vars, isInitialEquations);
3790 512 then BackendDAE.ALGORITHM(size, DAE.ALGORITHM_STMTS(statements), source, crExpand, attr);
3791
3792 else inEq;
3793 end match;
3794 end eaddInitialStmtsToAlgorithms1Helper;
3795
3796 public function expandAlgorithmStmts "Helper function to eaddInitialStmtsToAlgorithms1Helper."
3797 input list<DAE.Statement> inAlg;
3798 input list<DAE.Exp> inOutputs;
3799 input BackendDAE.Variables inVars;
3800 input Boolean isInitialEquation;
3801 output list<DAE.Statement> outAlg;
3802 algorithm
3803 outAlg := match(inAlg, inOutputs)
3804 local
3805 DAE.Exp out, initExp;
3806 list<DAE.Exp> rest;
3807 DAE.ComponentRef cref;
3808 list<BackendDAE.Var> vars;
3809 DAE.Statement stmt;
3810 DAE.Type type_;
3811 list<DAE.Statement> statements;
3812
3813 case(statements, {})
3814 then statements;
3815
3816 case(statements, out::rest) algorithm
3817 2203 cref := Expression.expCref(out);
3818 2203 (vars, _) := BackendVariable.getVar(cref, inVars);
3819
2/2
✓ Branch 0 taken 2203 times.
✓ Branch 1 taken 2203 times.
4406 for v in vars loop
3820 2203 type_ := v.varType;
3821
4/4
✓ Branch 1 taken 1822 times.
✓ Branch 2 taken 381 times.
✓ Branch 3 taken 1180 times.
✓ Branch 4 taken 642 times.
2203 if BackendVariable.isVarDiscrete(v) and not isInitialEquation then
3822 2360 initExp := Expression.makePureBuiltinCall("pre", {Expression.crefExp(v.varName)}, type_);
3823 else
3824 1023 initExp := Expression.crefExp(ComponentReference.crefPrefixStart(v.varName));
3825 end if;
3826 2203 stmt := Algorithm.makeAssignment(DAE.CREF(v.varName, type_), DAE.PROP(type_, DAE.C_VAR()), initExp, DAE.PROP(type_, DAE.C_VAR()), DAE.dummyAttrVar, SCode.NON_INITIAL(), DAE.emptyElementSource);
3827 statements := stmt::statements;
3828 end for;
3829 2203 then expandAlgorithmStmts(statements, rest, inVars, isInitialEquation);
3830 end match;
3831 end expandAlgorithmStmts;
3832
3833
3834 // =============================================================================
3835 // section for expandDerOperator
3836 //
3837 // =============================================================================
3838
3839 public function expandDerOperator "
3840 Expands der(expr) using Derive.differentiteExpTime.
3841 This can not be done in Static, since we need all time-
3842 dependent variables, which is only available in BackendDAE."
3843 input BackendDAE.BackendDAE inDAE;
3844 output BackendDAE.BackendDAE outDAE;
3845 algorithm
3846 1089 outDAE := BackendDAEUtil.mapEqSystem(inDAE, expandDerOperatorWork);
3847 end expandDerOperator;
3848
3849 protected function expandDerOperatorWork "
3850 expands der(expr) using Derive.differentiteExpTime.
3851 This can not be done in Static, since we need all time-
3852 dependent variables, which is only available in BackendDAE."
3853 input output BackendDAE.EqSystem syst;
3854 input output BackendDAE.Shared shared;
3855 algorithm
3856 (syst, shared) := match (syst, shared)
3857 local
3858 BackendDAE.Variables vars;
3859 BackendDAE.EquationArray eqns, inieqns, remeqns;
3860 Mutable<BackendDAE.Shared> shared_arr;
3861
3862 case (syst as BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns, removedEqs=remeqns), BackendDAE.SHARED(initialEqs=inieqns))
3863 algorithm
3864 1089 shared_arr := Mutable.create(shared);
3865 1089 (_, vars) := BackendEquation.traverseEquationArray_WithUpdate(eqns, function traverserexpandDerEquation(shared=shared_arr), vars);
3866 1089 (_, vars) := BackendEquation.traverseEquationArray_WithUpdate(inieqns, function traverserexpandDerEquation(shared=shared_arr), vars);
3867 // A side-effect-only when-equation is a removed equation, but its
3868 // condition is still evaluated.
3869 1089 (remeqns, vars) := BackendEquation.traverseEquationArray_WithUpdate(remeqns, function traverserexpandDerEquation(shared=shared_arr), vars);
3870 1089 syst.removedEqs := remeqns;
3871 1089 syst.orderedVars := vars;
3872 1089 then (syst, Mutable.access(shared_arr));
3873 end match;
3874 end expandDerOperatorWork;
3875
3876 protected function traverserexpandDerEquation "
3877 Help function to e.g. traverserexpandDerEquation"
3878 input output BackendDAE.Equation eq;
3879 input output BackendDAE.Variables vars;
3880 input Mutable<BackendDAE.Shared> shared;
3881 protected
3882 list<DAE.SymbolicOperation> ops;
3883 algorithm
3884 162718 (eq, (vars, ops)) := BackendEquation.traverseExpsOfEquation(eq, function traverserexpandDerExp(shared=shared), (vars, {}));
3885 162718 eq := List.foldr(ops, BackendEquation.addOperation, eq);
3886 end traverserexpandDerEquation;
3887
3888 protected function traverserexpandDerExp "
3889 Help function to e.g. traverserexpandDerExp"
3890 input output DAE.Exp exp;
3891 input output tuple<BackendDAE.Variables, list<DAE.SymbolicOperation>> tpl;
3892 input Mutable<BackendDAE.Shared> shared;
3893 protected
3894 DAE.Exp exp_1;
3895 BackendDAE.Variables vars1, vars2;
3896 list<DAE.SymbolicOperation> ops;
3897 algorithm
3898 330183 (vars1, ops) := tpl;
3899 330183 (exp_1, vars2) := Expression.traverseExpBottomUp(exp, function expandDerExp(inShared=shared), vars1);
3900
4/4
✓ Branch 0 taken 317571 times.
✓ Branch 1 taken 12612 times.
✓ Branch 2 taken 317569 times.
✓ Branch 3 taken 2 times.
330183 if not (referenceEq(vars1, vars2) and referenceEq(exp, exp_1)) then
3901 12614 ops := DAE.OP_DIFFERENTIATE(DAE.crefTime, exp, exp_1)::ops;
3902 exp := exp_1;
3903 12614 tpl := (vars2, ops);
3904 end if;
3905 end traverserexpandDerExp;
3906
3907 protected function expandDerExp "
3908 Help function to e.g. expandDerOperatorEqn"
3909 input output DAE.Exp exp;
3910 input output BackendDAE.Variables vars;
3911 input Mutable<BackendDAE.Shared> inShared;
3912 protected
3913 Boolean failed = false;
3914 algorithm
3915 () := match exp
3916 local
3917 DAE.ComponentRef cr;
3918 String str;
3919 case DAE.CALL(path=Absyn.IDENT(name = "der"), expLst={DAE.CALL(path=Absyn.IDENT(name = "der"), expLst={DAE.CREF(componentRef=cr)})})
3920 algorithm
3921 ✗ str := ComponentReference.crefStr(cr);
3922 ✗ str := stringAppendList({"The model includes derivatives of order > 1 for: ", str, ". That is not supported. Adding 'Real d", str, " = der(", str, ");' *might* result in a solvable model"});
3923 ✗ Error.addMessage(Error.INTERNAL_ERROR, {str});
3924 ✗ then fail();
3925 else ();
3926 end match;
3927 (exp,vars) := matchcontinue exp
3928 local
3929 DAE.Exp e1, e2;
3930 DAE.ComponentRef cr;
3931 list<BackendDAE.Var> varlst;
3932 BackendDAE.Var v;
3933 BackendDAE.Shared shared;
3934 // case for arrays
3935 case e1 as DAE.CALL(path=Absyn.IDENT(name = "der"), expLst={DAE.CREF(ty = DAE.T_ARRAY())})
3936 algorithm
3937
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 119 times.
119 (e2, true) := Expression.extendArrExp(e1, false);
3938 119 (exp,vars) := Expression.traverseExpBottomUp(e2, function expandDerExp(inShared=inShared), vars);
3939 then (exp,vars);
3940 // case for records
3941 case e1 as DAE.CALL(path=Absyn.IDENT(name = "der"), expLst={DAE.CREF(ty = DAE.T_COMPLEX(complexClassType=ClassInf.RECORD(_)))})
3942 algorithm
3943 ✗ (e2, true) := Expression.extendArrExp(e1, false);
3944 ✗ (exp,vars) := Expression.traverseExpBottomUp(e2, function expandDerExp(inShared=inShared), vars);
3945 then (exp,vars);
3946 case e1 as DAE.CALL(path=Absyn.IDENT(name = "der"), expLst={DAE.CREF(componentRef=cr)})
3947 algorithm
3948 13514 (v, _) := BackendVariable.getVarSingle(cr, vars);
3949 try
3950 13511 (vars, e1) := updateStatesVar(vars, v, e1);
3951 else
3952 failed := true;
3953 end try;
3954 13511 then (e1, vars);
3955 case e1 as DAE.CALL(path=Absyn.IDENT(name = "der"), expLst={DAE.CREF(componentRef=cr)})
3956 algorithm
3957 3 (varlst, _) := BackendVariable.getVar(cr, vars);
3958 ✗ vars := updateStatesVars(vars, varlst, false);
3959 ✗ then (e1, vars);
3960 case DAE.CALL(path=Absyn.IDENT(name = "der"), expLst={e1})
3961 algorithm
3962 127 (e2, shared) := Differentiate.differentiateExpTime(e1, vars, Mutable.access(inShared));
3963
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 124 times.
127 false := Expression.isZero(e2);
3964 124 Mutable.update(inShared, shared);
3965 124 (e2, _) := ExpressionSimplify.simplify(e2);
3966 124 (_, vars) := Expression.traverseExpBottomUp(e2, derCrefsExp, vars);
3967 124 then (e2, vars);
3968 1315047 else (exp,vars);
3969 end matchcontinue;
3970
3971 // FIXME dumb hack to make matchcontinue fail
3972 // I don't want to rewrite the damn thing
3973
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1328801 times.
1328801 if failed then
3974 ✗ fail();
3975 end if;
3976 end expandDerExp;
3977
3978 protected function derCrefsExp "helper for statesExp"
3979 input DAE.Exp inExp;
3980 input BackendDAE.Variables inVars;
3981 output DAE.Exp outExp;
3982 output BackendDAE.Variables outVars;
3983 algorithm
3984 (outExp,outVars) := matchcontinue (inExp,inVars)
3985 local
3986 DAE.ComponentRef cr;
3987 BackendDAE.Variables vars;
3988 list<BackendDAE.Var> varlst;
3989 BackendDAE.Var v;
3990 DAE.Exp e;
3991 case (e as DAE.CALL(path = Absyn.IDENT(name = "der"), expLst = {DAE.CREF(componentRef = cr)}), vars)
3992 algorithm
3993 404 (v, _) := BackendVariable.getVarSingle(cr, vars);
3994 404 (vars, e) := updateStatesVar(vars, v, e);
3995 404 then (e, vars);
3996 case (e as DAE.CALL(path = Absyn.IDENT(name = "der"), expLst = {DAE.CREF(componentRef = cr)}), vars)
3997 algorithm
3998 ✗ (varlst, _) := BackendVariable.getVar(cr, vars);
3999 ✗ vars := updateStatesVars(vars, varlst, false);
4000 ✗ then (e, vars);
4001 else (inExp,inVars);
4002 end matchcontinue;
4003 end derCrefsExp;
4004
4005 protected function updateStatesVar "
4006 Help function to expandDerExp"
4007 input BackendDAE.Variables inVars;
4008 input BackendDAE.Var var;
4009 input DAE.Exp iExp;
4010 output BackendDAE.Variables outVars = inVars;
4011 output DAE.Exp oExp = iExp;
4012 protected
4013 BackendDAE.Var var1;
4014 DAE.Exp arg;
4015 algorithm
4016
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13915 times.
13915 if BackendVariable.isVarNonDifferentiable(var) then
4017 ✗ DAE.CALL(expLst = {arg}) := iExp;
4018 ✗ Error.addSourceMessageAndFail(Error.DER_OF_NONDIFFERENTIABLE_EXP,
4019 {ExpressionBasics.printExpStr(arg)}, var.source.info);
4020 elseif BackendVariable.isVarDiscrete(var) then
4021 oExp := DAE.RCONST(0.0);
4022 elseif not BackendVariable.isStateVar(var) or BackendVariable.varStateSelectForced(var) then
4023 13053 var1 := BackendVariable.setVarKind(var, BackendDAE.STATE(1, NONE(), true));
4024 13053 outVars := BackendVariable.addVar(var1, inVars);
4025 oExp := iExp;
4026 else
4027 /* Might be part of a different equation-system...
4028 str = "BackendDAECreate.updateStatesVars failed for: " + ComponentReferenceBasics.printComponentRefStr(cr);
4029 Error.addMessage(Error.INTERNAL_ERROR, {str});
4030 */
4031 end if;
4032 end updateStatesVar;
4033
4034 protected function updateStatesVars "
4035 Help function to expandDerExp"
4036 input BackendDAE.Variables inVars;
4037 input list<BackendDAE.Var> inNewStates;
4038 input Boolean noStateFound;
4039 output BackendDAE.Variables outVars;
4040 algorithm
4041 outVars := matchcontinue(inNewStates, noStateFound)
4042 local
4043 BackendDAE.Var var;
4044 list<BackendDAE.Var> newStates;
4045 BackendDAE.Variables vars;
4046 //DAE.ComponentRef cr;
4047 //String str;
4048
4049 case({}, true) then inVars;
4050 case(var::newStates, _)
4051 algorithm
4052 ✗ false := BackendVariable.isVarDiscrete(var) "do not change discrete vars to states, because they have no derivative" ;
4053 ✗ false := BackendVariable.isStateVar(var);
4054 ✗ var := BackendVariable.setVarKind(var, BackendDAE.STATE(1,NONE(),true));
4055 ✗ vars := BackendVariable.addVar(var, inVars);
4056 ✗ vars := updateStatesVars(vars, newStates, true);
4057 then vars;
4058 case(_::newStates, _)
4059 algorithm
4060 /* Might be part of a different equation-system...
4061 str = "BackendDAECreate.updateStatesVars failed for: " + ComponentReferenceBasics.printComponentRefStr(cr);
4062 Error.addMessage(Error.INTERNAL_ERROR, {str});
4063 */
4064 ✗ vars := updateStatesVars(inVars, newStates, noStateFound);
4065 then vars;
4066 end matchcontinue;
4067 end updateStatesVars;
4068
4069 // =============================================================================
4070 // section for addedScaledVars
4071 //
4072 // =============================================================================
4073
4074 public function addedScaledVars_states
4075 "added var_norm = var/nominal, where var is state."
4076 input BackendDAE.BackendDAE inDAE;
4077 output BackendDAE.BackendDAE outDAE;
4078 protected
4079 list<BackendDAE.EqSystem> systlst;
4080 list<BackendDAE.EqSystem> osystlst = {};
4081 BackendDAE.Variables vars;
4082 BackendDAE.EquationArray eqns;
4083 list<BackendDAE.Var> lst_states;
4084 BackendDAE.Var tmpv;
4085 DAE.ComponentRef cref;
4086 DAE.Exp norm, y_norm, y, lhs;
4087 BackendDAE.Equation eqn;
4088 BackendDAE.Shared oshared;
4089 BackendDAE.EqSystem syst;
4090 algorithm
4091 2 BackendDAE.DAE(systlst, oshared) := inDAE;
4092
4093
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 for syst in systlst loop
4094 syst := match syst
4095 local
4096 BackendDAE.EqSystem syst1;
4097 case syst1 as BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns)
4098 algorithm
4099 // get vars
4100 2 lst_states := List.select(BackendVariable.varList(vars), BackendVariable.isStateVar);
4101 //BackendDump.printVarList(lst_states);
4102
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 for v in lst_states loop
4103 2 cref := BackendVariable.varCref(v);
4104 2 tmpv := BackendVariable.createVar(cref, "__OMC$scaled_state");
4105 2 y := Expression.crefExp(cref);
4106 2 norm := BackendVariable.getVarNominalValue(v);
4107 2 y_norm := Expression.expDiv(y,norm);
4108 2 (y_norm,_) := ExpressionSimplify.simplify(y_norm);
4109 // lhs
4110 2 cref := BackendVariable.varCref(tmpv);
4111 2 lhs := Expression.crefExp(cref);
4112 2 eqn := BackendDAE.EQUATION(lhs, y_norm, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC);
4113 //print("\n" + BackendDump.equationString(eqn));
4114 2 eqns := BackendEquation.add(eqn, eqns);
4115 2 vars := BackendVariable.addVar(tmpv, vars);
4116 end for;
4117 2 syst1.orderedVars := vars;
4118 2 syst1.orderedEqs := eqns;
4119 2 then BackendDAEUtil.clearEqSyst(syst1);
4120 end match;
4121 osystlst := syst::osystlst;
4122 end for;
4123
4124 2 outDAE := BackendDAE.DAE(osystlst, oshared);
4125 end addedScaledVars_states;
4126
4127 public function addedScaledVars_inputs
4128 "added var_norm = var/nominal, where var is state."
4129 input BackendDAE.BackendDAE inDAE;
4130 output BackendDAE.BackendDAE outDAE;
4131 protected
4132 list<BackendDAE.EqSystem> systlst;
4133 list<BackendDAE.EqSystem> osystlst = {};
4134 BackendDAE.Variables vars;
4135 BackendDAE.EquationArray eqns;
4136 list<BackendDAE.Var> kvarlst, lst_inputs;
4137 BackendDAE.Var tmpv;
4138 DAE.ComponentRef cref;
4139 DAE.Exp norm, y_norm, y, lhs;
4140 BackendDAE.Equation eqn;
4141 BackendDAE.Shared oshared;
4142 BackendDAE.EqSystem syst;
4143 algorithm
4144 2 BackendDAE.DAE(systlst, oshared) := inDAE;
4145 2 kvarlst := BackendVariable.varList(oshared.globalKnownVars);
4146 2 lst_inputs := List.select(kvarlst, BackendVariable.isVarOnTopLevelAndInputNoDerInput);
4147
4148 //BackendDump.printVarList(lst_inputs);
4149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 syst :: osystlst := systlst;
4150 syst := match syst
4151 local
4152 BackendDAE.EqSystem syst1;
4153 case syst1 as BackendDAE.EQSYSTEM(orderedEqs=eqns, orderedVars=vars)
4154 algorithm
4155
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 for v in lst_inputs loop
4156 2 cref := BackendVariable.varCref(v);
4157 2 tmpv := BackendVariable.createVar(cref, "__OMC$scaled_input");
4158 2 y := Expression.crefExp(cref);
4159 2 norm := BackendVariable.getVarNominalValue(v);
4160 2 y_norm := Expression.expDiv(y,norm);
4161 2 (y_norm,_) := ExpressionSimplify.simplify(y_norm);
4162 // lhs
4163 2 cref := BackendVariable.varCref(tmpv);
4164 2 lhs := Expression.crefExp(cref);
4165 2 eqn := BackendDAE.EQUATION(lhs, y_norm, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC);
4166 //print("\n" + BackendDump.equationString(eqn));
4167 2 eqns := BackendEquation.add(eqn, eqns);
4168 2 vars := BackendVariable.addVar(tmpv, vars);
4169 end for;
4170 2 syst1.orderedEqs := eqns;
4171 2 syst1.orderedVars := vars;
4172 2 then BackendDAEUtil.clearEqSyst(syst1);
4173 end match;
4174 osystlst := syst::osystlst;
4175
4176 2 outDAE := BackendDAE.DAE(osystlst, oshared);
4177 end addedScaledVars_inputs;
4178
4179 // =============================================================================
4180 // section for sortEqnsVars
4181 //
4182 // author: Vitalij Ruge
4183 // =============================================================================
4184
4185 public function sortEqnsVars
4186 input BackendDAE.BackendDAE inDAE;
4187 output BackendDAE.BackendDAE outDAE = inDAE;
4188 protected
4189 list<BackendDAE.EqSystem> systlst, new_systlst = {};
4190 BackendDAE.Shared shared;
4191 BackendDAE.Variables vars;
4192 BackendDAE.EquationArray eqns;
4193 BackendDAE.AdjacencyMatrix m;
4194 BackendDAE.AdjacencyMatrixT mT;
4195 Integer ne,nv;
4196 array<Integer> w_vars, w_eqns;
4197 AvlTreePathFunction.Tree functionTree;
4198 list<tuple<Integer,Integer>> tplIndexWeight;
4199 list<Integer> indexs;
4200 list<BackendDAE.Var> var_lst;
4201 list<BackendDAE.Equation> eqn_lst;
4202 algorithm
4203 //BackendDump.bltdump("Start", outDAE);
4204 ✗ BackendDAE.DAE(systlst, shared) := inDAE;
4205 ✗ BackendDAE.SHARED(functionTree=functionTree) := shared;
4206 ✗ for syst in systlst loop
4207 syst := match syst
4208 local
4209 BackendDAE.EqSystem syst1;
4210 case syst1 as BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns)
4211 algorithm
4212 ✗ (_, m, mT) := BackendDAEUtil.getAdjacencyMatrix(syst, BackendDAE.ABSOLUTE(), SOME(functionTree), BackendDAEUtil.isInitializationDAE(shared));
4213 //debug
4214 ✗ if Flags.isSet(Flags.SORT_EQNS_AND_VARS) then
4215 ✗ BackendDump.dumpAdjacencyMatrix(m);
4216 ✗ BackendDump.dumpAdjacencyMatrixT(mT);
4217 end if;
4218
4219 ✗ BackendDAE.VARIABLES(varArr = BackendDAE.VARIABLE_ARRAY(numberOfElements = nv)) := vars;
4220 ✗ ne := ExpandableArray.getNumberOfElements(eqns);
4221 //init weights
4222 ✗ w_vars := arrayCreate(nv, -1);
4223 ✗ w_eqns := arrayCreate(ne, -1);
4224 //weights vars, TODO: improve me!
4225 ✗ sortEqnsVarsWeights(w_vars, nv, mT);
4226 //weights eqns, TODO: improve me!
4227 ✗ sortEqnsVarsWeights(w_eqns, ne, m);
4228 //sort vars
4229 ✗ tplIndexWeight := list((i, w_vars[i]) for i in 1:nv);
4230 //sorted vars
4231 ✗ tplIndexWeight := List.sort(tplIndexWeight, Util.compareTuple2IntLt);
4232 //new order vars indexs
4233 ✗ indexs := sortEqnsVarsWorkTpl(tplIndexWeight);
4234 ✗ var_lst := list(BackendVariable.getVarAt(vars, i) for i in indexs);
4235 // new vars
4236 ✗ vars := BackendVariable.listVar1(var_lst);
4237 //sort eqns
4238 ✗ tplIndexWeight := list((i, w_eqns[i]) for i in 1:ne);
4239 //sorted eqns
4240 ✗ tplIndexWeight := List.sort(tplIndexWeight, Util.compareTuple2IntGt);
4241 //new order eqns indexs
4242 ✗ indexs := sortEqnsVarsWorkTpl(tplIndexWeight);
4243 ✗ eqn_lst := list(BackendEquation.get(eqns, i) for i in indexs);
4244 //new eqns
4245 ✗ eqns := BackendEquation.listEquation(eqn_lst);
4246 ✗ syst1.orderedEqs := eqns;
4247 ✗ syst1.orderedVars := vars;
4248
4249 //debug
4250 ✗ if Flags.isSet(Flags.SORT_EQNS_AND_VARS) then
4251 ✗ (_, m, mT) := BackendDAEUtil.getAdjacencyMatrix(syst1, BackendDAE.ABSOLUTE(), SOME(functionTree), BackendDAEUtil.isInitializationDAE(shared));
4252 ✗ BackendDump.dumpAdjacencyMatrix(m);
4253 ✗ BackendDump.dumpAdjacencyMatrixT(mT);
4254 end if;
4255
4256 ✗ GCExt.free(w_vars);
4257 ✗ GCExt.free(w_eqns);
4258 ✗ then BackendDAEUtil.clearEqSyst(syst1);
4259 end match;
4260 new_systlst := syst :: new_systlst;
4261 end for; //syst
4262
4263 ✗ outDAE:= BackendDAE.DAE(new_systlst, shared);
4264 //BackendDump.bltdump("End", outDAE);
4265 end sortEqnsVars;
4266
4267 protected function sortEqnsVarsWorkTpl
4268 input list<tuple<Integer,Integer>> tplIndexWeight;
4269 output list<Integer> outIndexs;
4270 algorithm
4271 ✗ outIndexs := list(Util.tuple21(elem) for elem in tplIndexWeight);
4272 end sortEqnsVarsWorkTpl;
4273
4274 protected function sortEqnsVarsWeights
4275 input array<Integer> inW;
4276 input Integer n;
4277 input BackendDAE.AdjacencyMatrix m;
4278 output array<Integer> outW = inW;
4279 protected
4280 Integer i;
4281 algorithm
4282 ✗ for i in 1:n loop
4283 ✗ outW[i] := listLength(m[i]);
4284 end for;
4285 end sortEqnsVarsWeights;
4286
4287 // =============================================================================
4288 // fix some bugs for complex function
4289 //
4290 // e.g. (a,-b) = f(.) -> (a,c) = f(.) with c = -b
4291 // (a,b) = (c,d) -> a=c and b = d
4292 // {a,b} = {c,d} -> a=c and b = d
4293 // (a,b) = f(a) fixed iterration var
4294 // author: Vitalij Ruge
4295 // =============================================================================
4296
4297
4298 public function simplifyComplexFunction
4299 input BackendDAE.BackendDAE inDAE;
4300 output BackendDAE.BackendDAE outDAE;
4301 algorithm
4302 2190 outDAE := simplifyComplexFunction1(inDAE, true);
4303 end simplifyComplexFunction;
4304
4305 public function simplifyComplexFunction1
4306 input BackendDAE.BackendDAE inDAE;
4307 input Boolean withTmpVars = false;
4308 output BackendDAE.BackendDAE outDAE = inDAE;
4309 protected
4310 list<BackendDAE.EqSystem> systlst = {};
4311 BackendDAE.Shared shared;
4312 BackendDAE.EquationArray eqns;
4313 BackendDAE.Variables vars;
4314 Integer n, size, idx = 1, m, j;
4315 BackendDAE.Equation eqn = BackendDAE.DUMMY_EQUATION(), eqn1;
4316 DAE.Exp left, right, e1, e2, e, e3;
4317 list<DAE.Exp> left_lst, right_lst;
4318 list<Integer> indRemove;
4319 DAE.ElementSource source "origin of equation";
4320 BackendDAE.EquationAttributes attr;
4321 Boolean update, sc;
4322 Absyn.Path path;
4323 list<DAE.Exp> arrayLst, arrayLst2, expLst;
4324 DAE.CallAttributes cattr;
4325 DAE.ComponentRef cr;
4326 BackendDAE.Var tmpvar;
4327 String tmpVarPrefix;
4328 algorithm
4329 2198 shared := inDAE.shared;
4330 tmpVarPrefix := match shared
4331 case BackendDAE.SHARED(backendDAEType=BackendDAE.SIMULATION()) then "$OMC$CF$sim";
4332 case BackendDAE.SHARED(backendDAEType=BackendDAE.INITIALSYSTEM()) then "$OMC$CF$init";
4333 else "$OMC$CF$unknown";
4334 end match;
4335
4336
2/2
✓ Branch 0 taken 51506 times.
✓ Branch 1 taken 2198 times.
53704 for syst in inDAE.eqs loop
4337 51506 BackendDAE.EQSYSTEM(orderedVars=vars,orderedEqs=eqns) := syst;
4338 51506 n := ExpandableArray.getNumberOfElements(eqns);
4339 update := false;
4340 indRemove := {};
4341
4342
2/2
✓ Branch 0 taken 51398 times.
✓ Branch 1 taken 108 times.
235563 for i in 1:n loop
4343 try
4344 184057 eqn := BackendEquation.get(eqns, i);
4345 else
4346 ✗ continue;
4347 end try;
4348
4/4
✓ Branch 1 taken 182836 times.
✓ Branch 2 taken 1221 times.
✓ Branch 4 taken 563 times.
✓ Branch 5 taken 182273 times.
184057 if BackendEquation.isComplexEquation(eqn) or BackendEquation.isArrayEquation(eqn) then
4349
2/2
✓ Branch 1 taken 1221 times.
✓ Branch 2 taken 563 times.
1784 if BackendEquation.isComplexEquation(eqn) then
4350
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1221 times.
1221 BackendDAE.COMPLEX_EQUATION(size=size,left=left, right=right, attr= attr, source=source) := eqn;
4351 else
4352
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 563 times.
563 BackendDAE.ARRAY_EQUATION(left=left, right=right, attr= attr, source=source) := eqn;
4353 end if;
4354
4355
4/4
✓ Branch 1 taken 518 times.
✓ Branch 2 taken 1266 times.
✓ Branch 4 taken 27 times.
✓ Branch 5 taken 491 times.
1784 if Expression.isTuple(left) and Expression.isTuple(right) then // tuple() = tuple()
4356 //print(BackendDump.equationString(eqn) + "--In--\n");
4357
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 DAE.TUPLE(PR = left_lst) := left;
4358
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 DAE.TUPLE(PR = right_lst) := right;
4359 27 update := true;
4360 27 indRemove := i :: indRemove;
4361
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 27 times.
82 for e1 in left_lst loop
4362
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
55 e2 :: right_lst := right_lst;
4363 //print("=>" + ExpressionBasics.printExpStr(e2) + " = " + ExpressionBasics.printExpStr(e1) + "\n");
4364
2/2
✓ Branch 1 taken 52 times.
✓ Branch 2 taken 3 times.
55 if not Expression.isWild(e1) then
4365
2/2
✓ Branch 1 taken 50 times.
✓ Branch 2 taken 2 times.
52 if Expression.isScalar(e2) then
4366 50 eqn1 := BackendEquation.generateEquation(e1, e2, source, attr);
4367 50 eqns := BackendEquation.add(eqn1, eqns);
4368 //print(BackendDump.equationString(eqn1) + "--new--\n");
4369 else
4370 2 expLst := simplifyComplexFunction2(e1);
4371 2 arrayLst := simplifyComplexFunction2(e2);
4372
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
5 for e_asub in arrayLst loop
4373
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 e3 :: expLst := expLst;
4374 3 eqn1 := BackendEquation.generateEquation(e_asub, e3, source, attr);
4375 3 eqns := BackendEquation.add(eqn1, eqns);
4376 //print(BackendDump.equationString(eqn1) + "--new--\n");
4377 end for;
4378 end if; //isScalar
4379 end if; // isWild
4380 end for;
4381 elseif Expression.isArray(left) and Expression.isArray(right)
4382 then // array{} = array{} // not work with arrayType
4383 //print(BackendDump.equationString(eqn) + "--In--\n");
4384 try
4385 5 left_lst := Expression.getArrayOrRangeContents(left);
4386 5 right_lst := Expression.getArrayOrRangeContents(right);
4387 5 update := true;
4388 5 indRemove := i :: indRemove;
4389
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 5 times.
20 for e1 in left_lst loop
4390
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 e2 :: right_lst := right_lst;
4391 //print("=>" + ExpressionBasics.printExpStr(e2) + " = " + ExpressionBasics.printExpStr(e1) + "\n");
4392
1/2
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
15 if not Expression.isWild(e1) then
4393
1/2
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
15 if Expression.isScalar(e2) then
4394 15 eqn1 := BackendEquation.generateEquation(e1, e2, source, attr);
4395 15 eqns := BackendEquation.add(eqn1, eqns);
4396 //print(BackendDump.equationString(eqn1) + "--new--\n");
4397 else
4398 ✗ expLst := simplifyComplexFunction2(e1);
4399 ✗ arrayLst := simplifyComplexFunction2(e2);
4400 ✗ for e_asub in arrayLst loop
4401 ✗ e3 :: expLst := expLst;
4402 ✗ eqn1 := BackendEquation.generateEquation(e_asub, e3, source, attr);
4403 ✗ eqns := BackendEquation.add(eqn1, eqns);
4404 //print(BackendDump.equationString(eqn1) + "--new--\n");
4405 end for;
4406 end if; //isScalar
4407 end if; // isWild
4408 end for;
4409 else
4410 ✗ continue;
4411 end try;
4412 elseif withTmpVars and Expression.isTuple(left) and Expression.isCall(right) //tuple() = call()
4413 then
4414
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 491 times.
491 DAE.TUPLE(PR = left_lst) := left;
4415
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 491 times.
491 DAE.CALL(path=path,expLst = expLst, attr= cattr) := right;
4416 expLst := {};
4417
2/2
✓ Branch 0 taken 2880 times.
✓ Branch 1 taken 491 times.
3371 for e1 in left_lst loop
4418
2/2
✓ Branch 1 taken 2868 times.
✓ Branch 2 taken 12 times.
2880 if Expression.isCref(e1) then
4419
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2868 times.
2868 DAE.CREF(componentRef = cr) := e1;
4420
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 2867 times.
2868 if Expression.expHasCrefNoPreOrStart(right, cr) then
4421 1 update := true;
4422 1 cr := ComponentReferenceBasics.makeCrefIdent(tmpVarPrefix + intString(idx), Expression.typeof(e1) , {});
4423 1 idx := idx + 1;
4424 1 e := Expression.crefExp(cr);
4425 1 tmpvar := BackendVariable.makeVar(cr);
4426 1 tmpvar := BackendVariable.setVarTS(tmpvar,SOME(BackendDAE.AVOID()));
4427 1 vars := BackendVariable.addVar(tmpvar, vars);
4428
4429 1 eqn1 := BackendDAE.EQUATION(e, e1, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC);
4430 1 eqns := BackendEquation.add(eqn1, eqns);
4431 else
4432 e := e1;
4433 end if;
4434 elseif Expression.isUnaryCref(e1) then
4435 ✗ update := true;
4436 ✗ cr := ComponentReferenceBasics.makeCrefIdent(tmpVarPrefix + intString(idx), Expression.typeof(e1) , {});
4437 ✗ idx := idx + 1;
4438 ✗ e := Expression.crefExp(cr);
4439 ✗ tmpvar := BackendVariable.makeVar(cr);
4440 ✗ tmpvar := BackendVariable.setVarTS(tmpvar,SOME(BackendDAE.AVOID()));
4441 ✗ vars := BackendVariable.addVar(tmpvar, vars);
4442 ✗ eqn1 := BackendDAE.EQUATION(e, e1, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC);
4443 //print(BackendDump.equationString(eqn1) + "--new--\n");
4444 ✗ eqns := BackendEquation.add(eqn1, eqns);
4445 elseif Expression.isArray(e1) then
4446 ✗ update := true;
4447 ✗ DAE.ARRAY(array=arrayLst, scalar=sc) := e1;
4448 ✗ m := listLength(arrayLst);
4449 ✗ cr := ComponentReferenceBasics.makeCrefIdent(tmpVarPrefix + intString(idx), Expression.typeof(e1) , {});
4450 ✗ idx := idx + 1;
4451 ✗ e := Expression.crefExp(cr);
4452 ✗ tmpvar := BackendVariable.makeVar(cr);
4453 ✗ tmpvar := BackendVariable.setVarTS(tmpvar,SOME(BackendDAE.AVOID()));
4454 ✗ tmpvar.arryDim := {DAE.DIM_INTEGER(m)};
4455 // e[1]
4456 ✗ arrayLst2 := list( Expression.makeAsubAddIndex(e,k) for k in 1:m);
4457 j := 1;
4458 ✗ for e2 in arrayLst2 loop
4459 ✗ e3 :: arrayLst := arrayLst;
4460 ✗ eqn1 := BackendDAE.EQUATION(e2, e3, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC);
4461 //print(BackendDump.equationString(eqn1) + "--new--\n");
4462 ✗ eqns := BackendEquation.add(eqn1, eqns);
4463 ✗ cr := ComponentReferenceBasics.makeCrefIdent(tmpVarPrefix + intString(idx-1), Expression.typeof(e1) , {DAE.INDEX(DAE.ICONST(j))});
4464 ✗ j := j + 1;
4465 ✗ tmpvar.varName := cr;
4466 ✗ vars := BackendVariable.addVar(tmpvar, vars);
4467 //vars := BackendVariable.addVar(tmpvar, vars);
4468 end for;
4469 //BackendDump.printVariables(vars);
4470 else
4471 e := e1;
4472 end if;
4473 expLst := e :: expLst;
4474 end for; // lhs
4475 491 left := DAE.TUPLE(MetaModelica.Dangerous.listReverseInPlace(expLst));
4476 491 eqn := BackendEquation.generateEquation(left, right, source, attr);
4477 491 eqns := BackendEquation.setAtIndex(eqns, i, eqn);
4478 end if; // lhs <-> rhs
4479 end if; // complex
4480 end for; //1:n
4481
4482
4483
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 51488 times.
51506 if update then
4484
2/2
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 18 times.
50 for i in listReverse(indRemove) loop
4485 //print("\neqns:" + intString(i) + "\n");
4486 //BackendDump.printEquationArray(eqns);
4487 32 eqns := BackendEquation.delete(i,eqns);
4488 end for;
4489 18 eqns := BackendEquation.listEquation(BackendEquation.equationList(eqns));
4490 18 systlst := BackendDAEUtil.createEqSystem(vars, eqns, syst.stateSets, syst.partitionKind, syst.removedEqs) :: systlst;
4491 else
4492 systlst := syst :: systlst;
4493 end if;
4494 end for; // syst
4495
4496 2198 outDAE.eqs := systlst;
4497 end simplifyComplexFunction1;
4498
4499 function simplifyComplexFunction2
4500 input DAE.Exp e1;
4501 output list<DAE.Exp> out_lst_e1 = {};
4502 protected
4503 list<DAE.Exp> lst_e;
4504 algorithm
4505 try
4506
3/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 8 times.
10 if Expression.isArray(e1) or Expression.isArrayType(Expression.typeof(e1)) then
4507 2 lst_e := Expression.getArrayOrRangeContents(e1);
4508
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 for e in lst_e loop
4509 4 out_lst_e1 := listAppend(simplifyComplexFunction2(e),out_lst_e1);
4510 end for;
4511 elseif Expression.isRecord(e1) then
4512 2 lst_e := Expression.splitRecord(e1, Expression.typeof(e1));
4513
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 for e in lst_e loop
4514 2 out_lst_e1 := listAppend(simplifyComplexFunction2(e),out_lst_e1);
4515 end for;
4516 out_lst_e1 := {e1};
4517 else
4518 out_lst_e1 := {e1};
4519 end if;
4520 else
4521 out_lst_e1 := {e1};
4522 end try;
4523
4524 end simplifyComplexFunction2;
4525
4526 // =============================================================================
4527 // section for hets
4528 //
4529 // (h)euristic (e)quation (t)erms (s)ort
4530 // heuristic sorting of terms for better numeric in equations(res, torn,...)
4531 //
4532 // author: Vitalij Ruge
4533 // =============================================================================
4534
4535 public function hets
4536 input BackendDAE.BackendDAE inDAE;
4537 output BackendDAE.BackendDAE outDAE;
4538 algorithm
4539 ✗ if Flags.getConfigString(Flags.HETS)<> "none" then
4540 ✗ outDAE := hetsWork(inDAE);
4541 else
4542 outDAE := inDAE;
4543 end if;
4544 end hets;
4545
4546 protected function hetsWork
4547 input BackendDAE.BackendDAE inDAE;
4548 output BackendDAE.BackendDAE outDAE = inDAE;
4549 protected
4550 BackendDAE.EquationArray eqns;
4551 BackendDAE.Variables vars;
4552 BackendDAE.Matching matching;
4553 BackendDAE.StateSets stateSets;
4554 BackendDAE.BaseClockPartitionKind partitionKind;
4555 BackendDAE.InnerEquations innerEquations;
4556 BackendDAE.InnerEquation innerEquation;
4557 Integer i,j;
4558 BackendDAE.Equation eqn;
4559 list<Integer> tvars "be careful with states, this are solved for der(x)";
4560 list<Integer> teqns;
4561 DAE.ComponentRef cr;
4562 BackendDAE.StrongComponents comps;
4563 BackendDAE.Shared shared;
4564 algorithm
4565 ✗ shared := outDAE.shared;
4566 ✗ for syst in outDAE.eqs loop
4567 ✗ BackendDAE.EQSYSTEM(orderedVars=vars,orderedEqs=eqns,matching=matching as BackendDAE.MATCHING(comps=comps),stateSets=stateSets,partitionKind=partitionKind) := syst;
4568
4569 ✗ for comp in comps loop
4570 ✗ if BackendEquation.isTornSystem(comp) then
4571
4572 ✗ BackendDAE.TORNSYSTEM(strictTearingSet = BackendDAE.TEARINGSET(tearingvars=tvars, residualequations=teqns, innerEquations = innerEquations)) := comp;
4573 ✗ for innerEquation in innerEquations loop
4574 try
4575 ✗ (i,{j},_) := BackendDAEUtil.getEqnAndVarsFromInnerEquation(innerEquation);
4576 ✗ eqn := BackendEquation.get(eqns, i);
4577 ✗ BackendDAE.VAR(varName = cr) := BackendVariable.getVarAt(vars, j);
4578 ✗ eqn := BackendEquation.solveEquation(eqn, Expression.crefExp(cr), SOME(shared.functionTree));
4579 ✗ eqn := hetsSplitRhs(eqn);
4580 ✗ eqns := BackendEquation.setAtIndex(eqns, i, eqn);
4581 else
4582 end try;
4583 end for;
4584
4585 ✗ for i in teqns loop
4586 ✗ eqn := BackendEquation.get(eqns, i);
4587 ✗ eqn := hetsSplitRes(eqn);
4588 ✗ eqns := BackendEquation.setAtIndex(eqns, i, eqn);
4589 end for;
4590 elseif BackendEquation.isEquationsSystem(comp) then
4591 ✗ BackendDAE.EQUATIONSYSTEM(eqns=teqns) := comp;
4592 ✗ for i in teqns loop
4593 ✗ eqn := BackendEquation.get(eqns, i);
4594 ✗ eqn := hetsSplitRes(eqn);
4595 ✗ eqns := BackendEquation.setAtIndex(eqns, i, eqn);
4596 end for;
4597 end if;
4598 end for;
4599 end for;
4600 end hetsWork;
4601
4602 function hetsSplitRes
4603 input BackendDAE.Equation iEqn;
4604 output BackendDAE.Equation oEqn;
4605
4606 algorithm
4607 oEqn := match iEqn
4608 local DAE.Exp e1,e2, e;
4609 DAE.ElementSource source;
4610 BackendDAE.EquationAttributes attr;
4611
4612 case BackendDAE.EQUATION(exp=e1, scalar=e2, source=source, attr=attr)
4613 algorithm
4614 ✗ e := Expression.createResidualExp(e1, e2);
4615 ✗ e := hetsSplitExp(e);
4616 ✗ then BackendDAE.RESIDUAL_EQUATION(e, source, attr);
4617
4618 case BackendDAE.RESIDUAL_EQUATION(e, source, attr)
4619 algorithm
4620 ✗ e := hetsSplitExp(e);
4621 ✗ then BackendDAE.RESIDUAL_EQUATION(e, source, attr);
4622
4623 else iEqn;
4624 end match;
4625 end hetsSplitRes;
4626
4627 function hetsSplitRhs
4628 input BackendDAE.Equation iEqn;
4629 output BackendDAE.Equation oEqn;
4630
4631 algorithm
4632 oEqn := match iEqn
4633 local DAE.Exp e1,e2;
4634 DAE.ElementSource source;
4635 BackendDAE.EquationAttributes attr;
4636
4637 case BackendDAE.EQUATION(exp=e1, scalar=e2, source=source, attr=attr)
4638 algorithm
4639 ✗ e2 := hetsSplitExp(e2);
4640 ✗ then BackendDAE.EQUATION(e1, e2, source, attr);
4641
4642 else iEqn;
4643 end match;
4644 end hetsSplitRhs;
4645
4646 function hetsSplitExp
4647 input DAE.Exp iExp;
4648 output DAE.Exp oExp;
4649 algorithm
4650 oExp := match iExp
4651 local DAE.Exp e,e1,e2; DAE.Operator op;
4652 list<DAE.Exp> terms, termsDer;
4653
4654 case DAE.BINARY(e1, op, e2)
4655 guard Expression.isMulOrDiv(op)
4656 algorithm
4657 ✗ e1 := hetsSplitExp(e1);
4658 ✗ e2 := hetsSplitExp(e2);
4659 ✗ then DAE.BINARY(e1, op, e2);
4660
4661 case e as DAE.BINARY(_, op, _)
4662 guard Expression.isAddOrSub(op)
4663 algorithm
4664 ✗ terms := Expression.terms(e);
4665 ✗ terms := list(hetsSplitExp(t) for t in terms);
4666 ✗ (termsDer, terms) := List.splitOnTrue(terms, Expression.expHasDer);
4667 ✗ then Expression.expAdd(Expression.makeSum1(terms), Expression.makeSum1(termsDer));
4668 else iExp;
4669 end match;
4670 end hetsSplitExp;
4671
4672 // =============================================================================
4673 // section inlineFunctionInLoops
4674 // force inlining function of loop
4675 // author: Vitalij Ruge
4676 // motivation see #3997 library devs introduce annotation(Inline=true) for simplify loops
4677 // =============================================================================
4678 public function inlineFunctionInLoops
4679 input output BackendDAE.BackendDAE dae;
4680 algorithm
4681 4 dae := inlineFunctionInLoopsMain(dae);
4682 end inlineFunctionInLoops;
4683
4684 protected function inlineFunctionInLoopsMain
4685 input BackendDAE.BackendDAE inDAE;
4686 output BackendDAE.BackendDAE outDAE;
4687 protected
4688 BackendDAE.Shared shared;
4689 AvlTreePathFunction.Tree functionTree;
4690 BackendDAE.EqSystems eqs;
4691 BackendDAE.EqSystem _syst;
4692 algorithm
4693 4 shared := inDAE.shared;
4694 4 functionTree := shared.functionTree;
4695 eqs := {};
4696
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 for syst in inDAE.eqs loop
4697 4 (_syst, shared) := inlineFunctionInLoopsWork(syst, functionTree, shared);
4698 eqs := _syst :: eqs;
4699 end for;
4700 4 outDAE := BackendDAE.DAE(eqs, shared);
4701 end inlineFunctionInLoopsMain;
4702
4703 protected function inlineFunctionInLoopsWork
4704 input output BackendDAE.EqSystem syst;
4705 input AvlTreePathFunction.Tree functionTree;
4706 input output BackendDAE.Shared shared;
4707 protected
4708 BackendDAE.Variables vars;
4709 BackendDAE.EquationArray eqns;
4710 BackendDAE.BaseClockPartitionKind partitionKind;
4711 BackendDAE.StateSets stateSets;
4712 BackendDAE.StrongComponents comps;
4713 BackendDAE.Matching matching;
4714 BackendDAE.StateSets stateSets;
4715 Inline.Functiontuple fns = (SOME(functionTree),{DAE.NORM_INLINE(),DAE.AFTER_INDEX_RED_INLINE(), DAE.DEFAULT_INLINE()});
4716 Boolean inlined;
4717 BackendDAE.Equation eq, eqNew;
4718 BackendDAE.EqSystem tmpEqs, tmpEqs1;
4719 list<Integer> idEqns;
4720 Boolean inlined1;
4721 Integer id;
4722 algorithm
4723 4 inlined := false;
4724 inlined1 := false;
4725 4 tmpEqs1 := BackendDAEUtil.createEqSystem( BackendVariable.listVar({}), BackendEquation.listEquation({}));
4726
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 BackendDAE.EQSYSTEM(orderedVars=vars,orderedEqs=eqns,matching=matching as BackendDAE.MATCHING(comps=comps),stateSets=stateSets,partitionKind=partitionKind) := syst;
4727
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 for comp in comps
4728 loop
4729 if BackendEquation.isEquationsSystem(comp) or BackendEquation.isTornSystem(comp) or
4730 (match comp case BackendDAE.SINGLECOMPLEXEQUATION() then true; else false; end match)
4731 then
4732 idEqns := match comp
4733 case BackendDAE.EQUATIONSYSTEM(eqns=idEqns) then idEqns;
4734 case BackendDAE.SINGLECOMPLEXEQUATION(eqn = id) then {id};
4735 end match;
4736
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 for id in idEqns
4737 loop
4738 8 eq := BackendEquation.get(eqns, id);
4739 //eqn := BackendInline.inlineEqOpt(SOME(eq), fns);
4740 //eqns := BackendEquation.setAtIndexFirst(id, eq, eqns);
4741 8 (eqNew, tmpEqs, inlined, shared) := BackendInline.inlineEqAppend_debug(eq, fns, shared);
4742
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
8 if inlined or not BackendEquation.equationEqual(eq, eqNew)
4743 then
4744 8 tmpEqs1 := BackendDAEUtil.mergeEqSystems(tmpEqs, tmpEqs1);
4745 8 eqns := BackendEquation.setAtIndexFirst(id, eqNew, eqns);
4746 //BackendDump.printEquation(BackendEquation.get(eqns, id));
4747 inlined1 := true;
4748 end if;
4749 end for;
4750 end if;
4751 end for;
4752
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 syst.orderedEqs := eqns;
4753
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if inlined1 then
4754 4 syst := BackendDAEUtil.clearEqSyst(syst);
4755 4 syst := BackendDAEUtil.mergeEqSystems(tmpEqs1, syst);
4756 end if;
4757 end inlineFunctionInLoopsWork;
4758
4759 // =============================================================================
4760 // section for simplifyLoops
4761 //
4762 // simplify(hopful) loops for simulation/optimization
4763 // author: Vitalij Ruge
4764 // =============================================================================
4765
4766 public function simplifyLoops
4767 input BackendDAE.BackendDAE inDAE;
4768 output BackendDAE.BackendDAE outDAE;
4769 algorithm
4770
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 outDAE := if Flags.getConfigInt(Flags.SIMPLIFY_LOOPS) > 0 then simplifyLoopsMain(inDAE) else inDAE;
4771 end simplifyLoops;
4772
4773 protected function simplifyLoopsMain
4774 input BackendDAE.BackendDAE inDAE;
4775 output BackendDAE.BackendDAE outDAE = inDAE;
4776 protected
4777 list<BackendDAE.EqSystem> new_systlst = {};
4778 BackendDAE.Shared shared;
4779 BackendDAE.Variables vars;
4780 BackendDAE.EquationArray eqns;
4781 BackendDAE.BaseClockPartitionKind partitionKind;
4782 BackendDAE.StateSets stateSets;
4783 BackendDAE.StrongComponents comps;
4784 BackendDAE.Matching matching;
4785 AvlTreePathFunction.Tree functionTree;
4786 Boolean update;
4787 Integer index = 1, ii;
4788 BackendDAE.EqSystem nSyst;
4789 list<Integer> ass1;
4790 list<Integer> ass2;
4791 list<Integer> compOrders;
4792 Integer ne, nv;
4793 Boolean simDAE;
4794 algorithm
4795 //BackendDump.bltdump("START:", outDAE);
4796 8 shared := inDAE.shared;
4797 8 functionTree := shared.functionTree;
4798
4799 simDAE := match shared
4800 case BackendDAE.SHARED(backendDAEType=BackendDAE.SIMULATION()) then true;
4801 case BackendDAE.SHARED(backendDAEType=BackendDAE.INITIALSYSTEM()) then true;
4802 else false;
4803 end match;
4804
4805
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
8 if Flags.isSet(Flags.DUMP_SIMPLIFY_LOOPS) then
4806 4 print("START: simplifyLoops\n");
4807
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if not simDAE then
4808 ✗ print("\n***noSIM***\n");
4809 end if;
4810 end if;
4811
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 8 times.
24 for syst in inDAE.eqs loop
4812 16 update := false;
4813 16 ass1 := {};
4814 16 ass2 := {};
4815 16 compOrders := {};
4816 ii := 1;
4817
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 BackendDAE.EQSYSTEM(orderedVars=vars,orderedEqs=eqns,matching=matching as BackendDAE.MATCHING(comps=comps),stateSets=stateSets,partitionKind=partitionKind) := syst;
4818 16 ne := ExpandableArray.getNumberOfElements(eqns);
4819 16 BackendDAE.VARIABLES(numberOfVars= nv) := vars;
4820
4821
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 16 times.
266 for comp in comps loop
4822
3/4
✓ Branch 1 taken 250 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 242 times.
250 if BackendEquation.isEquationsSystem(comp) or BackendEquation.isTornSystem(comp) then
4823 8 (index,vars,eqns,shared,update, ass1, ass2,compOrders) := simplifyLoopsWork(comp, index, vars, eqns, shared, update, ass1, ass2, simDAE, ii, compOrders);
4824 end if;
4825 250 ii := ii + 1;
4826 end for; // comp
4827
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 10 times.
16 nSyst := if update then simplifyLoopsUpdateMatching(vars, eqns, syst, listReverse(ass1), listReverse(ass2), ne, nv, functionTree, listReverse(compOrders)) else syst;
4828 new_systlst := nSyst :: new_systlst;
4829 end for; //syst
4830 8 outDAE:= BackendDAE.DAE(new_systlst, shared);
4831 //outDAE:= BackendDAE.DAE(listReverse(new_systlst), shared);
4832 //BackendDump.bltdump("ENDE:", outDAE);
4833
4834
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
8 if Flags.isSet(Flags.DUMP_SIMPLIFY_LOOPS) then
4835 4 print("END: simplifyLoops\n");
4836 end if;
4837
4838 end simplifyLoopsMain;
4839
4840 protected function simplifyLoopsUpdateMatching
4841 "
4842 TODO: check me!
4843 "
4844 input BackendDAE.Variables inVars "vars array";
4845 input BackendDAE.EquationArray inEqns "eqns array";
4846 input BackendDAE.EqSystem inSyst;
4847 input list<Integer> ass1_;
4848 input list<Integer> ass2_;
4849 input Integer nEqns;
4850 input Integer nVars;
4851 input AvlTreePathFunction.Tree functionTree;
4852 input list<Integer> compOrders;
4853 output BackendDAE.EqSystem outSyst = inSyst;
4854
4855 protected
4856 array<Integer> ass1 "eqn := ass1[var]";
4857 array<Integer> ass2 "var := ass2[eqn]";
4858 Integer n1, n2;
4859 BackendDAE.Matching matching;
4860 BackendDAE.StrongComponents comps;
4861 algorithm
4862 //print("\nStart simplifyLoopsUpdateMatching");
4863 6 matching := inSyst.matching;
4864
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 BackendDAE.MATCHING(comps=comps, ass1=ass1, ass2=ass2) := matching;
4865
4866 6 n1 := listLength(ass1_);
4867 6 n2 := listLength(ass2_);
4868
4869 6 ass1 := Array.expand(n1, ass1, -1);
4870 6 ass2 := Array.expand(n2, ass2, -1);
4871
4872 //print("ass1 :" + intString(arrayLength(ass1)) + "/" + intString(n1) + "/" + intString(nEqns));
4873 //print("\nass2 :" + intString(arrayLength(ass2)) + "/" + intString(n2) + "/" + intString(nVars) + "\n");
4874 //alg fix
4875
4876 6 ass1 := simplifyLoopsUpdateAss(ass1, ass1_, nVars);
4877 6 ass2 := simplifyLoopsUpdateAss(ass2, ass2_, nEqns);
4878
4879 6 comps := simplifyLoopsUpdateComps(comps, ass1_, ass2_, compOrders);
4880
4881 6 outSyst.matching := BackendDAE.MATCHING(ass1, ass2, comps);
4882 outSyst.orderedEqs := inEqns;
4883 outSyst.orderedVars := inVars;
4884 6 outSyst := BackendDAEUtil.setEqSystMatrices(outSyst);
4885
4886 //print("\nEnde simplifyLoopsUpdateMatching");
4887 end simplifyLoopsUpdateMatching;
4888
4889 protected function simplifyLoopsUpdateAss
4890 input array<Integer> inAss;
4891 input list<Integer> new_ass;
4892 input Integer n;
4893 output array<Integer> outAss = inAss;
4894 protected
4895 Integer i = 1;
4896 algorithm
4897
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 12 times.
66 for a in new_ass loop
4898 54 outAss[i+n] := a;
4899 54 i := i + 1;
4900 end for;
4901 end simplifyLoopsUpdateAss;
4902
4903 protected function simplifyLoopsUpdateComps
4904 input BackendDAE.StrongComponents inComps;
4905 input list<Integer> inAss1;
4906 input list<Integer> inAss2;
4907 input list<Integer> inCompOrders;
4908 output BackendDAE.StrongComponents outComps = inComps;
4909 protected
4910 Integer a1, a2, shift = 0, o;
4911 BackendDAE.StrongComponent comp;
4912 list<Integer> ass1 = inAss1, ass2 = inAss2, compOrders = inCompOrders;
4913 algorithm
4914
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 6 times.
33 for a1 in ass1 loop
4915
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 o :: compOrders := compOrders;
4916
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 a2 :: ass2 := ass2;
4917 27 comp := BackendDAE.SINGLEEQUATION(a1, a2);
4918 //print("comp: " + intString(a1) + " <->" + intString(a2) + "\n");
4919 27 outComps := List.insert(outComps, o + shift, comp);
4920 27 shift := shift + 1;
4921 //outComps := comp :: outComps;
4922 end for;
4923 end simplifyLoopsUpdateComps;
4924
4925 protected function simplifyLoopsWork
4926 input BackendDAE.StrongComponent inComp;
4927 input Integer inIndx;
4928 input BackendDAE.Variables inVars "vars array";
4929 input BackendDAE.EquationArray inEqns "eqns array";
4930 input BackendDAE.Shared inShared;
4931 input Boolean inUpdate;
4932 input list<Integer> ass1_;
4933 input list<Integer> ass2_;
4934 input Boolean simDAE;
4935 input Integer ii;
4936 input list<Integer> inCompOrders;
4937 output Integer outIndx = inIndx;
4938 output BackendDAE.Variables outVars = inVars "vars array";
4939 output BackendDAE.EquationArray outEqns = inEqns "eqns array";
4940 output BackendDAE.Shared outShared = inShared;
4941 output Boolean outUpdate = inUpdate;
4942 output list<Integer> ass1 = ass1_;
4943 output list<Integer> ass2 = ass2_;
4944 output list<Integer> outCompOrders = inCompOrders;
4945 protected
4946 list<Integer> eqns;
4947 list<Integer> vv;
4948 list<Integer> vars "be careful with states, this are solved for der(x)";
4949 list<DAE.ComponentRef> var_lst = {} "varName";
4950 DAE.ComponentRef cr;
4951 BackendDAE.Equation eqn;
4952 Boolean update, linear;
4953 Integer i, k;
4954 BackendDAE.InnerEquations innerEquations;
4955 BackendDAE.InnerEquation innerEquation;
4956 algorithm
4957
4958
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 if BackendEquation.isEquationsSystem(inComp) then
4959 ✗ BackendDAE.EQUATIONSYSTEM(eqns=eqns,vars=vars) := inComp;
4960
4961 //linear system need simplifications?
4962 ✗ if BackendDAEUtil.isLinearEqSystemComp(inComp) then
4963 ✗ return;
4964 end if;
4965 ✗ if Flags.isSet(Flags.DUMP_SIMPLIFY_LOOPS) then
4966 ✗ print("------ EquationsSystem ------\n");
4967 end if;
4968
4969 else
4970
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 BackendDAE.TORNSYSTEM(linear=linear, strictTearingSet = BackendDAE.TEARINGSET(tearingvars=vars, residualequations=eqns, innerEquations = innerEquations)) := inComp;
4971
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if linear then
4972 ✗ return;
4973 end if;
4974
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
8 if Flags.isSet(Flags.DUMP_SIMPLIFY_LOOPS) then
4975 4 print("------ Tearing ------\n");
4976 end if;
4977
4978
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 8 times.
56 for innerEquation in innerEquations loop
4979 48 (k,vv) := BackendDAEUtil.getEqnAndVarsFromInnerEquation(innerEquation);
4980 eqns := k :: eqns;
4981 48 vars := listAppend(vv,vars);
4982 end for;
4983 end if; //comp
4984
4985
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
8 if Flags.isSet(Flags.DUMP_SIMPLIFY_LOOPS) then
4986 4 print("------ loop-vars ------\n");
4987 end if;
4988
4989
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 8 times.
64 for i in vars loop
4990 56 BackendDAE.VAR(varName = cr) := BackendVariable.getVarAt(outVars, i);
4991 56 var_lst := cr :: var_lst;
4992
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 44 times.
56 if Flags.isSet(Flags.DUMP_SIMPLIFY_LOOPS) then
4993 12 print(ComponentReferenceBasics.printComponentRefStr(cr) +"\n");
4994 end if;
4995 end for;
4996
4997
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
8 if Flags.isSet(Flags.DUMP_SIMPLIFY_LOOPS) then
4998 4 print("------------\n");
4999 end if;
5000
5001
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 8 times.
64 for i in eqns loop
5002 try
5003 56 eqn := BackendEquation.get(outEqns, i);
5004
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 44 times.
56 if Flags.isSet(Flags.DUMP_SIMPLIFY_LOOPS) then
5005 12 print("update eqn[" + intString(i) + "]\n");
5006 12 print(BackendDump.equationString(eqn) + "--old--\n");
5007 end if;
5008 56 (outIndx, outVars, outEqns, outShared, update, eqn, ass1, ass2, outCompOrders) := simplifyLoopEqn(outIndx, outVars, outEqns, outShared, var_lst, eqn, ass1, ass2, simDAE, ii, outCompOrders);
5009
4/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 40 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 6 times.
56 outUpdate := outUpdate or update;
5010 //if update then
5011 56 outEqns := BackendEquation.setAtIndex(outEqns, i, eqn);
5012 //end if;
5013
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 44 times.
56 if Flags.isSet(Flags.DUMP_SIMPLIFY_LOOPS) then
5014 12 print("=> ");
5015 12 print(BackendDump.equationString(eqn) + "--new--\n");
5016 end if;
5017 else
5018 end try;
5019 end for;
5020
5021 end simplifyLoopsWork;
5022
5023 protected function simplifyLoopEqn
5024 input Integer inIndx;
5025 input BackendDAE.Variables inVars "vars array";
5026 input BackendDAE.EquationArray inEqns "eqns array";
5027 input BackendDAE.Shared inShared;
5028 input list<DAE.ComponentRef> var_lst "filter vars";
5029 input BackendDAE.Equation inEqn "filter eqn";
5030 input list<Integer> ass1_;
5031 input list<Integer> ass2_;
5032 input Boolean simDAE;
5033 input Integer ii;
5034 input list<Integer> inCompOrders;
5035 output Integer outIndx = inIndx;
5036 output BackendDAE.Variables outVars = inVars "vars array";
5037 output BackendDAE.EquationArray outEqns = inEqns "eqns array";
5038 output BackendDAE.Shared outShared = inShared;
5039 output Boolean outUpdate = false;
5040 output BackendDAE.Equation outEqn = inEqn;
5041 output list<Integer> ass1 = ass1_;
5042 output list<Integer> ass2 = ass2_;
5043 output list<Integer> outCompOrder = inCompOrders;
5044 protected
5045 DAE.Exp rhs, lhs, e;
5046 Boolean update_lhs, update_rhs;
5047 list<DAE.Exp> loopTerms_lhs, noLoopTerms_lhs, loopTerms_rhs, noLoopTerms_rhs;
5048 Boolean useTmpVars = Flags.getConfigInt(Flags.SIMPLIFY_LOOPS) > 1;
5049 algorithm
5050
5051
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 56 times.
56 if BackendEquation.isAlgorithm(outEqn) then
5052 ✗ return;
5053 end if;
5054
5055 //get
5056 56 lhs := BackendEquation.getEquationLHS(outEqn);
5057 //check
5058
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 56 times.
56 if not Types.isIntegerOrRealOrSubTypeOfEither(Expression.typeof(lhs)) then
5059 ✗ return ;
5060 end if;
5061 56 rhs := BackendEquation.getEquationRHS(outEqn);
5062
5063 56 (loopTerms_lhs, noLoopTerms_lhs) := simplifyLoops_SplitTerms(var_lst, lhs);
5064 56 (loopTerms_rhs, noLoopTerms_rhs) := simplifyLoops_SplitTerms(var_lst, rhs);
5065
5066
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 54 times.
56 if listLength(loopTerms_lhs) > listLength(loopTerms_rhs) then
5067 2 lhs := Expression.expSub(Expression.makeSum1(loopTerms_lhs), Expression.makeSum1(loopTerms_rhs));
5068 2 rhs := Expression.expSub(Expression.makeSum1(noLoopTerms_rhs), Expression.makeSum1(noLoopTerms_lhs));
5069 else
5070 54 lhs := Expression.expSub(Expression.makeSum1(loopTerms_rhs), Expression.makeSum1(loopTerms_lhs));
5071 54 rhs := Expression.expSub(Expression.makeSum1(noLoopTerms_lhs), Expression.makeSum1(noLoopTerms_rhs));
5072 end if;
5073
5074 //
5075 56 (lhs,rhs,_) := Expression.createResidualExp3(lhs,rhs);
5076 56 (lhs,e) := Expression.makeFraction(lhs);
5077 56 (lhs, _) := ExpressionSimplify.simplify(lhs);
5078 56 (e, _) := ExpressionSimplify.simplify(e);
5079
5080 //rhs := Expression.expMul(rhs,e);
5081 56 rhs := ExpressionSimplify.simplifySumOperatorExpression(rhs, DAE.MUL(Expression.typeof(rhs)), e);
5082
5083 //update
5084 56 (outIndx, outVars, outEqns, outShared, update_rhs, rhs, ass1, ass2, outCompOrder) := simplifyLoopExp(outIndx, outVars, outEqns, outShared, var_lst, rhs, ass1, ass2, simDAE, useTmpVars,ii,outCompOrder);
5085 56 (outIndx, outVars, outEqns, outShared, update_lhs, lhs, ass1, ass2, outCompOrder) := simplifyLoopExp(outIndx, outVars, outEqns, outShared, var_lst, lhs, ass1, ass2, simDAE, useTmpVars,ii,outCompOrder);
5086
5087 //
5088 56 outEqn := BackendEquation.setEquationLHS(outEqn, lhs);
5089 56 outEqn := BackendEquation.setEquationRHS(outEqn, rhs);
5090
5091
4/4
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 33 times.
✓ Branch 3 taken 1 time.
56 outUpdate := outUpdate or update_rhs or update_lhs;
5092 end simplifyLoopEqn;
5093
5094
5095 public function simplifyLoopExp
5096 input Integer inIndx;
5097 input BackendDAE.Variables inVars "vars array";
5098 input BackendDAE.EquationArray inEqns "eqns array";
5099 input BackendDAE.Shared inShared;
5100 input list<DAE.ComponentRef> var_lst "filter vars";
5101 input DAE.Exp inExp;
5102 input list<Integer> ass1_;
5103 input list<Integer> ass2_;
5104 input Boolean simDAE;
5105 input Boolean useTmpVars = true;
5106 input Integer ii;
5107 input list<Integer> inCompOrders;
5108 input String tmpVarName = "LOOP";
5109 input Boolean noPara = false;
5110 output Integer outIndx = inIndx;
5111 output BackendDAE.Variables outVars = inVars "vars array";
5112 output BackendDAE.EquationArray outEqns = inEqns "eqns array";
5113 output BackendDAE.Shared outShared = inShared;
5114 output Boolean outUpdate = false;
5115 output DAE.Exp outExp = inExp;
5116 output list<Integer> ass1 = ass1_;
5117 output list<Integer> ass2 = ass2_;
5118 output list<Integer> outCompOrder = inCompOrders;
5119 protected
5120 list<DAE.Exp> loopTerms, noLoopTerms, loopFactors, noLoopFactors, loopTermsUpdatedFactors, loopFacotrsUpdatedTerms;
5121 DAE.Exp res, noLoopTerm, noLoopFactor, e1, e2;
5122 Boolean update;
5123 DAE.Operator op;
5124 Boolean para;
5125 algorithm
5126
5127 152 (loopTerms, noLoopTerms) := simplifyLoops_SplitTerms(var_lst, outExp);
5128
5129 //terms
5130 152 (noLoopTerm,_) := ExpressionSimplify.simplify1(Expression.makeSum1(noLoopTerms));
5131
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 24 times.
152 if useTmpVars and simDAE then
5132 128 (noLoopTerm, outEqns, outVars, outShared, update, para) := BackendEquation.makeTmpEqnForExp(noLoopTerm, tmpVarName + "T", System.tmpTickIndex(Global.tmpVariableIndex), outEqns, outVars, outShared);
5133 128 (outUpdate, ass1, ass2, outIndx, outCompOrder) := simplifyLoopExpHelper(update, outUpdate, para, ass1, ass2, outVars, outEqns, outIndx, ii, outCompOrder);
5134 end if;
5135
5136 //factors
5137 loopTermsUpdatedFactors := {};
5138
2/2
✓ Branch 0 taken 159 times.
✓ Branch 1 taken 152 times.
311 for factor in loopTerms loop
5139 159 (loopFactors, noLoopFactors) := simplifyLoops_SplitFactors(var_lst, factor);
5140 159 (noLoopFactor,_) := ExpressionSimplify.simplify1(Expression.makeProductLst(noLoopFactors));
5141
5142
2/2
✓ Branch 0 taken 133 times.
✓ Branch 1 taken 26 times.
159 if useTmpVars and simDAE then
5143 if (match noLoopFactor case DAE.BINARY(operator = DAE.DIV()) then true; case DAE.BINARY(operator = DAE.POW()) then true; else false; end match) then
5144
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 DAE.BINARY(e1,op,e2) := noLoopFactor;
5145 2 (e1, outEqns, outVars, outShared, update, para) := BackendEquation.makeTmpEqnForExp(e1, "LOOPF", if simDAE then outIndx else -outIndx, outEqns, outVars, outShared,noPara);
5146 2 (outUpdate, ass1, ass2, outIndx, outCompOrder) := simplifyLoopExpHelper(update, outUpdate, para, ass1, ass2, outVars, outEqns, outIndx, ii, outCompOrder);
5147 2 (e2, outEqns, outVars, outShared, update, para) := BackendEquation.makeTmpEqnForExp(e2, "LOOPF", if simDAE then outIndx else -outIndx, outEqns, outVars, outShared,noPara);
5148 2 (outUpdate, ass1, ass2, outIndx, outCompOrder) := simplifyLoopExpHelper(update, outUpdate, para, ass1, ass2, outVars, outEqns, outIndx, ii, outCompOrder);
5149 2 noLoopFactor := DAE.BINARY(e1,op,e2);
5150 else
5151 131 (noLoopFactor, outEqns, outVars, outShared, update, para) := BackendEquation.makeTmpEqnForExp(noLoopFactor, tmpVarName + "F", if simDAE then outIndx else -outIndx, outEqns, outVars, outShared);
5152 131 (outUpdate, ass1, ass2, outIndx, outCompOrder) := simplifyLoopExpHelper(update, outUpdate, para, ass1, ass2, outVars, outEqns, outIndx, ii, outCompOrder);
5153 end if;
5154 end if;
5155
5156 //recursive
5157 loopFacotrsUpdatedTerms := {};
5158
2/2
✓ Branch 0 taken 159 times.
✓ Branch 1 taken 159 times.
318 for term in loopFactors loop
5159 159 res := term;
5160
2/2
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 141 times.
159 if Expression.isBinary(res) then
5161
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 DAE.BINARY(operator=op) := res;
5162
4/6
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 10 times.
✗ Branch 8 not taken.
18 if Expression.isAddOrSub(op) or Expression.isMulOrDiv(op) or Expression.isPow(op) then
5163
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 if not ExpressionBasics.expEqual(res, inExp) then
5164
3/4
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 8 times.
18 if Expression.isDiv(op) or Expression.isPow(op) then
5165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 DAE.BINARY(e1,op,e2) := res;
5166 10 (outIndx, outVars, outEqns, outShared, update, e1, ass1, ass2, outCompOrder) := simplifyLoopExp(outIndx, outVars, outEqns, outShared, var_lst, e1, ass1, ass2, simDAE, useTmpVars, ii, outCompOrder);
5167 10 outUpdate := update or outUpdate;
5168 10 (outIndx, outVars, outEqns, outShared, update, e2, ass1, ass2, outCompOrder) := simplifyLoopExp(outIndx, outVars, outEqns, outShared, var_lst, e2, ass1, ass2, simDAE, useTmpVars, ii, outCompOrder);
5169 10 outUpdate := update or outUpdate;
5170 10 (e2,_) := ExpressionSimplify.simplify1(e2);
5171 10 res := DAE.BINARY(e1,op,e2);
5172 else
5173 8 (outIndx, outVars, outEqns, outShared, update, res, ass1, ass2, outCompOrder) := simplifyLoopExp(outIndx, outVars, outEqns, outShared, var_lst, res, ass1, ass2, simDAE, useTmpVars, ii, outCompOrder);
5174 8 outUpdate := update or outUpdate;
5175 end if; // DIV, POW
5176 end if; // equal
5177 end if; // *, /, +, -, ^
5178 end if; // BINARY
5179 159 loopFacotrsUpdatedTerms := res :: loopFacotrsUpdatedTerms;
5180 end for; //term2
5181 159 loopTermsUpdatedFactors := Expression.makeProductLst(noLoopFactor :: loopFacotrsUpdatedTerms) :: loopTermsUpdatedFactors;
5182 end for; //factor
5183
5184 152 outExp := ExpressionSimplify.simplify(Expression.makeSum1(noLoopTerm::loopTermsUpdatedFactors,true));
5185
5186 end simplifyLoopExp;
5187
5188 protected function simplifyLoopExpHelper
5189 input Boolean update;
5190 input Boolean update_;
5191 input Boolean para;
5192 input list<Integer> ass1_;
5193 input list<Integer> ass2_;
5194 input BackendDAE.Variables inVars "vars array";
5195 input BackendDAE.EquationArray inEqns "eqns array";
5196 input Integer inIndex;
5197 input Integer ii;
5198 input list<Integer> inCompOrders;
5199 output Boolean outUpdate = update_;
5200 output list<Integer> ass1 = ass1_;
5201 output list<Integer> ass2 = ass2_;
5202 output Integer outIndx = inIndex;
5203 output list<Integer> outCompOrder = inCompOrders;
5204 protected
5205 Integer ne, nv;
5206 algorithm
5207
2/2
✓ Branch 0 taken 228 times.
✓ Branch 1 taken 35 times.
263 if update then
5208 35 outIndx := outIndx + 1;
5209 outUpdate := update;
5210
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35 times.
35 if not para then
5211 35 ne := ExpandableArray.getNumberOfElements(inEqns);
5212 35 BackendDAE.VARIABLES(numberOfVars= nv) := inVars;
5213 ass1 := ne :: ass1;
5214 ass2 := nv :: ass2;
5215 outCompOrder := ii :: outCompOrder;
5216 end if;
5217 end if;
5218 end simplifyLoopExpHelper;
5219
5220 public function simplifyLoops_SplitTerms
5221 input list<DAE.ComponentRef> var_lst;
5222 input DAE.Exp inExp;
5223 output list<DAE.Exp> loopTerms = {};
5224 output list<DAE.Exp> noLoopTerms;
5225 protected
5226 list<DAE.Exp> tmp_loopTerms;
5227 algorithm
5228 267 noLoopTerms := Expression.terms(inExp);
5229
2/2
✓ Branch 0 taken 1944 times.
✓ Branch 1 taken 128 times.
2072 for cr in var_lst loop
5230
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 1805 times.
1944 if listEmpty(noLoopTerms) then
5231 break;
5232 else
5233 1805 (tmp_loopTerms, noLoopTerms) := List.split1OnTrue(noLoopTerms, Expression.expHasCrefNoPreOrStart, cr);
5234 1805 loopTerms := listAppend(tmp_loopTerms, loopTerms);
5235 end if;
5236 end for;
5237 end simplifyLoops_SplitTerms;
5238
5239 protected function simplifyLoops_SplitFactors
5240 input list<DAE.ComponentRef> var_lst;
5241 input DAE.Exp inExp;
5242 output list<DAE.Exp> loopTerms = {};
5243 output list<DAE.Exp> noLoopTerms;
5244 protected
5245 list<DAE.Exp> tmp_loopTerms;
5246 algorithm
5247 159 noLoopTerms := Expression.factors(inExp);
5248
2/2
✓ Branch 0 taken 1019 times.
✓ Branch 1 taken 59 times.
1078 for cr in var_lst loop
5249
2/2
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 919 times.
1019 if listEmpty(noLoopTerms) then
5250 break;
5251 else
5252 919 (tmp_loopTerms, noLoopTerms) := List.split1OnTrue(noLoopTerms, Expression.expHasCrefNoPreOrStart, cr);
5253 919 loopTerms := listAppend(tmp_loopTerms, loopTerms);
5254 end if;
5255 end for;
5256
5257 end simplifyLoops_SplitFactors;
5258
5259 // =============================================================================
5260 // section for introduceDerAlias
5261 //
5262 // =============================================================================
5263
5264 public function introduceDerAlias
5265 " This module introduces alias for derivatove call in the form
5266 dx = der(x);
5267 This helps tearing and non-linear solvers to handle them more efficent."
5268 input BackendDAE.BackendDAE inDAE;
5269 output BackendDAE.BackendDAE outDAE;
5270 algorithm
5271 1 outDAE := BackendDAEUtil.mapEqSystem(inDAE, introduceDerAliasWork);
5272 end introduceDerAlias;
5273
5274 protected function introduceDerAliasWork
5275 input BackendDAE.EqSystem inSyst;
5276 input BackendDAE.Shared shared;
5277 output BackendDAE.EqSystem osyst;
5278 output BackendDAE.Shared oshared = shared;
5279 protected
5280 BackendDAE.Variables vars;
5281 BackendDAE.EquationArray eqns;
5282 list<BackendDAE.Equation> eqnsList;
5283 algorithm
5284 osyst := match inSyst
5285 local
5286 BackendDAE.EqSystem syst;
5287 case syst as BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns)
5288 algorithm
5289 2 (eqns, (vars, eqnsList, _, _)) :=
5290 BackendEquation.traverseEquationArray_WithUpdate( eqns, traverserintroduceDerAliasEquation,
5291 (vars, {}, shared, true) );
5292 2 eqns := BackendEquation.addList(eqnsList, eqns);
5293
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 syst.orderedEqs := eqns; syst.orderedVars := vars;
5294 then syst;
5295 end match;
5296 end introduceDerAliasWork;
5297
5298 protected function traverserintroduceDerAliasEquation "
5299 Help function to e.g. introduceDerAliasWork"
5300 input BackendDAE.Equation inEq;
5301 input tuple<BackendDAE.Variables, list<BackendDAE.Equation>, BackendDAE.Shared, Boolean> tpl;
5302 output BackendDAE.Equation outEq;
5303 output tuple<BackendDAE.Variables, list<BackendDAE.Equation>, BackendDAE.Shared, Boolean> outTpl;
5304 protected
5305 BackendDAE.Equation e;
5306 BackendDAE.Variables vars;
5307 Boolean b;
5308 list<DAE.SymbolicOperation> ops;
5309 BackendDAE.Shared shared;
5310 list<BackendDAE.Equation> eqnLst;
5311 algorithm
5312 15 (vars, eqnLst, shared, b) := tpl;
5313
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 (e, (vars, eqnLst, shared, ops, _)) := BackendEquation.traverseExpsOfEquation(inEq, traverserintroduceDerAliasExp, (vars, eqnLst, shared, {}, b));
5314 15 outEq := List.foldr(ops, BackendEquation.addOperation, e);
5315 15 outTpl := (vars, eqnLst, shared, b);
5316 end traverserintroduceDerAliasEquation;
5317
5318 protected function traverserintroduceDerAliasExp "
5319 Help function to e.g. traverserintroduceDerAliasEquation"
5320 input DAE.Exp inExp;
5321 input tuple<BackendDAE.Variables, list<BackendDAE.Equation>, BackendDAE.Shared, list<DAE.SymbolicOperation>, Boolean> tpl;
5322 output DAE.Exp outExp;
5323 output tuple<BackendDAE.Variables, list<BackendDAE.Equation>, BackendDAE.Shared, list<DAE.SymbolicOperation>, Boolean> outTpl;
5324 protected
5325 DAE.Exp e, e1;
5326 tuple<BackendDAE.Variables, list<BackendDAE.Equation>, BackendDAE.Shared, Boolean, Boolean> ext_arg;
5327 BackendDAE.Variables vars;
5328 list<DAE.SymbolicOperation> ops;
5329 Boolean b, addVars;
5330 BackendDAE.Shared shared;
5331 list<BackendDAE.Equation> eqnLst;
5332 algorithm
5333 e := inExp;
5334 30 (vars, eqnLst, shared, ops, addVars) := tpl;
5335
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 ext_arg := (vars, eqnLst, shared, addVars, false);
5336 30 (e1, (vars, eqnLst, shared, _, b)) := Expression.traverseExpBottomUp(e, introDerAlias, ext_arg);
5337 30 ops := List.consOnTrue(b, DAE.SUBSTITUTION({e1}, e), ops);
5338 outExp := e1;
5339 30 outTpl := (vars, eqnLst, shared, ops, addVars);
5340 end traverserintroduceDerAliasExp;
5341
5342 protected function introDerAlias "
5343 Help function to e.g. traverserintroduceDerAliasExp"
5344 input DAE.Exp inExp;
5345 input tuple<BackendDAE.Variables, list<BackendDAE.Equation>, BackendDAE.Shared, Boolean, Boolean> itpl;
5346 output DAE.Exp outExp;
5347 output tuple<BackendDAE.Variables, list<BackendDAE.Equation>, BackendDAE.Shared, Boolean, Boolean> tpl;
5348 algorithm
5349 (outExp,tpl) := matchcontinue (inExp, itpl)
5350 local
5351 BackendDAE.Variables vars;
5352 DAE.ComponentRef cr,cref;
5353 DAE.Type ty;
5354 String str;
5355 BackendDAE.Shared shared;
5356 BackendDAE.Var v, v1;
5357 Boolean addVar;
5358 list<BackendDAE.Equation> eqnLst;
5359 Integer numVars;
5360 list<DAE.Exp> expLst;
5361 String str;
5362
5363 case (DAE.CALL(path=Absyn.IDENT(name="der"), expLst={DAE.CREF(componentRef=cr, ty=ty)}), (vars, eqnLst, shared, addVar, _)) algorithm
5364 10 (v, _) := BackendVariable.getVarSingle(cr, vars);
5365 10 cref := BackendVariable.varCref(v);
5366 10 v1 := BackendVariable.createAliasDerVar(cref);
5367 10 v1 := BackendVariable.mergeNominalAttribute(v, v1, false);
5368 10 cref := BackendVariable.varCref(v1);
5369 10 outExp := DAE.CREF(cref,ty);
5370
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if addVar then
5371 10 numVars := BackendVariable.varsSize(vars);
5372 10 vars := BackendVariable.addVar(v1, vars);
5373
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 6 times.
10 eqnLst := if numVars < BackendVariable.varsSize(vars) then BackendDAE.EQUATION(inExp, outExp, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC)::eqnLst else eqnLst;
5374 end if;
5375
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 then (outExp, (vars, eqnLst, shared, addVar, true));
5376
5377 case (DAE.CALL(path=Absyn.IDENT(name="der")), _) algorithm
5378 ✗ str := "BackendDAEOptimize.introduceDerAlias failed for: " + ExpressionBasics.printExpStr(inExp) + "\n";
5379 ✗ Error.addMessage(Error.INTERNAL_ERROR, {str});
5380 ✗ then fail();
5381
5382 else (inExp, itpl);
5383 end matchcontinue;
5384 end introDerAlias;
5385
5386
5387 // =============================================================================
5388 // section for replaceDerCall
5389 //
5390 // =============================================================================
5391
5392 public function replaceDerCalls
5393 " This module replaces all der(cref)-calls by $DER.cref crefs expression."
5394 input BackendDAE.BackendDAE inDAE;
5395 output BackendDAE.BackendDAE outDAE;
5396 algorithm
5397 ✗ outDAE := BackendDAEUtil.mapEqSystem(inDAE, replaceDerCallWork);
5398 end replaceDerCalls;
5399
5400 protected function replaceDerCallWork
5401 input BackendDAE.EqSystem inSyst;
5402 input BackendDAE.Shared shared;
5403 output BackendDAE.EqSystem osyst;
5404 output BackendDAE.Shared oshared = shared;
5405 algorithm
5406 osyst := match inSyst
5407 local
5408 BackendDAE.EqSystem syst;
5409 BackendDAE.Variables localKnowns;
5410 BackendDAE.Variables vars;
5411 BackendDAE.EquationArray eqns;
5412 case syst as BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns)
5413 algorithm
5414 ✗ (eqns, vars) :=
5415 BackendEquation.traverseEquationArray_WithUpdate(eqns, traverserreplaceDerCall, vars);
5416 ✗ (localKnowns, vars) := BackendVariable.traverseBackendDAEVars(vars,
5417 moveStatesVariables, (oshared.localKnownVars, vars));
5418 ✗ oshared.localKnownVars := localKnowns;
5419 ✗ syst.orderedEqs := eqns;
5420 ✗ syst.orderedVars := vars;
5421 then syst;
5422 end match;
5423 end replaceDerCallWork;
5424
5425 protected function traverserreplaceDerCall "
5426 Help function to e.g. replaceDerCall"
5427 input BackendDAE.Equation inEq;
5428 input BackendDAE.Variables inVars;
5429 output BackendDAE.Equation outEq;
5430 output BackendDAE.Variables outVars = inVars;
5431 protected
5432 BackendDAE.Equation e;
5433 list<DAE.SymbolicOperation> ops;
5434 algorithm
5435 ✗ (e, ops) := BackendEquation.traverseExpsOfEquation(inEq, traverserreplaceDerCallExp, {});
5436 ✗ outEq := List.foldr(ops, BackendEquation.addOperation, e);
5437 end traverserreplaceDerCall;
5438
5439 protected function traverserreplaceDerCallExp "
5440 Help function to e.g. traverserreplaceDerCall"
5441 input DAE.Exp inExp;
5442 input list<DAE.SymbolicOperation> tpl;
5443 output DAE.Exp outExp;
5444 output list<DAE.SymbolicOperation> outTpl;
5445 protected
5446 DAE.Exp e, e1;
5447 Boolean b;
5448 algorithm
5449 e := inExp;
5450 ✗ (e1, b) := Expression.traverseExpBottomUp(e, replaceDerCall, false);
5451 ✗ outTpl := List.consOnTrue(b, DAE.SUBSTITUTION({e1}, e), tpl);
5452 outExp := e1;
5453 end traverserreplaceDerCallExp;
5454
5455 protected function replaceDerCall "
5456 Help function to e.g. traverserreplaceDerCallExp"
5457 input DAE.Exp inExp;
5458 input Boolean itpl;
5459 output DAE.Exp outExp;
5460 output Boolean tpl;
5461 algorithm
5462 (outExp,tpl) := matchcontinue inExp
5463 local
5464 DAE.ComponentRef cr,cref;
5465 DAE.Type ty;
5466
5467 case DAE.CALL(path=Absyn.IDENT(name="der"), expLst={DAE.CREF(componentRef=cr, ty=ty)}) algorithm
5468 ✗ cref := ComponentReference.crefPrefixDer(cr);
5469 ✗ outExp := DAE.CREF(cref,ty);
5470 then (outExp, true);
5471
5472 case DAE.CALL(path=Absyn.IDENT(name="der")) algorithm
5473 ✗ Error.addMessage(Error.INTERNAL_ERROR, {getInstanceName() + " failed for: " + ExpressionBasics.printExpStr(inExp) + "\n"});
5474 ✗ then fail();
5475
5476 else (inExp, itpl);
5477 end matchcontinue;
5478 end replaceDerCall;
5479
5480 protected function moveStatesVariables
5481 input BackendDAE.Var inVar;
5482 input tuple<BackendDAE.Variables, BackendDAE.Variables> inTpl;
5483 output BackendDAE.Var outVar = inVar;
5484 output tuple<BackendDAE.Variables, BackendDAE.Variables> outTpl = inTpl;
5485 algorithm
5486 () := match inVar
5487 local
5488 DAE.ComponentRef cref;
5489 BackendDAE.Var newVar;
5490 BackendDAE.Variables localKnowns, newVars;
5491 case BackendDAE.VAR(varKind = BackendDAE.STATE(), varName=cref) algorithm
5492 ✗ (localKnowns, newVars) := inTpl;
5493 // remove the state from variables
5494 ✗ newVars := BackendVariable.deleteVar(cref, newVars);
5495 // push it to the local knows
5496 ✗ localKnowns := BackendVariable.addVar(inVar, localKnowns);
5497
5498 ✗ cref := ComponentReference.crefPrefixDer(cref);
5499 ✗ newVar := BackendVariable.copyVarNewName(cref, inVar);
5500 ✗ newVar := BackendVariable.setVarKind(newVar, BackendDAE.STATE_DER());
5501
5502 ✗ newVars := BackendVariable.addVar(newVar, newVars);
5503 ✗ outTpl := (localKnowns, newVars);
5504 then ();
5505 else ();
5506 end match;
5507 end moveStatesVariables;
5508
5509
5510 // =============================================================================
5511 // replace expression with rewritten expression
5512 //
5513 // =============================================================================
5514
5515 public function applyRewriteRulesBackend
5516 "@author: adrpo"
5517 input BackendDAE.BackendDAE inDAE;
5518 output BackendDAE.BackendDAE outDAE;
5519 algorithm
5520 ✗ (outDAE, _) := BackendDAEUtil.mapEqSystemAndFold(inDAE, applyRewriteRulesBackend0, false);
5521 ✗ outDAE := applyRewriteRulesBackendShared(outDAE);
5522 end applyRewriteRulesBackend;
5523
5524 protected function applyRewriteRulesBackend0
5525 "@author: adrpo"
5526 input BackendDAE.EqSystem isyst;
5527 input BackendDAE.Shared inShared;
5528 input Boolean inChanged;
5529 output BackendDAE.EqSystem osyst = isyst;
5530 output BackendDAE.Shared outShared = inShared;
5531 output Boolean outChanged;
5532 algorithm
5533 try
5534 ✗ BackendDAEUtil.traverseBackendDAEExpsVarsWithUpdate(isyst.orderedVars, traverserapplyRewriteRulesBackend, false);
5535 ✗ BackendDAEUtil.traverseBackendDAEExpsEqns(isyst.orderedEqs, traverserapplyRewriteRulesBackend, false);
5536 ✗ BackendDAEUtil.traverseBackendDAEExpsEqns(isyst.removedEqs, traverserapplyRewriteRulesBackend, false);
5537 outChanged := true;
5538 else
5539 outChanged := false;
5540 end try;
5541 end applyRewriteRulesBackend0;
5542
5543 protected function traverserapplyRewriteRulesBackend
5544 "@author: adrpo"
5545 input DAE.Exp inExp;
5546 input Boolean inB;
5547 output DAE.Exp outExp;
5548 output Boolean outB;
5549 algorithm
5550 ✗ (outExp,outB) := Expression.traverseExpBottomUp(inExp,traverserExpapplyRewriteRulesBackend,inB);
5551 end traverserapplyRewriteRulesBackend;
5552
5553 protected function traverserExpapplyRewriteRulesBackend
5554 "@author: adrpo"
5555 input DAE.Exp inExp;
5556 input Boolean inB;
5557 output DAE.Exp outExp;
5558 output Boolean outB;
5559 algorithm
5560 (outExp,outB) := matchcontinue inExp
5561 local
5562 DAE.Exp e;
5563
5564 // apply rewrite rule
5565 case e algorithm
5566 ✗ (e, true) := RewriteRules.rewriteBackEnd(e);
5567 then (e, true);
5568
5569 else (inExp,inB);
5570 end matchcontinue;
5571 end traverserExpapplyRewriteRulesBackend;
5572
5573 protected function applyRewriteRulesBackendShared "@author: adrpo"
5574 input BackendDAE.BackendDAE inDAE;
5575 output BackendDAE.BackendDAE outDAE;
5576 protected
5577 BackendDAE.Shared shared;
5578 algorithm
5579 ✗ shared := inDAE.shared;
5580 ✗ BackendDAEUtil.traverseBackendDAEExpsVarsWithUpdate(shared.globalKnownVars, traverserapplyRewriteRulesBackend, false);
5581 ✗ BackendDAEUtil.traverseBackendDAEExpsEqns(shared.initialEqs, traverserapplyRewriteRulesBackend, false);
5582 ✗ BackendDAEUtil.traverseBackendDAEExpsEqns(shared.removedEqs, traverserapplyRewriteRulesBackend, false);
5583 // not sure if we should apply the rules on the event info!
5584 // (ei, _) := traverseEventInfoExps(eventInfo, traverserapplyRewriteRulesBackend, false);
5585 ✗ outDAE := BackendDAE.DAE(inDAE.eqs, shared);
5586 end applyRewriteRulesBackendShared;
5587
5588 // =============================================================================
5589 // generates a list with all iteration variables
5590 //
5591 // =============================================================================
5592
5593 public function listAllIterationVariables "author: lochel"
5594 input BackendDAE.BackendDAE inBackendDAE;
5595 protected
5596 BackendDAE.BackendDAEType backendDAEType;
5597 list<String> warnings;
5598 algorithm
5599 4 BackendDAE.DAE(shared=BackendDAE.SHARED(backendDAEType=backendDAEType)) := inBackendDAE;
5600 4 (warnings, _) := listAllIterationVariables0(inBackendDAE.eqs);
5601
5602 4 Error.addCompilerNotification("List of all iteration variables (DAE kind: " + BackendDump.printBackendDAEType2String(backendDAEType) + ")\n" + stringDelimitList(warnings, "\n"));
5603 end listAllIterationVariables;
5604
5605 public function listAllIterationVariables0 "author: lochel"
5606 input list<BackendDAE.EqSystem> inEqs;
5607 output list<String> outWarnings;
5608 output list<DAE.ComponentRef> outComponentRef;
5609 protected
5610 list<String> warnings;
5611 list<DAE.ComponentRef> crefs;
5612 list<list<String>> warnings_accum = {};
5613 list<list<DAE.ComponentRef>> crefs_accum = {};
5614 algorithm
5615
2/2
✓ Branch 0 taken 44822 times.
✓ Branch 1 taken 1123 times.
45945 for eq in inEqs loop
5616 44822 (warnings, crefs) := listAllIterationVariables1(eq);
5617 warnings_accum := warnings :: warnings_accum;
5618 44822 crefs_accum := crefs :: crefs_accum;
5619 end for;
5620
5621 1123 outWarnings := List.flattenReverse(warnings_accum);
5622 1123 outComponentRef := List.flattenReverse(crefs_accum);
5623 end listAllIterationVariables0;
5624
5625 protected function listAllIterationVariables1 "author: lochel"
5626 input BackendDAE.EqSystem inEqSystem;
5627 output list<String> outWarning;
5628 output list<DAE.ComponentRef> outComponentRef;
5629 protected
5630 BackendDAE.Variables vars;
5631 BackendDAE.StrongComponents comps;
5632 algorithm
5633
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44822 times.
44822 BackendDAE.EQSYSTEM(orderedVars=vars,
5634 matching=BackendDAE.MATCHING(comps=comps)) := inEqSystem;
5635 44822 (outWarning, outComponentRef) := listAllIterationVariables2(comps, vars);
5636 end listAllIterationVariables1;
5637
5638 protected function listAllIterationVariables2
5639 input BackendDAE.StrongComponents comps;
5640 input BackendDAE.Variables vars;
5641 output list<String> warnings = {};
5642 output list<DAE.ComponentRef> componentRefs = {};
5643 protected
5644 list<Integer> var_idxs, var_idxs2;
5645
5646 constant String NONLINEAR_SYSTEM = "Iteration variables of nonlinear equation system:\n";
5647 constant String ANALYTIC_JACOBIAN = "Iteration variables of equation system with analytic Jacobian:\n";
5648 constant String NO_ANALYTIC_JACOBIAN = "Iteration variables of equation system without analytic Jacobian:\n";
5649 constant String TORN_LINEAR = "Iteration variables of torn linear equation system:\n";
5650 constant String TORN_NONLINEAR = "Iteration variables of torn nonlinear equation system:\n";
5651 algorithm
5652
2/2
✓ Branch 1 taken 92463 times.
✓ Branch 2 taken 44822 times.
137285 for comp in listReverse(comps) loop
5653 (warnings, componentRefs) := match comp
5654 case BackendDAE.EQUATIONSYSTEM(jacType = BackendDAE.JAC_NONLINEAR())
5655 ✗ then listAllIterationVariables3(comp.vars, vars, NONLINEAR_SYSTEM, warnings, componentRefs);
5656
5657 case BackendDAE.EQUATIONSYSTEM(jacType = BackendDAE.JAC_GENERIC())
5658 175 then listAllIterationVariables3(comp.vars, vars, ANALYTIC_JACOBIAN, warnings, componentRefs);
5659
5660 case BackendDAE.EQUATIONSYSTEM(jacType = BackendDAE.JAC_NO_ANALYTIC())
5661 1 then listAllIterationVariables3(comp.vars, vars, NO_ANALYTIC_JACOBIAN, warnings, componentRefs);
5662
5663 case BackendDAE.TORNSYSTEM(strictTearingSet = BackendDAE.TEARINGSET(tearingvars = var_idxs),
5664 casualTearingSet = NONE())
5665
2/2
✓ Branch 0 taken 329 times.
✓ Branch 1 taken 410 times.
1068 then listAllIterationVariables3(var_idxs, vars,
5666 if comp.linear then TORN_LINEAR else TORN_NONLINEAR, warnings, componentRefs);
5667
5668 case BackendDAE.TORNSYSTEM(strictTearingSet = BackendDAE.TEARINGSET(tearingvars = var_idxs),
5669 casualTearingSet = SOME(BackendDAE.TEARINGSET(tearingvars = var_idxs2)))
5670 ✗ then
5671 listAllIterationVariables3(List.union(var_idxs, var_idxs2), vars,
5672 if comp.linear then TORN_LINEAR else TORN_NONLINEAR, warnings, componentRefs);
5673
5674 91548 else (warnings, componentRefs);
5675 end match;
5676 end for;
5677 end listAllIterationVariables2;
5678
5679 protected function listAllIterationVariables3
5680 input list<Integer> varIndices;
5681 input BackendDAE.Variables allVars;
5682 input String message;
5683 input output list<String> warnings;
5684 input output list<DAE.ComponentRef> crefs;
5685 protected
5686 list<BackendDAE.Var> vars;
5687 algorithm
5688
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 915 times.
915 if not listEmpty(varIndices) then
5689
4/4
✓ Branch 0 taken 3422 times.
✓ Branch 1 taken 915 times.
✓ Branch 2 taken 3422 times.
✓ Branch 3 taken 915 times.
4337 vars := list(BackendVariable.getVarAt(allVars, v) for v in varIndices);
5690
4/4
✓ Branch 0 taken 3422 times.
✓ Branch 1 taken 915 times.
✓ Branch 2 taken 3422 times.
✓ Branch 3 taken 915 times.
4337 crefs := List.append_reverse(list(BackendVariable.varCref(v) for v in vars), crefs);
5691 915 warnings := (message + warnAboutVars(vars)) :: warnings;
5692 end if;
5693 end listAllIterationVariables3;
5694
5695 protected function warnAboutVars
5696 input list<BackendDAE.Var> vars;
5697 output String str;
5698 algorithm
5699
4/4
✓ Branch 0 taken 3422 times.
✓ Branch 1 taken 915 times.
✓ Branch 2 taken 3422 times.
✓ Branch 3 taken 915 times.
4337 str := stringDelimitList(list(" " + BackendDump.varString(v) for v in vars), "\n");
5700 end warnAboutVars;
5701
5702 public function addTimeAsState
5703 input BackendDAE.BackendDAE inDAE;
5704 output BackendDAE.BackendDAE outDAE = inDAE;
5705 protected
5706 BackendDAE.EqSystems eqs;
5707 BackendDAE.EqSystem eq;
5708 BackendDAE.Shared shared;
5709 BackendDAE.Variables orderedVars "ordered Variables, only states and alg. vars";
5710 BackendDAE.EquationArray orderedEqs "ordered Equations";
5711 BackendDAE.Var var;
5712 algorithm
5713 ✗ (BackendDAE.DAE(eqs, shared), _) := BackendDAEUtil.mapEqSystemAndFold(inDAE, addTimeAsState1, 0);
5714 ✗ orderedVars := BackendVariable.emptyVars();
5715 var := BackendDAE.VAR(DAE.crefTimeState, BackendDAE.STATE(1, NONE(), true), DAE.BIDIR(), DAE.NON_PARALLEL(), DAE.T_REAL_DEFAULT, NONE(), NONE(), {}, DAE.emptyElementSource, NONE(), NONE(), NONE(), NONE(), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER(), true, false, false);
5716 ✗ var := BackendVariable.setVarFixed(var, true);
5717 ✗ var := BackendVariable.setVarStartValue(var, DAE.CREF(DAE.crefTime, DAE.T_REAL_DEFAULT));
5718 ✗ orderedVars := BackendVariable.addVar(var, orderedVars);
5719 ✗ orderedEqs := BackendEquation.emptyEqnsSized(1);
5720 ✗ orderedEqs := BackendEquation.add(BackendDAE.EQUATION(DAE.CALL(Absyn.IDENT("der"), {DAE.CREF(DAE.crefTimeState, DAE.T_REAL_DEFAULT)}, DAE.callAttrBuiltinReal), DAE.RCONST(1.0), DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC), orderedEqs);
5721 ✗ eq := BackendDAEUtil.createEqSystem(orderedVars, orderedEqs, {}, BackendDAE.CONTINUOUS_TIME_PARTITION());
5722 ✗ outDAE := BackendDAE.DAE(eq::eqs, shared);
5723 end addTimeAsState;
5724
5725 protected function addTimeAsState1
5726 input BackendDAE.EqSystem inSystem;
5727 input BackendDAE.Shared inShared;
5728 input Integer inFoo;
5729 output BackendDAE.EqSystem outSystem;
5730 output BackendDAE.Shared outShared = inShared;
5731 output Integer outFoo = inFoo;
5732 algorithm
5733 outSystem := matchcontinue inSystem
5734 local
5735 BackendDAE.EquationArray orderedEqs;
5736 BackendDAE.EqSystem syst;
5737
5738 case syst as BackendDAE.EQSYSTEM( orderedEqs=orderedEqs)
5739 algorithm
5740 ✗ BackendEquation.traverseEquationArray_WithUpdate(orderedEqs, addTimeAsState2, inFoo);
5741 then syst;
5742
5743 else inSystem;
5744 end matchcontinue;
5745 end addTimeAsState1;
5746
5747 protected function addTimeAsState2
5748 input BackendDAE.Equation inEq;
5749 input Integer inFoo;
5750 output BackendDAE.Equation outEq;
5751 output Integer outFoo = inFoo;
5752 algorithm
5753 ✗ (outEq, _) := BackendEquation.traverseExpsOfEquation(inEq, addTimeAsState3, inFoo);
5754 end addTimeAsState2;
5755
5756 protected function addTimeAsState3
5757 input DAE.Exp inExp;
5758 input Integer inTuple;
5759 output DAE.Exp outExp;
5760 output Integer outTuple;
5761 algorithm
5762 ✗ (outExp, outTuple) := Expression.traverseExpTopDown(inExp, addTimeAsState4, inTuple);
5763 end addTimeAsState3;
5764
5765 protected function addTimeAsState4
5766 input DAE.Exp inExp;
5767 input Integer inTuple;
5768 output DAE.Exp outExp;
5769 output Boolean cont = true;
5770 output Integer outTuple = inTuple;
5771 algorithm
5772 outExp := match inExp
5773 local
5774 DAE.Type ty;
5775
5776 case DAE.CREF(componentRef=DAE.CREF_IDENT(ident="time"), ty=ty) algorithm
5777 ✗ then DAE.CREF(DAE.crefTimeState, ty);
5778
5779 else inExp;
5780 end match;
5781 end addTimeAsState4;
5782
5783 //-------------------------------------
5784 //Evaluate Output Variables Only.
5785 //-------------------------------------
5786 public function evaluateOutputsOnly"Computes only the scc which are necessary in order to calculate the output vars.
5787 author: Waurich TUD 09/2015"
5788 input BackendDAE.BackendDAE daeIn;
5789 output BackendDAE.BackendDAE daeOut;
5790 protected
5791 Integer size, nVars, nEqs;
5792 array<Integer> ass1,ass2, varVisited;
5793 list<Integer> outputVarIndxs, stateIndxs, stateTasks, stateTasks1 , outputTasks, predecessors, tasks;
5794 list<BackendDAE.StrongComponent> comps, compsNew, addComps;
5795 BackendDAE.StrongComponent comp;
5796 BackendDAE.EqSystem syst;
5797 BackendDAE.EqSystems systs, systsNew;
5798 BackendDAE.Equation eq;
5799 BackendDAE.EquationArray eqs;
5800 BackendDAE.AdjacencyMatrix m, mT;
5801 BackendDAE.Matching matching;
5802 BackendDAE.Shared shared;
5803 BackendDAE.Variables vars;
5804 AvlTreePathFunction.Tree funcTree;
5805 list<BackendDAE.Equation> eqLst, eqLstNew;
5806 list<BackendDAE.Var> varLst, varLstNew, states;
5807 list<DAE.ComponentRef> crefs;
5808 HpcOmTaskGraph.TaskGraph taskGraph, taskGraphT;
5809 HpcOmTaskGraph.TaskGraphMeta taskGraphData;
5810 array<tuple<Integer,Integer,Integer>> varCompMapping;
5811 array<tuple<Integer,Integer,Integer>> eqCompMapping;
5812
5813 array<list<Integer>> mapEqnIncRow;
5814 array<Integer> mapIncRowEqn;
5815 Integer systemNumber=0, numberOfSystems;
5816
5817 list<Integer> eqIndLst, eqIndexLst = {};
5818 UnorderedMap<DAE.ComponentRef, DAE.Exp> der_replacement;
5819 BackendDAE.Var derVar;
5820
5821 constant Boolean debug = false;
5822 algorithm
5823 daeOut := daeIn;
5824
5825 1 BackendDAE.DAE(systs,shared) := daeIn;
5826 1 BackendDAE.SHARED(functionTree = funcTree) := shared;
5827 systsNew := {};
5828 //traverse the simulation-DAE systems
5829 1 numberOfSystems := listLength(systs);
5830
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 time.
5 for syst in systs loop
5831 systemNumber := systemNumber+1;
5832 4 BackendDAE.EQSYSTEM(orderedVars = vars, orderedEqs=eqs, matching=matching) := syst;
5833
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 BackendDAE.MATCHING(ass1=ass1, ass2=ass2, comps=comps) := matching;
5834
5835 // get taskgraph and transposed taskgraph for simulation eqsystem
5836 4 (taskGraph,taskGraphData) := HpcOmTaskGraph.getEmptyTaskGraph(0,0,0);
5837 4 (taskGraph,taskGraphData,_) := HpcOmTaskGraph.createTaskGraph0(syst,shared,false,(taskGraph,taskGraphData,1));
5838
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 HpcOmTaskGraph.TASKGRAPHMETA(varCompMapping=varCompMapping, eqCompMapping=eqCompMapping) := taskGraphData;
5839 size := arrayLength(taskGraph);
5840 4 taskGraphT := AdjacencyMatrix.transposeAdjacencyMatrix(taskGraph,size);
5841
5842 //get output variables
5843 4 BackendDAE.EQSYSTEM(orderedVars = vars) := syst;
5844 4 varLst := BackendVariable.varList(vars);
5845 4 varLst := List.filterOnTrue(varLst,BackendVariable.isVarOnTopLevelAndOutput);
5846
5847
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 3 times.
4 if not listEmpty(varLst) then
5848
5849 //THIS SYSTEM CONTAINS OUTPUT VARIABLES
5850 //-------------------------------------
5851 1 outputVarIndxs := BackendVariable.getVarIndexFromVars(varLst,vars);
5852 1 outputTasks := List.map(List.map1(outputVarIndxs,Array.getIndexFirst,varCompMapping),Util.tuple31);
5853 if debug then print("outputTasks "+stringDelimitList(List.map(outputTasks,intString),", ")+"\n"); end if;
5854
5855 //get all necessary components to calculate the outputs
5856 1 predecessors := HpcOmTaskGraph.getAllSuccessors(outputTasks,taskGraphT);
5857 1 predecessors := List.sort(predecessors,intGt);
5858 1 compsNew := List.map1(listAppend(outputTasks,predecessors),List.getIndexFirst,comps);
5859 if debug then print("predecessors of outputs "+stringDelimitList(List.map(predecessors,intString),", ")+"\n"); end if;
5860
5861 //get equations from the new reduced set of comps
5862 1 eqLstNew := BackendDAEUtil.getStrongComponentEquations(compsNew,eqs,vars);
5863
5864 // Get all state-variables which are needed in these equations and apply the same search for these equations.
5865 // The according state-derivatives have to be computed.
5866 stateTasks := {};
5867 1 varVisited := arrayCreate(BackendVariable.varsSize(vars),-1);
5868
2/2
✓ Branch 0 taken 178 times.
✓ Branch 1 taken 1 time.
179 while not listEmpty(eqLstNew) loop
5869 178 eq::eqLstNew := eqLstNew;
5870 if debug then print("eq: "+BackendDump.equationString(eq)+"\n"); end if;
5871 178 crefs := BackendEquation.equationCrefs(eq);
5872 178 crefs := List.filter1OnTrue(crefs,BackendVariable.isState,vars);
5873 178 (states,stateIndxs) := BackendVariable.getVarLst(crefs,vars);
5874 178 (stateIndxs,states) := List.filter1OnTrueSync(stateIndxs,stateVarIsNotVisited,varVisited,states);//not yet visited
5875
2/2
✓ Branch 0 taken 176 times.
✓ Branch 1 taken 2 times.
178 if not listEmpty(stateIndxs) then
5876 if debug then print("states "+stringDelimitList(List.map(states,BackendDump.varString),"\n ")+"\n"); end if;
5877 2 List.map2_0(stateIndxs,Array.updateIndexFirst,1,varVisited);
5878 //add the new tasks which are necessary for the states
5879 2 stateTasks1 := List.map(List.map1(stateIndxs,Array.getIndexFirst,varCompMapping),Util.tuple31);
5880 2 stateTasks := List.append_reverse(stateTasks1,stateTasks);
5881 //get their predecessor tasks, the corresponding comps and add their equations
5882 2 predecessors := HpcOmTaskGraph.getAllSuccessors(stateTasks1,taskGraphT);
5883 2 addComps := List.map1(listAppend(stateTasks1,predecessors),List.getIndexFirst,comps);
5884 2 eqLstNew := listAppend(BackendDAEUtil.getStrongComponentEquations(addComps,eqs,vars), eqLstNew);
5885 end if;
5886 end while;
5887 1 stateTasks := Dangerous.listReverseInPlace(stateTasks);
5888
5889 //get all necessary components to calculate the outputs and the state derivatives
5890 1 predecessors := HpcOmTaskGraph.getAllSuccessors(listAppend(outputTasks,stateTasks),taskGraphT);
5891 1 tasks := List.sort(listAppend(predecessors,listAppend(outputTasks,stateTasks)),intGt);
5892 if debug then print("predecessors of outputs and states "+stringDelimitList(List.map(tasks,intString),", ")+"\n"); end if;
5893 1 compsNew := List.map1(tasks,List.getIndexFirst,comps);
5894 1 compsNew := List.unique(compsNew);
5895 if debug then print("There have been "+intString(listLength(comps))+" SCCs and now there are "+intString(listLength(compsNew))+" SCCs.\n"); end if;
5896
5897 //get vars and equations from the new reduced set of comps and make a equationIdxMap
5898 eqLstNew := {};
5899 varLstNew := {};
5900
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 1 time.
67 for comp in compsNew loop
5901 66 (varLst,_,eqLst,eqIndLst) := BackendDAEUtil.getStrongComponentVarsAndEquations(comp,vars,eqs);
5902 66 varLstNew := listAppend(varLst,varLstNew);
5903 66 eqLstNew := listAppend(eqLst,eqLstNew);
5904 66 eqIndexLst := listAppend(eqIndLst,eqIndexLst);
5905 end for;
5906
5907 // causalize again
5908 1 syst.orderedVars := BackendVariable.listVar1(listReverse(varLstNew));
5909 syst.orderedEqs := BackendEquation.listEquation(listReverse(eqLstNew));
5910
5911 syst.m := NONE();
5912 syst.mT := NONE();
5913 syst.matching := BackendDAE.NO_MATCHING();
5914 1 (m,mT) := BackendDAEUtil.adjacencyMatrix(syst,BackendDAE.NORMAL(),NONE(),BackendDAEUtil.isInitializationDAE(shared));
5915 1 syst.m := SOME(m);
5916 syst.mT := SOME(mT);
5917 1 nVars := listLength(varLstNew);
5918 1 nEqs := listLength(eqLstNew);
5919 1 ass1 := arrayCreate(nVars, -1);
5920 1 ass2 := arrayCreate(nEqs, -1);
5921 1 Matching.matchingExternalsetAdjacencyMatrix(nVars, nEqs, m);
5922 1 BackendDAEEXT.matching(nVars, nEqs, 5, -1, 0.0, 1);
5923 1 BackendDAEEXT.getAssignment(ass2, ass1);
5924 1 matching := BackendDAE.MATCHING(ass1,ass2,compsNew);
5925 1 syst.matching := matching;
5926
5927 2 (syst, _, _, mapEqnIncRow, mapIncRowEqn) := BackendDAEUtil.getAdjacencyMatrixScalar(syst, BackendDAE.NORMAL(), SOME(funcTree), BackendDAEUtil.isInitializationDAE(shared));
5928 1 syst := BackendDAETransform.strongComponentsScalar(syst,shared,mapEqnIncRow,mapIncRowEqn);
5929 1 syst.removedEqs := BackendEquation.emptyEqns();
5930
5931 systsNew := syst::systsNew;
5932
5933 // find unneeded vars and equations
5934 1 vars := BackendVariable.deleteVars(syst.orderedVars, vars);
5935 1 eqs := BackendEquation.deleteList(eqs, eqIndexLst);
5936 else
5937 if debug then print("No output variables in this system ("+intString(systemNumber)+"/"+intString(numberOfSystems)+")\n"); end if;
5938 end if;
5939
5940 // make unneeded state derivatives and add them to unneeded vars
5941 4 der_replacement := UnorderedMap.new<DAE.Exp>(ComponentReferenceBasics.hashComponentRef, ComponentReferenceBasics.crefEqual);
5942
2/2
✓ Branch 1 taken 163 times.
✓ Branch 2 taken 4 times.
167 for state in BackendVariable.varList(vars) loop
5943
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 163 times.
163 if BackendVariable.isStateVar(state) then
5944 ✗ derVar := BackendVariable.makeVar(ComponentReference.prependStringCref("$DER_REM_", state.varName));
5945 ✗ UnorderedMap.add(state.varName, Expression.crefExp(derVar.varName), der_replacement);
5946 ✗ vars := BackendVariable.addVar(derVar, vars);
5947 end if;
5948 end for;
5949
5950 // replace unneeded der() calls with derivative crefs
5951 4 eqs := BackendEquation.traverseEquationArray_WithUpdate(eqs, function BackendEquation.traverseExpsOfEquation(inFunc = replaceDerCallOutputsOnly), der_replacement);
5952
5953 // make unneeded vars parameters and equations initial equations
5954 4 (vars, _) := BackendVariable.traverseBackendDAEVarsWithUpdate(vars, BackendVariable.makeParamOutputsOnly, false);
5955 4 (eqs, _) := BackendEquation.traverseEquationArray_WithUpdate(eqs,BackendEquation.setEquationKind, BackendDAE.INITIAL_EQUATION());
5956
5957 // add unneeded variables and equations
5958 4 shared.globalKnownVars := BackendVariable.addVariables(vars, shared.globalKnownVars);
5959 shared.initialEqs := BackendEquation.addList(BackendEquation.equationList(eqs), shared.initialEqs);
5960 end for;
5961
5962 // alias vars are not necessary anymore
5963 1 shared.aliasVars := BackendVariable.emptyVars();
5964 1 daeOut := BackendDAE.DAE(systsNew,shared);
5965 end evaluateOutputsOnly;
5966
5967 protected function stateVarIsNotVisited"checks if the indexed entry in the array is less than 0"
5968 input Integer idx;
5969 input array<Integer> varArr;
5970 output Boolean b;
5971 algorithm
5972 16 b := intLt(arrayGet(varArr,idx),0);
5973 end stateVarIsNotVisited;
5974
5975 protected function replaceDerCallOutputsOnly
5976 input output DAE.Exp exp;
5977 input output UnorderedMap<DAE.ComponentRef, DAE.Exp> der_replacement;
5978 algorithm
5979 exp := match exp
5980 local
5981 DAE.ComponentRef cr;
5982 case DAE.CALL(path = Absyn.IDENT("der"), expLst = {DAE.CREF(cr)})
5983 ✗ then UnorderedMap.getOrDefault(cr, der_replacement, exp);
5984 else exp;
5985 end match;
5986 end replaceDerCallOutputsOnly;
5987
5988 // =============================================================================
5989 // section for initOptModule >>inlineHomotopy<<
5990 //
5991 // =============================================================================
5992
5993 public function inlineHomotopy
5994 input BackendDAE.BackendDAE inDAE;
5995 output BackendDAE.BackendDAE outDAE = inDAE;
5996 protected
5997 BackendDAE.EquationArray orderedEqs;
5998 Boolean foundHomotopy;
5999 algorithm
6000
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 for syst in inDAE.eqs loop
6001 4 orderedEqs := syst.orderedEqs;
6002 4 (orderedEqs, foundHomotopy) := BackendEquation.traverseEquationArray_WithUpdate(orderedEqs, inlineHomotopy2, false);
6003 4 syst.orderedEqs := orderedEqs;
6004 end for;
6005 end inlineHomotopy;
6006
6007 protected function inlineHomotopy2
6008 input BackendDAE.Equation inEq;
6009 input Boolean inFoundHomotopy;
6010 output BackendDAE.Equation outEq;
6011 output Boolean outFoundHomotopy = inFoundHomotopy;
6012 algorithm
6013
3/4
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 22 times.
✓ Branch 3 taken 41 times.
✗ Branch 4 not taken.
60 (outEq, outFoundHomotopy) := BackendEquation.traverseExpsOfEquation(inEq, inlineHomotopy3, inFoundHomotopy);
6014 end inlineHomotopy2;
6015
6016 protected function inlineHomotopy3
6017 input DAE.Exp inExp;
6018 input Boolean inFoundHomotopy;
6019 output DAE.Exp outExp;
6020 output Boolean outFoundHomotopy = inFoundHomotopy;
6021 algorithm
6022
3/4
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 46 times.
✓ Branch 3 taken 82 times.
✗ Branch 4 not taken.
118 (outExp, outFoundHomotopy) := Expression.traverseExpTopDown(inExp, replaceHomotopyWithLambdaExpression, inFoundHomotopy);
6023 end inlineHomotopy3;
6024
6025 protected function replaceHomotopyWithLambdaExpression
6026 input DAE.Exp inExp;
6027 input Boolean inFoundHomotopy;
6028 output DAE.Exp outExp = inExp;
6029 output Boolean cont = true;
6030 output Boolean outFoundHomotopy;
6031 algorithm
6032 outFoundHomotopy := match inExp
6033 local
6034 DAE.Exp actual, simplified, lambda;
6035
6036 case DAE.CALL(path=Absyn.IDENT("homotopy"), expLst={actual,simplified})
6037 algorithm
6038 8 lambda := Expression.crefExp(ComponentReferenceBasics.makeCrefIdent(BackendDAE.homotopyLambda, DAE.T_REAL_DEFAULT, {}));
6039 8 outExp := DAE.BINARY(DAE.BINARY(simplified, DAE.MUL(DAE.T_REAL_DEFAULT), DAE.BINARY(DAE.RCONST(1.0), DAE.SUB(DAE.T_REAL_DEFAULT), lambda)), DAE.ADD(DAE.T_REAL_DEFAULT), DAE.BINARY(actual, DAE.MUL(DAE.T_REAL_DEFAULT), lambda));
6040 then true;
6041
6042 else inFoundHomotopy;
6043 end match;
6044 end replaceHomotopyWithLambdaExpression;
6045
6046 // =============================================================================
6047 // section for initOptModule >>generateHomotopyComponents<<
6048 //
6049 // =============================================================================
6050
6051 public function generateHomotopyComponents " finds the smallest homotopy loop and creates a component out of it
6052 author: ptaeuber 2017"
6053 input BackendDAE.BackendDAE inDAE;
6054 output BackendDAE.BackendDAE outDAE = inDAE;
6055 protected
6056 BackendDAE.StrongComponents comps;
6057 BackendDAE.EqSystems newEqSystems={};
6058 array<Integer> ass1, ass2;
6059 algorithm
6060
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 if Config.adaptiveHomotopy() then
6061
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 for syst in outDAE.eqs loop
6062
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 BackendDAE.MATCHING(ass1=ass1, ass2=ass2, comps=comps) := syst.matching;
6063
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
4 if Config.globalHomotopy() then
6064 2 (comps, syst) := traverseStrongComponentsForHomotopyLoop(comps, syst);
6065 else
6066 2 (comps, syst) := traverseStrongComponentsAddLambda(comps, syst);
6067 end if;
6068 8 syst.matching := BackendDAE.MATCHING(ass1=ass1, ass2=ass2, comps=comps);
6069 newEqSystems := syst::newEqSystems;
6070 end for;
6071 4 outDAE.eqs := listReverse(newEqSystems);
6072 else
6073 ✗ Error.addCompilerWarning("InitOptModule generateHomotopyComponents is activated for an equidistant homotopy method and will therefore be ignored.");
6074 end if;
6075 end generateHomotopyComponents;
6076
6077 protected function traverseStrongComponentsForHomotopyLoop " traverses all the strong components and finds the smallest homotopy loop
6078 author: ptaeuber 2017"
6079 input output BackendDAE.StrongComponents comps;
6080 input output BackendDAE.EqSystem system;
6081 protected
6082 Integer nComps, compIndex=0, homotopyLoopBeginning=0, homotopyLoopEnd=0;
6083 BackendDAE.StrongComponents preHomotopyComponents, homotopyComponents, postHomotopyComponents;
6084 BackendDAE.StrongComponent homotopyComponent;
6085 BackendDAE.Var lambda;
6086 Integer lambdaIdx;
6087 algorithm
6088 2 nComps := listLength(comps);
6089
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 2 times.
15 for comp in comps loop
6090
2/9
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
13 compIndex := compIndex + 1;
6091 () := match comp
6092 local
6093 Integer eqnIndex;
6094 list<Integer> eqnIndexes, resEqnIndexes, innerEqnIndexes;
6095 BackendDAE.InnerEquations innerEquations;
6096 BackendDAE.Equation eqn;
6097 list<BackendDAE.Equation> eqnLst;
6098 Boolean hasHomotopy;
6099
6100 case BackendDAE.SINGLEEQUATION(eqn=eqnIndex)
6101 algorithm
6102 9 eqn := BackendEquation.get(system.orderedEqs, eqnIndex);
6103 9 (_, hasHomotopy) := BackendEquation.traverseExpsOfEquation(eqn, BackendDAEUtil.containsHomotopyCall, false);
6104
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7 times.
9 if hasHomotopy then
6105 homotopyLoopEnd := compIndex;
6106
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (homotopyLoopBeginning == 0) then
6107 homotopyLoopBeginning := compIndex;
6108 end if;
6109 end if;
6110 then();
6111
6112 case BackendDAE.EQUATIONSYSTEM(eqns=eqnIndexes)
6113 algorithm
6114 ✗ if (homotopyLoopBeginning == 0) then
6115 ✗ eqnLst := BackendEquation.getList(eqnIndexes, system.orderedEqs);
6116 ✗ (_, hasHomotopy) := BackendEquation.traverseExpsOfEquationList(eqnLst, BackendDAEUtil.containsHomotopyCall, false);
6117
6118 ✗ if hasHomotopy then
6119 homotopyLoopBeginning := compIndex;
6120 homotopyLoopEnd := compIndex;
6121 end if;
6122 else
6123 homotopyLoopEnd := compIndex;
6124 end if;
6125 then();
6126
6127 case BackendDAE.SINGLEARRAY(eqn=eqnIndex)
6128 algorithm
6129 ✗ eqn := BackendEquation.get(system.orderedEqs, eqnIndex);
6130 ✗ (_, hasHomotopy) := BackendEquation.traverseExpsOfEquation(eqn, BackendDAEUtil.containsHomotopyCall, false);
6131
6132 ✗ if hasHomotopy then
6133 homotopyLoopEnd := compIndex;
6134 ✗ if (homotopyLoopBeginning == 0) then
6135 homotopyLoopBeginning := compIndex;
6136 end if;
6137 end if;
6138 then();
6139
6140 case BackendDAE.SINGLEALGORITHM(eqn=eqnIndex)
6141 algorithm
6142 ✗ eqn := BackendEquation.get(system.orderedEqs, eqnIndex);
6143 ✗ (_, hasHomotopy) := BackendEquation.traverseExpsOfEquation(eqn, BackendDAEUtil.containsHomotopyCall, false);
6144
6145 ✗ if hasHomotopy then
6146 homotopyLoopEnd := compIndex;
6147 ✗ if (homotopyLoopBeginning == 0) then
6148 homotopyLoopBeginning := compIndex;
6149 end if;
6150 end if;
6151 then();
6152
6153 case BackendDAE.SINGLECOMPLEXEQUATION(eqn=eqnIndex)
6154 algorithm
6155 ✗ eqn := BackendEquation.get(system.orderedEqs, eqnIndex);
6156 ✗ (_, hasHomotopy) := BackendEquation.traverseExpsOfEquation(eqn, BackendDAEUtil.containsHomotopyCall, false);
6157
6158 ✗ if hasHomotopy then
6159 homotopyLoopEnd := compIndex;
6160 ✗ if (homotopyLoopBeginning == 0) then
6161 homotopyLoopBeginning := compIndex;
6162 end if;
6163 end if;
6164 then();
6165
6166 case BackendDAE.SINGLEWHENEQUATION(eqn=eqnIndex)
6167 algorithm
6168 ✗ eqn := BackendEquation.get(system.orderedEqs, eqnIndex);
6169 ✗ (_, hasHomotopy) := BackendEquation.traverseExpsOfEquation(eqn, BackendDAEUtil.containsHomotopyCall, false);
6170
6171 ✗ if hasHomotopy then
6172 homotopyLoopEnd := compIndex;
6173 ✗ if (homotopyLoopBeginning == 0) then
6174 homotopyLoopBeginning := compIndex;
6175 end if;
6176 end if;
6177 then();
6178
6179 case BackendDAE.SINGLEIFEQUATION(eqn=eqnIndex)
6180 algorithm
6181 ✗ eqn := BackendEquation.get(system.orderedEqs, eqnIndex);
6182 ✗ (_, hasHomotopy) := BackendEquation.traverseExpsOfEquation(eqn, BackendDAEUtil.containsHomotopyCall, false);
6183
6184 ✗ if hasHomotopy then
6185 homotopyLoopEnd := compIndex;
6186 ✗ if (homotopyLoopBeginning == 0) then
6187 homotopyLoopBeginning := compIndex;
6188 end if;
6189 end if;
6190 then();
6191
6192 case BackendDAE.TORNSYSTEM(strictTearingSet=BackendDAE.TEARINGSET(residualequations=resEqnIndexes, innerEquations=innerEquations))
6193 algorithm
6194
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 3 times.
4 if (homotopyLoopBeginning == 0) then
6195 1 eqnLst := BackendEquation.getList(resEqnIndexes, system.orderedEqs);
6196 1 (_, hasHomotopy) := BackendEquation.traverseExpsOfEquationList(eqnLst, BackendDAEUtil.containsHomotopyCall, false);
6197
6198
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 if not hasHomotopy then
6199 1 (innerEqnIndexes,_,_) := List.map_3(innerEquations, BackendDAEUtil.getEqnAndVarsFromInnerEquation);
6200 1 eqnLst := BackendEquation.getList(innerEqnIndexes, system.orderedEqs);
6201 1 (_, hasHomotopy) := BackendEquation.traverseExpsOfEquationList(eqnLst, BackendDAEUtil.containsHomotopyCall, false);
6202 end if;
6203
6204
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if hasHomotopy then
6205 homotopyLoopBeginning := compIndex;
6206 homotopyLoopEnd := compIndex;
6207 end if;
6208 else
6209 homotopyLoopEnd := compIndex;
6210 end if;
6211 then();
6212 end match;
6213 end for;
6214
6215
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if homotopyLoopBeginning > 0 then
6216 // Add homotopy lambda to system
6217 2 lambda := BackendDAE.VAR(ComponentReferenceBasics.makeCrefIdent(BackendDAE.homotopyLambda, DAE.T_REAL_DEFAULT, {}), BackendDAE.VARIABLE(), DAE.BIDIR(), DAE.NON_PARALLEL(), DAE.T_REAL_DEFAULT, NONE(), NONE(), {}, DAE.emptyElementSource, NONE(), NONE(), NONE(), NONE(), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER(), true, false, false);
6218 2 system.orderedVars := BackendVariable.addVar(lambda, system.orderedVars);
6219 2 lambdaIdx := BackendVariable.varsSize(system.orderedVars);
6220
6221 2 (preHomotopyComponents, homotopyComponents, postHomotopyComponents) := getHomotopyComponents(List.intRange(nComps), comps, homotopyLoopBeginning, homotopyLoopEnd);
6222
6223 2 homotopyComponent := createOneHomotopyComponent(homotopyComponents, system, lambdaIdx);
6224
6225 2 comps := homotopyComponent::postHomotopyComponents;
6226 2 comps := listAppend(preHomotopyComponents, comps);
6227 end if;
6228 end traverseStrongComponentsForHomotopyLoop;
6229
6230
6231 protected function getHomotopyComponents " divides the components into pre-homotopy, homotopy and post-homotopy parts
6232 author: ptaeuber 2017"
6233 input list<Integer> componentIndexes;
6234 input BackendDAE.StrongComponents components;
6235 input Integer homotopyLoopBeginning;
6236 input Integer homotopyLoopEnd;
6237 input output BackendDAE.StrongComponents outPreHomotopyComponents = {};
6238 input output BackendDAE.StrongComponents outHomotopyComponents = {};
6239 input output BackendDAE.StrongComponents outPostHomotopyComponents = {};
6240 algorithm
6241 (outPreHomotopyComponents, outHomotopyComponents, outPostHomotopyComponents) := match(componentIndexes, components)
6242 local
6243 Integer i;
6244 list<Integer> indexes;
6245 BackendDAE.StrongComponent comp;
6246 BackendDAE.StrongComponents comps;
6247
6248 case(i::{}, comp::{})
6249 algorithm
6250
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if intLt(i, homotopyLoopBeginning) then
6251 outPreHomotopyComponents := comp::outPreHomotopyComponents;
6252 elseif intGt(i, homotopyLoopEnd) then
6253 outPostHomotopyComponents := comp::outPostHomotopyComponents;
6254 else
6255 outHomotopyComponents := comp::outHomotopyComponents;
6256 end if;
6257 2 then (listReverse(outPreHomotopyComponents), listReverse(outHomotopyComponents), listReverse(outPostHomotopyComponents));
6258
6259 case(i::indexes, comp::comps)
6260 algorithm
6261
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 7 times.
11 if intLt(i, homotopyLoopBeginning) then
6262 outPreHomotopyComponents := comp::outPreHomotopyComponents;
6263 elseif intGt(i, homotopyLoopEnd) then
6264 outPostHomotopyComponents := comp::outPostHomotopyComponents;
6265 else
6266 outHomotopyComponents := comp::outHomotopyComponents;
6267 end if;
6268 11 then getHomotopyComponents(indexes, comps, homotopyLoopBeginning, homotopyLoopEnd, outPreHomotopyComponents, outHomotopyComponents, outPostHomotopyComponents);
6269 end match;
6270 end getHomotopyComponents;
6271
6272 protected function createOneHomotopyComponent " creates one BackendDAE.TORNSYSTEM out of all homotopy components
6273 author: ptaeuber 2017"
6274 input BackendDAE.StrongComponents homotopyComponents;
6275 input BackendDAE.EqSystem inSystem;
6276 input Integer lambdaIdx;
6277 output BackendDAE.StrongComponent outHomotopyComponent;
6278 protected
6279 BackendDAE.InnerEquations newInnerEquations = {};
6280 list<Integer> newResEquations = {};
6281 list<Integer> newIterationVars = {};
6282 Boolean isMixed = false;
6283 algorithm
6284
4/11
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 7 times.
✓ Branch 10 taken 2 times.
9 for comp in homotopyComponents loop
6285 (newInnerEquations, newResEquations, newIterationVars) := match comp
6286 local
6287 Integer eqnIndex, varIndex;
6288 list<Integer> eqnIndexes, varIndexes, resEqnIndexes, tVarIndexes;
6289 BackendDAE.InnerEquations innerEquations;
6290 BackendDAE.InnerEquation newInnerEquation;
6291 Boolean mixedSystem;
6292
6293 case BackendDAE.SINGLEEQUATION(eqn=eqnIndex, var=varIndex)
6294 algorithm
6295 4 newInnerEquation := BackendDAE.INNEREQUATION(eqn=eqnIndex, vars={varIndex});
6296 then (newInnerEquation::newInnerEquations, newResEquations, newIterationVars);
6297
6298 case BackendDAE.EQUATIONSYSTEM(eqns=eqnIndexes, vars=varIndexes, mixedSystem=mixedSystem)
6299 algorithm
6300 ✗ if mixedSystem then
6301 isMixed := true;
6302 end if;
6303 ✗ then (newInnerEquations, listAppend(newResEquations, eqnIndexes), listAppend(newIterationVars, varIndexes));
6304
6305 case BackendDAE.SINGLEARRAY(eqn=eqnIndex, vars=varIndexes)
6306 algorithm
6307 ✗ newInnerEquation := BackendDAE.INNEREQUATION(eqn=eqnIndex, vars=varIndexes);
6308 then (newInnerEquation::newInnerEquations, newResEquations, newIterationVars);
6309
6310 case BackendDAE.SINGLEALGORITHM(eqn=eqnIndex, vars=varIndexes)
6311 algorithm
6312 ✗ newInnerEquation := BackendDAE.INNEREQUATION(eqn=eqnIndex, vars=varIndexes);
6313 then (newInnerEquation::newInnerEquations, newResEquations, newIterationVars);
6314
6315 case BackendDAE.SINGLECOMPLEXEQUATION(eqn=eqnIndex, vars=varIndexes)
6316 algorithm
6317 ✗ newInnerEquation := BackendDAE.INNEREQUATION(eqn=eqnIndex, vars=varIndexes);
6318 then (newInnerEquation::newInnerEquations, newResEquations, newIterationVars);
6319
6320 case BackendDAE.SINGLEWHENEQUATION(eqn=eqnIndex, vars=varIndexes)
6321 algorithm
6322 ✗ newInnerEquation := BackendDAE.INNEREQUATION(eqn=eqnIndex, vars=varIndexes);
6323 then (newInnerEquation::newInnerEquations, newResEquations, newIterationVars);
6324
6325 case BackendDAE.SINGLEIFEQUATION(eqn=eqnIndex, vars=varIndexes)
6326 algorithm
6327 ✗ newInnerEquation := BackendDAE.INNEREQUATION(eqn=eqnIndex, vars=varIndexes);
6328 then (newInnerEquation::newInnerEquations, newResEquations, newIterationVars);
6329
6330 case BackendDAE.TORNSYSTEM(strictTearingSet=BackendDAE.TEARINGSET(residualequations=resEqnIndexes, tearingvars=tVarIndexes, innerEquations=innerEquations), mixedSystem=mixedSystem)
6331 algorithm
6332
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if mixedSystem then
6333 isMixed := true;
6334 end if;
6335
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 3 times.
9 for innerEquation in innerEquations loop
6336 newInnerEquations := innerEquation::newInnerEquations;
6337 end for;
6338 3 then (newInnerEquations, listAppend(newResEquations, resEqnIndexes), listAppend(newIterationVars, tVarIndexes));
6339 end match;
6340 end for;
6341
6342
1/2
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
4 outHomotopyComponent := BackendDAE.TORNSYSTEM(BackendDAE.TEARINGSET(listAppend(newIterationVars,{lambdaIdx}), newResEquations, listReverse(newInnerEquations), BackendDAE.EMPTY_JACOBIAN()), NONE(), false, isMixed);
6343 end createOneHomotopyComponent;
6344
6345 protected function traverseStrongComponentsAddLambda " traverses all the strong components and adds lambda as the last variable if the system contains homotopy
6346 author: ptaeuber 2017"
6347 input output BackendDAE.StrongComponents comps;
6348 input output BackendDAE.EqSystem system;
6349 protected
6350 BackendDAE.StrongComponents newComps={};
6351 BackendDAE.Var lambda;
6352 Integer lambdaIdx;
6353 Boolean hasAnyHomotopy = false;
6354 algorithm
6355 2 lambdaIdx := BackendVariable.varsSize(system.orderedVars) + 1;
6356
6357
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 2 times.
13 for comp in comps loop
6358 comp := match comp
6359 local
6360 list<Integer> eqnIndexes, varIndexes, resEqnIndexes, tVarIndexes, innerEqnIndexes;
6361 Option<BackendDAE.TearingSet> casualTearingSet;
6362 BackendDAE.InnerEquations innerEquations;
6363 BackendDAE.Jacobian jac;
6364 BackendDAE.JacobianType jacType;
6365 list<BackendDAE.Equation> eqnLst;
6366 Boolean linear, mixedSystem, hasHomotopy;
6367
6368 case BackendDAE.EQUATIONSYSTEM(eqns=eqnIndexes, vars=varIndexes, jac=jac, jacType=jacType, mixedSystem=mixedSystem)
6369 algorithm
6370 ✗ eqnLst := BackendEquation.getList(eqnIndexes, system.orderedEqs);
6371 ✗ (_, hasHomotopy) := BackendEquation.traverseExpsOfEquationList(eqnLst, BackendDAEUtil.containsHomotopyCall, false);
6372
6373 ✗ if hasHomotopy then
6374 hasAnyHomotopy := true;
6375 // Add lambda in front of the list, list seems to be reversed later for EQUATIONSYSTEM
6376 ✗ comp := BackendDAE.EQUATIONSYSTEM(eqnIndexes, lambdaIdx::varIndexes, jac, jacType, mixedSystem);
6377 end if;
6378 then comp;
6379
6380 case BackendDAE.TORNSYSTEM(strictTearingSet=BackendDAE.TEARINGSET(residualequations=resEqnIndexes, tearingvars=tVarIndexes, innerEquations=innerEquations, jac=jac), casualTearingSet=casualTearingSet, linear=linear, mixedSystem=mixedSystem)
6381 algorithm
6382 5 eqnLst := BackendEquation.getList(resEqnIndexes, system.orderedEqs);
6383 5 (_, hasHomotopy) := BackendEquation.traverseExpsOfEquationList(eqnLst, BackendDAEUtil.containsHomotopyCall, false);
6384
6385
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 time.
5 if not hasHomotopy then
6386 4 (innerEqnIndexes,_,_) := List.map_3(innerEquations, BackendDAEUtil.getEqnAndVarsFromInnerEquation);
6387 4 eqnLst := BackendEquation.getList(innerEqnIndexes, system.orderedEqs);
6388 4 (_, hasHomotopy) := BackendEquation.traverseExpsOfEquationList(eqnLst, BackendDAEUtil.containsHomotopyCall, false);
6389 end if;
6390
6391
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
5 if hasHomotopy then
6392 hasAnyHomotopy := true;
6393
2/4
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
6 comp := BackendDAE.TORNSYSTEM(BackendDAE.TEARINGSET(listAppend(tVarIndexes, {lambdaIdx}), resEqnIndexes, innerEquations, jac), casualTearingSet, linear, mixedSystem);
6394 end if;
6395 then comp;
6396 else comp;
6397 end match;
6398 newComps := comp::newComps;
6399 end for;
6400
6401
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if hasAnyHomotopy then
6402 // Add homotopy lambda to system
6403 2 lambda := BackendDAE.VAR(ComponentReferenceBasics.makeCrefIdent(BackendDAE.homotopyLambda, DAE.T_REAL_DEFAULT, {}), BackendDAE.VARIABLE(), DAE.BIDIR(), DAE.NON_PARALLEL(), DAE.T_REAL_DEFAULT, NONE(), NONE(), {}, DAE.emptyElementSource, NONE(), NONE(), NONE(), NONE(), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER(), true, false, false);
6404 2 system.orderedVars := BackendVariable.addVar(lambda, system.orderedVars);
6405 end if;
6406 2 comps := listReverse(newComps);
6407 end traverseStrongComponentsAddLambda;
6408
6409 annotation(__OpenModelica_Interface="backend");
6410 end BackendDAEOptimize;
6411