Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 77.4% 692 / 0 / 894
Functions: -% 0 / 1 / 1
Branches: 58.8% 323 / 0 / 549

OMCompiler/Compiler/BackEnd/Initialization.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 Initialization
37 " file: Initialization.mo
38 package: Initialization
39 description: Initialization.mo contains everything needed to set up the
40 BackendDAE for the initial system.
41 "
42
43 public
44 import Absyn;
45 import BackendDAE;
46 import BackendDAEFunc;
47 import DAE;
48 import HashSet;
49 import StringUtil;
50 import UnorderedSet;
51 import Util;
52
53 protected
54 import Array;
55 import BackendDAECreate;
56 import BackendDAEEXT;
57 import BackendDAEOptimize;
58 import BackendDAEUtil;
59 import BackendDump;
60 import BackendEquation;
61 import BackendVariable;
62 import BackendVarTransform;
63 import BaseHashSet;
64 import CheckModel;
65 import ClassInf;
66 import ComponentReference;
67 protected import ComponentReferenceBasics;
68 import Config;
69 import DoubleEnded;
70 import ElementSource;
71 import Error;
72 import ExecStat.execStat;
73 import Expression;
74 import ExpressionBasics;
75 import ExpressionSimplify;
76 import Flags;
77 import GCExt;
78 import IndexReduction;
79 import List;
80 import Matching;
81 import MetaModelica.Dangerous.listReverseInPlace;
82 import Sorting;
83 import SymbolicJacobian;
84 import SynchronousFeatures;
85 import System;
86 import Types;
87
88 // =============================================================================
89 // section for all public functions
90 //
91 // These are functions that can be used to access the initialization.
92 // =============================================================================
93
94 public function solveInitialSystem "author: lochel
95 This function generates a algebraic system of equations for the initialization and solves it."
96 input BackendDAE.BackendDAE inDAE "simulation system";
97 output BackendDAE.BackendDAE outInitDAE "initialization system";
98 output Option<BackendDAE.BackendDAE> outInitDAE_lambda0 "initialization system for lambda=0";
99 output list<BackendDAE.Equation> outRemovedInitialEquations;
100 output BackendDAE.Variables outGlobalKnownVars;
101 output BackendDAE.BackendDAE outSimDAE = inDAE "updated with fixed attribute";
102 protected
103 BackendDAE.BackendDAE dae;
104 BackendDAE.BackendDAE initdae, initdae0;
105 BackendDAE.EqSystem initsyst, initsyst0;
106 BackendDAE.EquationArray eqns, reeqns;
107 list<BackendDAE.Equation> eqnsLst, reeqnsLst;
108 BackendDAE.Shared shared;
109 BackendDAE.Variables initVars;
110 BackendDAE.Variables vars, fixvars;
111 Boolean useHomotopy, datarecon=false;
112 list<String> enabledModules, disabledModules;
113 HashSet.HashSet hs "contains all pre variables";
114 list<BackendDAE.Equation> removedEqns;
115 list<BackendDAE.Var> dumpVars, outAllPrimaryParameters;
116 UnorderedSet<DAE.ComponentRef> allPrimaryParameters;
117 algorithm
118 try
119 //if Flags.isSet(Flags.DUMP_INITIAL_SYSTEM) then
120 // BackendDump.dumpBackendDAE(inDAE, "inDAE for initialization");
121 //end if;
122
123 // inline all when equations, if active with body else with lhs=pre(lhs)
124 1086 dae := inlineWhenForInitialization(inDAE);
125 //if Flags.isSet(Flags.DUMP_INITIAL_SYSTEM) then
126 // BackendDump.dumpBackendDAE(dae, "inlineWhenForInitialization");
127 //end if;
128 1086 execStat("inlineWhenForInitialization (initialization)");
129
130 1086 (dae, initVars, outAllPrimaryParameters, outGlobalKnownVars) := selectInitializationVariablesDAE(dae);
131
132
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1085 times.
1085 if Flags.isSet(Flags.DUMP_INITIAL_SYSTEM) then
133 ✗ BackendDump.dumpVarList(outAllPrimaryParameters, "selected all primary parameters");
134 end if;
135 1085 execStat("selectInitializationVariablesDAE (initialization)");
136
137 1085 hs := collectPreVariables(dae);
138 1085 execStat("collectPreVariables (initialization)");
139
140 // collect vars and eqns for initial system
141 1085 vars := BackendVariable.emptyVars();
142
143 1085 fixvars := BackendVariable.listVar(outAllPrimaryParameters);
144
145 1085 eqns := BackendEquation.emptyEqnsSized(BackendVariable.varsSize(dae.shared.aliasVars)
146 + BackendVariable.varsSize(dae.shared.globalKnownVars)
147 + BackendVariable.varsSize(dae.shared.localKnownVars)
148 + BackendEquation.getNumberOfEquations(dae.shared.initialEqs)
149 + 2*BackendDAEUtil.daeSize(dae));
150 1085 reeqns := BackendEquation.emptyEqnsSized(BackendEquation.getNumberOfEquations(dae.shared.removedEqs));
151
152
4/4
✓ Branch 0 taken 131866 times.
✓ Branch 1 taken 1085 times.
✓ Branch 2 taken 131866 times.
✓ Branch 3 taken 1085 times.
132951 allPrimaryParameters := UnorderedSet.fromList(list(BackendVariable.varCref(v) for v in outAllPrimaryParameters),
153 ComponentReferenceBasics.hashComponentRef, ComponentReferenceBasics.crefEqual);
154 // check for datareconciliation and set the Flag, to set the Qualified Component names as TopLevel Input
155
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1085 times.
✓ Branch 2 taken 26 times.
✓ Branch 3 taken 1059 times.
1085 if isSome(inDAE.shared.dataReconciliationData) then
156 datarecon := true;
157 end if;
158 1085 (vars, fixvars, eqns, _) := BackendVariable.traverseBackendDAEVars(dae.shared.aliasVars, introducePreVarsForAliasVariables, (vars, fixvars, eqns, hs));
159
2/2
✓ Branch 0 taken 1059 times.
✓ Branch 1 taken 26 times.
2144 (vars, fixvars, eqns, _, _, _, _) := BackendVariable.traverseBackendDAEVars(dae.shared.globalKnownVars, collectInitialVars, (vars, fixvars, eqns, arrayCreate(0,0), hs, allPrimaryParameters,datarecon));
160 1085 (vars, fixvars, eqns, _, _, _, _) := BackendVariable.traverseBackendDAEVars(dae.shared.localKnownVars, collectInitialVars, (vars, fixvars, eqns, arrayCreate(0,0), hs, allPrimaryParameters,datarecon));
161 1085 (eqns, reeqns) := BackendEquation.traverseEquationArray(dae.shared.initialEqs, collectInitialEqns, (eqns, reeqns));
162 1085 (eqns, reeqns) := BackendEquation.traverseEquationArray(dae.shared.removedEqs, collectInitialEqns, (eqns, reeqns));
163 //if Flags.isSet(Flags.DUMP_INITIAL_SYSTEM) then
164 // BackendDump.dumpEquationArray(eqns, "initial equations");
165 //end if;
166 1085 execStat("collectInitialEqns (initialization)");
167
168 //((vars, fixvars, eqns, reeqns, _, _)) := List.fold(dae.eqs, collectInitialVarsEqnsSystem, ((vars, fixvars, eqns, reeqns, hs, allPrimaryParameters)));
169 1085 (vars, fixvars, eqns, reeqns) := collectInitialVarsEqnsSystem(dae.eqs, vars, fixvars, eqns, reeqns, hs, allPrimaryParameters, datarecon);
170 1085 (eqns, reeqns) := BackendVariable.traverseBackendDAEVars(vars, collectInitialBindings, (eqns, reeqns));
171 1085 execStat("collectInitialBindings (initialization)");
172
173 // Fix types of constant components in record bindings
174 1085 eqnsLst := BackendEquation.equationList(eqns);
175 1085 reeqnsLst := BackendEquation.equationList(reeqns);
176 1085 (_, eqnsLst, reeqnsLst, _) := BackendDAECreate.patchRecordBindings({}, {}, BackendVariable.varList(dae.shared.globalKnownVars), eqnsLst, reeqnsLst, {});
177 1085 eqns := BackendEquation.listEquation(eqnsLst);
178 1085 reeqns := BackendEquation.listEquation(reeqnsLst);
179
180 // scalarize variables after collecting bindings
181
2/2
✓ Branch 1 taken 1082 times.
✓ Branch 2 taken 3 times.
1085 if Flags.isSet(Flags.NF_SCALARIZE) then
182 1082 vars := BackendVariable.scalarizeVariables(vars);
183 1082 initVars := BackendVariable.scalarizeVariables(initVars);
184 end if;
185
186 // replace initial(), sample(...), delay(...) and homotopy(...)
187 1085 useHomotopy := BackendDAEUtil.traverseBackendDAEExpsEqns(eqns, simplifyInitialFunctions, false);
188 1085 execStat("simplifyInitialFunctions (initialization)");
189
190 1085 vars := BackendVariable.rehashVariables(vars);
191 1085 fixvars := BackendVariable.rehashVariables(fixvars);
192 1085 shared := BackendDAEUtil.createEmptyShared(BackendDAE.INITIALSYSTEM(), dae.shared.info, dae.shared.cache, dae.shared.graph);
193 1085 shared := BackendDAEUtil.setSharedRemovedEqns(shared, BackendEquation.emptyEqns());
194 1085 shared := BackendDAEUtil.setSharedGlobalKnownVars(shared, fixvars);
195 1085 shared := BackendDAEUtil.setSharedOptimica(shared, dae.shared.constraints, dae.shared.classAttrs);
196 1085 shared := BackendDAEUtil.setSharedFunctionTree(shared, dae.shared.functionTree);
197 1085 execStat("setup shared object (initialization)");
198
199 // generate initial system and pre-balance it
200 1085 initsyst := BackendDAEUtil.createEqSystem(vars, eqns);
201 1085 initsyst := BackendDAEUtil.setEqSystRemovedEqns(initsyst, reeqns);
202
203
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 1046 times.
1085 if useHomotopy then
204 39 initsyst0 := BackendDAEUtil.copyEqSystem(initsyst);
205
2/2
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 4 times.
39 enabledModules := if Config.adaptiveHomotopy() then {"inlineHomotopy", "generateHomotopyComponents"} else {};
206 disabledModules := {};
207 else
208 initsyst0 := initsyst;
209 enabledModules := {};
210 disabledModules := {"inlineHomotopy", "generateHomotopyComponents"};
211 end if;
212
213 1085 (initdae, dumpVars, outRemovedInitialEquations) := createInitialDAEFromSystem(initsyst, shared, initVars, enabledModules, disabledModules, outGlobalKnownVars, false);
214
215 // update the fixed attribute in the simulation DAE
216 1085 outSimDAE := BackendVariable.traverseBackendDAE(outSimDAE, updateFixedAttribute, BackendVariable.listVar(dumpVars));
217
218 // compute system for lambda=0
219
4/4
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 1046 times.
✓ Branch 3 taken 35 times.
✓ Branch 4 taken 4 times.
1085 if useHomotopy and Config.globalHomotopy() then
220 35 initsyst0 := replaceHomotopyWithSimplifiedEqs(initsyst0);
221 35 initdae0 := BackendDAE.DAE({initsyst0}, shared);
222 35 initdae0 := BackendDAEUtil.setFunctionTree(initdae0, BackendDAEUtil.getFunctions(initdae.shared));
223 35 (initdae0, _, removedEqns) := createInitialDAEFromSystem(initsyst0, shared, initVars, {}, {"inlineHomotopy", "generateHomotopyComponents"}, outGlobalKnownVars, true);
224 35 outRemovedInitialEquations := listAppend(removedEqns, outRemovedInitialEquations);
225 35 initdae0.shared := BackendDAEUtil.setSharedGlobalKnownVars(initdae0.shared, BackendVariable.emptyVars());
226 outInitDAE_lambda0 := SOME(initdae0);
227 35 initdae := BackendDAEUtil.setFunctionTree(initdae, BackendDAEUtil.getFunctions(initdae0.shared)); // PH: why?
228 else
229 outInitDAE_lambda0 := NONE();
230 end if;
231
232
3/4
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1084 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 time.
1085 if Flags.isSet(Flags.DUMP_EQNINORDER) and Flags.isSet(Flags.DUMP_INITIAL_SYSTEM) then
233 ✗ BackendDump.dumpEqnsSolved(initdae, "initial system: eqns in order");
234 end if;
235
236
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1083 times.
1085 if Flags.isSet(Flags.ITERATION_VARS) then
237 2 BackendDAEOptimize.listAllIterationVariables(initdae);
238 end if;
239
240
4/6
✓ Branch 1 taken 1026 times.
✓ Branch 2 taken 59 times.
✓ Branch 4 taken 1026 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1026 times.
1085 if Flags.isSet(Flags.DUMP_BACKENDDAE_INFO) or Flags.isSet(Flags.DUMP_STATESELECTION_INFO) or Flags.isSet(Flags.DUMP_DISCRETEVARS_INFO) then
241 59 BackendDump.dumpCompShort(initdae);
242 end if;
243
244 outInitDAE := initdae;
245 else
246 1 Error.addCompilerError("No system for the symbolic initialization was generated");
247 1 fail();
248 end try;
249 end solveInitialSystem;
250
251 function createInitialDAEFromSystem
252 input BackendDAE.EqSystem inInitsyst;
253 input BackendDAE.Shared inShared;
254 input BackendDAE.Variables initVars;
255 input list<String> enabledModules;
256 input list<String> disabledModules;
257 input BackendDAE.Variables globalKnownVars;
258 input Boolean isLambda0;
259 output BackendDAE.BackendDAE initdae;
260 output list<BackendDAE.Var> dumpVars;
261 output list<BackendDAE.Equation> removedEqns;
262 protected
263 String systemStr = if isLambda0 then "initialization_lambda0" else "initialization";
264 BackendDAE.Shared shared = inShared;
265 BackendDAE.EqSystem initsyst;
266 list<BackendDAE.EqSystem> systs;
267 list<BackendDAE.Var> dumpVars2;
268 list<tuple<BackendDAEFunc.optimizationModule, String>> initOptModules;
269 tuple<BackendDAEFunc.StructurallySingularSystemHandlerFunc, String, BackendDAEFunc.stateDeselectionFunc, String> daeHandler;
270 tuple<BackendDAEFunc.matchingAlgorithmFunc, String> matchingAlgorithm;
271 Boolean b1, b2;
272 String msg;
273 algorithm
274
275 1120 (initsyst, dumpVars) := preBalanceInitialSystem(inInitsyst, initVars, isLambda0);
276 1120 execStat("preBalanceInitialSystem (" + systemStr + ")");
277
278 1120 initdae := BackendDAE.DAE({initsyst}, shared);
279
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1118 times.
1120 if Flags.isSet(Flags.OPT_DAE_DUMP) then
280 2 BackendDump.dumpBackendDAE(initdae, "created " + systemStr + " system");
281 end if;
282
283 // split the initial system into independend subsystems
284
1/2
✓ Branch 1 taken 1120 times.
✗ Branch 2 not taken.
1120 if Flags.isSet(Flags.PARTITION_INITIALIZATION) then
285 1120 (systs, shared) := BackendDAEOptimize.partitionIndependentBlocksHelper(initsyst, shared, Error.getNumErrorMessages(), true);
286 1120 initdae := BackendDAE.DAE(systs, shared);
287 1120 execStat("partitionIndependentBlocks (" + systemStr + ")");
288 end if;
289
290
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1118 times.
1120 if Flags.isSet(Flags.OPT_DAE_DUMP) then
291 2 BackendDump.dumpBackendDAE(initdae, "partitioned " + systemStr + " system");
292 end if;
293
294 // fix over- and under-constrained subsystems
295 1120 (initdae, dumpVars2, removedEqns) := analyzeInitialSystem(initdae, initVars);
296 1120 dumpVars := listAppend(dumpVars, dumpVars2) annotation(__OpenModelica_DisableListAppendWarning=true);
297 1120 execStat("analyzeInitialSystem (" + systemStr + ")");
298
299 // some debug prints
300
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1120 times.
1120 if Flags.isSet(Flags.DUMP_INITIAL_SYSTEM) then
301 ✗ BackendDump.dumpBackendDAE(initdae, systemStr);
302 end if;
303
304 // now let's solve the system!
305 1120 initdae := BackendDAEUtil.mapEqSystem(initdae, solveInitialSystemEqSystem);
306 1120 execStat("solveInitialSystemEqSystem (" + systemStr + ")");
307
308 // solve system
309 1120 initdae := BackendDAEUtil.transformBackendDAE(initdae, SOME((BackendDAE.NO_INDEX_REDUCTION(), BackendDAE.EXACT())), NONE(), NONE());
310 1120 execStat("matching and sorting (n=" + String(BackendDAEUtil.daeSize(initdae)) + ") (" + systemStr + ")");
311
312 // add initial assignmnents to all algorithms
313 1120 initdae := BackendDAEOptimize.addInitialStmtsToAlgorithms(initdae, true);
314
315 // simplify system
316 1120 initdae := BackendDAEUtil.setDAEGlobalKnownVars(initdae, globalKnownVars);
317
318 1120 initOptModules := BackendDAEUtil.getInitOptModules(NONE(), enabledModules, disabledModules);
319 1120 matchingAlgorithm := BackendDAEUtil.getMatchingAlgorithm(NONE());
320 1120 daeHandler := BackendDAEUtil.getIndexReductionMethod(SOME("none"));
321 1120 initdae := BackendDAEUtil.postOptimizeDAE(initdae, initOptModules, matchingAlgorithm, daeHandler);
322
323
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1120 times.
1120 if Flags.isSet(Flags.DUMP_INITIAL_SYSTEM) then
324 ✗ BackendDump.dumpBackendDAE(initdae, "solved " + systemStr);
325 ✗ if Flags.isSet(Flags.ADDITIONAL_GRAPHVIZ_DUMP) then
326 ✗ BackendDump.graphvizBackendDAE(initdae, "dumpinitialsystem");
327 end if;
328 end if;
329
330 // Remove the globalKnownVars for the initialization set again
331 1120 initdae.shared := BackendDAEUtil.setSharedGlobalKnownVars(initdae.shared, BackendVariable.emptyVars());
332
333 // warn about selected default initial conditions
334 1120 b1 := not listEmpty(dumpVars);
335 1120 b2 := not listEmpty(removedEqns);
336 msg := "For more information set -d=initialization. In OMEdit Tools->Options->Simulation->Show additional information from the initialization process, in OMNotebook call setCommandLineOptions(\"-d=initialization\")";
337
2/2
✓ Branch 1 taken 29 times.
✓ Branch 2 taken 1091 times.
1120 if Flags.isSet(Flags.INITIALIZATION) then
338
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 17 times.
29 if b1 then
339 12 Error.addCompilerWarning("Assuming fixed start value for the following " + intString(listLength(dumpVars)) + " variables:\n" + warnAboutVars2(dumpVars));
340 end if;
341
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 17 times.
29 if b2 then
342 24 Error.addMessage(Error.INITIALIZATION_OVER_SPECIFIED, {"The following " + intString(listLength(removedEqns)) + " initial equations are redundant, so they are removed from the " + systemStr + " system:\n" + warnAboutEqns2(removedEqns)});
343 end if;
344 else
345
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 845 times.
1091 if b1 then
346 246 Error.addMessage(Error.INITIALIZATION_NOT_FULLY_SPECIFIED, {msg});
347 end if;
348
2/2
✓ Branch 0 taken 1088 times.
✓ Branch 1 taken 3 times.
1091 if b2 then
349 3 Error.addMessage(Error.INITIALIZATION_OVER_SPECIFIED, {msg});
350 end if;
351 end if;
352
353 end createInitialDAEFromSystem;
354
355 // =============================================================================
356 // section for helper functions of solveInitialSystem
357 //
358 // =============================================================================
359
360 protected function solveInitialSystemEqSystem "author: lochel
361 This solves the generated system."
362 input BackendDAE.EqSystem isyst;
363 input BackendDAE.Shared inShared;
364 output BackendDAE.EqSystem osyst = isyst;
365 output BackendDAE.Shared outShared = inShared "unused";
366 protected
367 Integer nVars, nEqns;
368 algorithm
369 47563 nEqns := BackendDAEUtil.systemSize(isyst);
370 47563 nVars := BackendVariable.varsSize(BackendVariable.daeVars(isyst));
371
372 // over-determined system: nEqns > nVars
373
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47563 times.
47563 if intGt(nEqns, nVars) then
374 ✗ if Flags.isSet(Flags.INITIALIZATION) then
375 ✗ Error.addCompilerWarning("It was not possible to solve the over-determined initial system (" + intString(nEqns) + " equations and " + intString(nVars) + " variables)");
376 ✗ BackendDump.dumpEqSystem(isyst, "It was not possible to solve the over-determined initial system (" + intString(nEqns) + " equations and " + intString(nVars) + " variables)");
377 end if;
378
379 ✗ fail();
380 end if;
381
382 // under-determined system: nEqns < nVars
383
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47563 times.
47563 if intLt(nEqns, nVars) then
384 ✗ if Flags.isSet(Flags.INITIALIZATION) then
385 ✗ Error.addCompilerWarning("It was not possible to solve the under-determined initial system (" + intString(nEqns) + " equations and " + intString(nVars) + " variables)");
386 ✗ BackendDump.dumpEqSystem(isyst, "It was not possible to solve the under-determined initial system (" + intString(nEqns) + " equations and " + intString(nVars) + " variables)");
387 end if;
388
389 ✗ fail();
390 end if;
391 end solveInitialSystemEqSystem;
392
393 // =============================================================================
394 // section for inlining when-clauses
395 //
396 // This section contains all the helper functions to replace all when-clauses
397 // from a given BackendDAE to get the initial equation system.
398 // =============================================================================
399
400 protected function inlineWhenForInitialization "author: lochel
401 This function inlines when-clauses for the initialization."
402 input BackendDAE.BackendDAE inDAE;
403 output BackendDAE.BackendDAE outDAE = inDAE;
404 protected
405 list<BackendDAE.Equation> eqnlst;
406 list<BackendDAE.Equation> clockEqnsLst;
407 HashSet.HashSet leftCrs = HashSet.emptyHashSet() "dummy hash set - should always be empty";
408 algorithm
409 1086 outDAE.eqs := List.map(inDAE.eqs, inlineWhenForInitializationSystem);
410 1086 (eqnlst, _) := BackendEquation.traverseEquationArray(inDAE.shared.removedEqs, inlineWhenForInitializationEquation, ({}, leftCrs));
411 1086 clockEqnsLst := BackendEquation.traverseEquationArray(inDAE.shared.removedEqs, SynchronousFeatures.getBoolClockWhenClauses, {});
412 1086 eqnlst := listAppend(clockEqnsLst, eqnlst);
413 1086 outDAE.shared := BackendDAEUtil.setSharedRemovedEqns(outDAE.shared, BackendEquation.listEquation(eqnlst));
414 end inlineWhenForInitialization;
415
416 protected function inlineWhenForInitializationSystem "author: lochel"
417 input BackendDAE.EqSystem inEqSystem;
418 output BackendDAE.EqSystem outEqSystem;
419 protected
420 list<BackendDAE.Equation> eqnlst;
421 HashSet.HashSet leftCrs = HashSet.emptyHashSet() "hack for #3209";
422 list<DAE.ComponentRef> crefLst;
423 algorithm
424 1584 (eqnlst, leftCrs) := BackendEquation.traverseEquationArray(inEqSystem.orderedEqs, inlineWhenForInitializationEquation, ({}, leftCrs));
425 1584 crefLst := BaseHashSet.hashSetList(leftCrs);
426 1584 eqnlst := generateInactiveWhenEquationForInitialization(crefLst, DAE.emptyElementSource, eqnlst);
427 1584 outEqSystem := BackendDAEUtil.setEqSystEqs(inEqSystem, BackendEquation.listEquation(eqnlst));
428 1584 outEqSystem := BackendDAEUtil.clearEqSyst(outEqSystem);
429 end inlineWhenForInitializationSystem;
430
431 protected function inlineWhenForInitializationEquation "author: lochel"
432 input BackendDAE.Equation inEq;
433 input tuple<list<BackendDAE.Equation>, HashSet.HashSet> inTpl;
434 output BackendDAE.Equation outEq = inEq;
435 output tuple<list<BackendDAE.Equation>, HashSet.HashSet> outTpl;
436 protected
437 BackendDAE.EquationAttributes eqAttr;
438 BackendDAE.WhenEquation weqn;
439 DAE.Algorithm alg;
440 DAE.ElementSource source;
441 DAE.Expand crefExpand;
442 HashSet.HashSet leftCrs;
443 Integer size;
444 list<BackendDAE.Equation> eqns;
445 list<BackendDAE.Equation> accEq;
446 list<DAE.Statement> stmts;
447 algorithm
448
3/3
✓ Branch 0 taken 442 times.
✓ Branch 1 taken 915 times.
✓ Branch 2 taken 54228 times.
55585 (accEq, leftCrs) := inTpl;
449 outTpl := match inEq
450 // when equation
451 case BackendDAE.WHEN_EQUATION(whenEquation=weqn, source=source, attr=eqAttr) algorithm
452 442 (leftCrs, eqns) := inlineWhenForInitializationWhenEquation(weqn, source, eqAttr, accEq, leftCrs);
453 442 then (eqns, leftCrs);
454
455 // algorithm
456 case BackendDAE.ALGORITHM(alg=alg, source=source, expand=crefExpand) algorithm
457 915 DAE.ALGORITHM_STMTS(statementLst=stmts) := alg;
458 915 (stmts, leftCrs) := inlineWhenForInitializationWhenAlgorithm(stmts, {}, leftCrs);
459 915 alg := DAE.ALGORITHM_STMTS(stmts);
460 915 size := listLength(CheckModel.checkAndGetAlgorithmOutputs(alg, source, crefExpand));
461 915 eqns := List.consOnTrue(not listEmpty(stmts), BackendDAE.ALGORITHM(size, alg, source, crefExpand, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC), accEq);
462 915 then (eqns, leftCrs);
463
464 54228 else (inEq::accEq, leftCrs);
465 end match;
466 end inlineWhenForInitializationEquation;
467
468 protected function inlineWhenForInitializationWhenEquation "author: lochel"
469 input BackendDAE.WhenEquation inWEqn;
470 input DAE.ElementSource inSource;
471 input BackendDAE.EquationAttributes inEqAttr;
472 input list<BackendDAE.Equation> inEqns;
473 input HashSet.HashSet inLeftCrs;
474 output HashSet.HashSet outLeftCrs = inLeftCrs;
475 output list<BackendDAE.Equation> outEqns = inEqns;
476 protected
477 DAE.Exp lhs, condition, e;
478 list<DAE.Exp> eLst;
479 BackendDAE.Equation eqn;
480 list<BackendDAE.WhenOperator> whenStmtLst;
481 DAE.ComponentRef cr;
482 list<DAE.ComponentRef > crefLst;
483 Boolean active;
484 DAE.ElementSource source;
485 algorithm
486 outEqns := match inWEqn
487 case BackendDAE.WHEN_STMTS(condition=condition,whenStmtLst=whenStmtLst) algorithm
488 442 active := Expression.containsInitialCall(condition);
489
2/2
✓ Branch 0 taken 442 times.
✓ Branch 1 taken 442 times.
884 for stmt in whenStmtLst loop
490 () := match stmt
491 case BackendDAE.ASSIGN(left = DAE.CREF(componentRef = cr), right = e) algorithm
492
2/2
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 366 times.
419 if active then
493 53 lhs := Expression.crefExp(cr);
494 53 eqn := BackendEquation.generateEquation(lhs, e, inSource, inEqAttr);
495 outEqns := eqn::outEqns;
496 else
497 366 outLeftCrs := List.fold(ComponentReference.expandCref(cr, true), BaseHashSet.add, outLeftCrs);
498 end if;
499 then ();
500
501 case BackendDAE.ASSIGN(left = lhs as DAE.TUPLE(PR = eLst), right = e) algorithm
502
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if active then
503 ✗ eqn := BackendEquation.generateEquation(lhs, e, inSource, inEqAttr);
504 outEqns := eqn::outEqns;
505 else
506 6 crefLst := List.flatten(List.map(eLst,Expression.getAllCrefs));
507
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
18 for cr in crefLst loop
508 12 outLeftCrs := List.fold(ComponentReference.expandCref(cr, true), BaseHashSet.add, outLeftCrs);
509 end for;
510 end if;
511 then ();
512
513 case BackendDAE.NORETCALL(exp=e, source=source) algorithm
514
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if active then
515 //eqn := BackendEquation.generateEquation(DAE.CREF(DAE.emptyCref, DAE.T_UNKNOWN_DEFAULT), e, inSource, inEqAttr);
516 ✗ eqn := BackendDAE.ALGORITHM(0, DAE.ALGORITHM_STMTS({DAE.STMT_NORETCALL(e, source)}), inSource, DAE.EXPAND(), BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
517 outEqns := eqn::outEqns;
518 end if;
519 then ();
520
521 // Everything else doesn't have to be handled
522 else ();
523 end match;
524 end for;
525 then outEqns;
526 else outEqns;
527 end match;
528 end inlineWhenForInitializationWhenEquation;
529
530 protected function inlineWhenForInitializationWhenAlgorithm "author: lochel
531 This function generates out of a given when-algorithm, a algorithm for the initialization-problem."
532 input list< DAE.Statement> inStmts;
533 input list< DAE.Statement> inAcc "={}";
534 input HashSet.HashSet inLeftCrs;
535 output list< DAE.Statement> outStmts;
536 output HashSet.HashSet outLeftCrs;
537 algorithm
538 (outStmts, outLeftCrs) := match inStmts
539 local
540 DAE.Statement stmt;
541 list<DAE.Statement> stmts, rest;
542 HashSet.HashSet leftCrs;
543
544 case {}
545 915 then (listReverse(inAcc), inLeftCrs);
546
547 // when statement
548 case (stmt as DAE.STMT_WHEN())::rest algorithm
549 // for when statements it is not necessary that all branches have the same left hand side variables
550 // -> take care that for each left hand side an assigment is generated
551 125 (stmts, leftCrs) := inlineWhenForInitializationWhenStmt(stmt, inLeftCrs, inAcc);
552 1418 (stmts, leftCrs) := inlineWhenForInitializationWhenAlgorithm(rest, stmts, leftCrs);
553 then (stmts, leftCrs);
554
555 // no when statement
556 case stmt::rest algorithm
557 1293 (stmts, leftCrs) := inlineWhenForInitializationWhenAlgorithm(rest, stmt::inAcc, inLeftCrs);
558 then (stmts, leftCrs);
559 end match;
560 end inlineWhenForInitializationWhenAlgorithm;
561
562 protected function inlineWhenForInitializationWhenStmt "author: lochel
563 This function generates out of a given when-algorithm, a algorithm for the initialization-problem."
564 input DAE.Statement inWhenStatement;
565 input HashSet.HashSet inLeftCrs;
566 input list< DAE.Statement> inAcc;
567 output list< DAE.Statement> outStmts;
568 output HashSet.HashSet outLeftCrs;
569 algorithm
570 (outStmts, outLeftCrs) := match inWhenStatement
571 local
572 DAE.Exp condition;
573 list<DAE.ComponentRef> crefLst;
574 DAE.Statement stmt;
575 list<DAE.Statement> stmts;
576 HashSet.HashSet leftCrs;
577
578 // active when equation during initialization
579 case DAE.STMT_WHEN(exp=condition, statementLst=stmts) guard
580 Expression.containsInitialCall(condition)
581 algorithm
582 29 stmts := List.foldr(stmts, List.consr, inAcc);
583 then (stmts, inLeftCrs);
584
585 // inactive when equation during initialization
586 case DAE.STMT_WHEN(statementLst=stmts, elseWhen=NONE()) algorithm
587 96 crefLst := CheckModel.algorithmStatementListOutputs(stmts, DAE.EXPAND()); // expand as we're in an algorithm
588 96 leftCrs := List.fold(crefLst, BaseHashSet.add, inLeftCrs);
589 then (inAcc, leftCrs);
590
591 // inactive when equation during initialization with elsewhen part
592 case DAE.STMT_WHEN(statementLst=stmts, elseWhen=SOME(stmt)) algorithm
593 25 crefLst := CheckModel.algorithmStatementListOutputs(stmts, DAE.EXPAND()); // expand as we're in an algorithm
594 25 leftCrs := List.fold(crefLst, BaseHashSet.add, inLeftCrs);
595 25 (stmts, leftCrs) := inlineWhenForInitializationWhenStmt(stmt, leftCrs, inAcc);
596 then (stmts, leftCrs);
597
598 else algorithm
599 ✗ Error.addInternalError("function inlineWhenForInitializationWhenStmt failed", sourceInfo());
600 ✗ then fail();
601 end match;
602 end inlineWhenForInitializationWhenStmt;
603
604 protected function generateInactiveWhenEquationForInitialization "author: lochel"
605 input list<DAE.ComponentRef> inCrLst;
606 input DAE.ElementSource inSource;
607 input list<BackendDAE.Equation> inEqns;
608 output list<BackendDAE.Equation> outEqns = inEqns;
609 protected
610 DAE.Type identType;
611 DAE.Exp crefExp, crefPreExp;
612 BackendDAE.Equation eqn;
613 algorithm
614
2/2
✓ Branch 0 taken 1048 times.
✓ Branch 1 taken 1584 times.
2632 for cr in inCrLst loop
615 1048 identType := ComponentReference.crefTypeConsiderSubs(cr);
616 1048 crefExp := DAE.CREF(cr, identType);
617 1048 crefPreExp := Expression.makePureBuiltinCall("pre", {crefExp}, identType);
618 1048 eqn := BackendDAE.EQUATION(crefExp, crefPreExp, inSource, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC);
619 outEqns := eqn::outEqns;
620 end for;
621 end generateInactiveWhenEquationForInitialization;
622
623 // =============================================================================
624 // section for collecting all variables, of which the left limit is also used.
625 //
626 // collect all pre variables in time equations
627 // =============================================================================
628
629 protected function collectPreVariables "author: lochel"
630 input BackendDAE.BackendDAE inDAE;
631 output HashSet.HashSet outHS;
632 protected
633 //list<DAE.ComponentRef> crefs;
634 algorithm
635 //BackendDump.dumpBackendDAE(inDAE, "inDAE");
636 1085 outHS := List.fold(inDAE.eqs, collectPreVariablesEqSystem, HashSet.emptyHashSet());
637 1085 (_, outHS) := BackendDAEUtil.traverseBackendDAEExpsEqns( inDAE.shared.initialEqs, Expression.traverseSubexpressionsHelper,
638 (collectPreVariablesTraverseExp, outHS) );
639 1085 (_, outHS) := BackendDAEUtil.traverseBackendDAEExpsEqns( inDAE.shared.removedEqs, Expression.traverseSubexpressionsHelper,
640 (collectPreVariablesTraverseExp, outHS) );
641 //print("collectPreVariables:\n");
642 //crefs := BaseHashSet.hashSetList(outHS);
643 //BackendDump.debuglst(crefs, ComponentReferenceBasics.printComponentRefStr, "\n", "\n");
644 end collectPreVariables;
645
646 public function collectPreVariablesEqSystem
647 input BackendDAE.EqSystem inSyst;
648 input HashSet.HashSet inHS;
649 output HashSet.HashSet outHS;
650 algorithm
651 8092 (_, outHS) := BackendDAEUtil.traverseBackendDAEExpsEqns( inSyst.orderedEqs, Expression.traverseSubexpressionsHelper,
652 (collectPreVariablesTraverseExp, inHS) );
653 8092 (_, outHS) := BackendDAEUtil.traverseBackendDAEExpsEqns( inSyst.removedEqs, Expression.traverseSubexpressionsHelper,
654 (collectPreVariablesTraverseExp, outHS) );
655 end collectPreVariablesEqSystem;
656
657 public function collectPreVariablesTraverseExp
658 input DAE.Exp inExp;
659 input HashSet.HashSet inHS;
660 output DAE.Exp outExp = inExp;
661 output HashSet.HashSet outHS;
662 algorithm
663 outHS := match inExp
664 case DAE.CALL(path=Absyn.IDENT(name="pre")) algorithm
665 2030 (_, outHS) := Expression.traverseExpBottomUp(inExp, collectPreVariablesTraverseExp2, inHS);
666 2030 then outHS;
667
668 case DAE.CALL(path=Absyn.IDENT(name="change")) algorithm
669 ✗ (_, outHS) := Expression.traverseExpBottomUp(inExp, collectPreVariablesTraverseExp2, inHS);
670 ✗ then outHS;
671
672 case DAE.CALL(path=Absyn.IDENT(name="edge")) algorithm
673 ✗ (_, outHS) := Expression.traverseExpBottomUp(inExp, collectPreVariablesTraverseExp2, inHS);
674 ✗ then outHS;
675
676 else inHS;
677 end match;
678 end collectPreVariablesTraverseExp;
679
680 protected function collectPreVariablesTraverseExp2 "author: lochel"
681 input DAE.Exp inExp;
682 input HashSet.HashSet inHS;
683 output DAE.Exp outExp = inExp;
684 output HashSet.HashSet outHS;
685 algorithm
686 outHS := match inExp
687 local
688 list<DAE.ComponentRef> crefs;
689 DAE.ComponentRef cr;
690
691 case DAE.CREF(componentRef=cr) algorithm
692 2032 crefs := ComponentReference.expandCref(cr, true);
693 2032 outHS := List.fold(crefs, BaseHashSet.add, inHS);
694 then outHS;
695
696 else inHS;
697 end match;
698 end collectPreVariablesTraverseExp2;
699
700 protected function warnAboutVars2 "author: lochel
701 TODO: Replace this with an general BackendDump implementation."
702 input list<BackendDAE.Var> vars;
703 output String outString;
704 protected
705 list<String> strs;
706 Integer len;
707 Integer size;
708 algorithm
709
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if listEmpty(vars) then
710 outString := "";
711 ✗ return;
712 end if;
713
4/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 13 times.
31 strs := list(BackendDump.varString(v) for v in vars);
714 13 len := listLength(strs);
715
4/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 13 times.
31 size := sum(stringLength(s) for s in strs) + len*10;
716 13 outString := warnAboutVars2Work(strs, " ", "\n", size);
717 end warnAboutVars2;
718
719 function warnAboutVars2Work
720 input list<String> strs;
721 input String prefix;
722 input String suffix;
723 input Integer size;
724 output String s="";
725 protected
726 // Allocate a string of the exact required length
727 System.StringAllocator sb=System.StringAllocator(size);
728 Integer i=0;
729 algorithm
730
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 13 times.
31 for str in strs loop
731 18 System.stringAllocatorStringCopy(sb, prefix, i);
732 18 i := i+stringLength(prefix);
733 18 System.stringAllocatorStringCopy(sb, str, i);
734 18 i := i+stringLength(str);
735 18 System.stringAllocatorStringCopy(sb, suffix, i);
736 18 i := i+stringLength(suffix);
737 end for;
738 // Return the string
739 13 s := System.stringAllocatorResult(sb,s);
740 end warnAboutVars2Work;
741
742 protected function warnAboutEqns2 "author: lochel
743 TODO: Replace this with an general BackendDump implementation."
744 input list<BackendDAE.Equation> inEqns;
745 output String outString;
746 algorithm
747 outString := match inEqns
748 local
749 BackendDAE.Equation eq;
750 list<BackendDAE.Equation> eqns;
751 String crStr;
752 String str;
753
754 case {} then "";
755
756 case eq::{} algorithm
757 12 crStr := " " + BackendDump.equationString(eq);
758 then crStr;
759
760 case eq::eqns algorithm
761 13 crStr := BackendDump.equationString(eq);
762 13 str := " " + crStr + "\n" + warnAboutEqns2(eqns);
763 then str;
764 end match;
765 end warnAboutEqns2;
766
767 // =============================================================================
768 // section for selecting initialization variables
769 //
770 // - unfixed state
771 // - secondary parameter
772 // - unfixed discrete -> pre(vd)
773 // =============================================================================
774
775 protected function selectInitializationVariablesDAE "author: lochel
776 This function wraps selectInitializationVariables.
777 All primary parameters get removed from the dae."
778 input output BackendDAE.BackendDAE dae;
779 output BackendDAE.Variables outInitVars;
780 output list<BackendDAE.Var> outAllPrimaryParameters = {};
781 output BackendDAE.Variables outGlobalKnownVars = dae.shared.globalKnownVars;
782 protected
783 BackendDAE.Variables otherVariables, globalKnownVars;
784 BackendDAE.EquationArray globalKnownVarsEqns;
785 BackendDAE.EqSystem globalKnownVarsSystem;
786 BackendDAE.AdjacencyMatrix m, mT;
787 array<Integer> ass1 "eqn := ass1[var]";
788 array<Integer> ass2 "var := ass2[eqn]";
789 list<list<Integer>> comps;
790 list<Integer> flatComps;
791 Integer nGlobalKnownVars;
792 array<Integer> secondary;
793 BackendDAE.Var v;
794 DAE.Exp bindExp;
795 BackendDAE.Variables primary;
796 list<DAE.ComponentRef> crefs;
797 list<BackendDAE.Var> globalKnownVarList = {};
798 algorithm
799
800 /* #6262, fix start values for input, when start exp has non constant bindings associated with a parameter (e.g)
801 input Real x(start = x_start);
802 parameter Real x_start = 6.0;
803 */
804
2/2
✓ Branch 1 taken 184488 times.
✓ Branch 2 taken 1086 times.
185574 for var in BackendVariable.varList(dae.shared.globalKnownVars) loop
805
6/6
✓ Branch 1 taken 295 times.
✓ Branch 2 taken 184193 times.
✓ Branch 5 taken 9 times.
✓ Branch 6 taken 286 times.
✓ Branch 9 taken 7 times.
✓ Branch 10 taken 2 times.
184488 if BackendVariable.isInput(var) and not Expression.isConstValue(BackendVariable.varStartValue(var)) and not Types.isArray(BackendVariable.varType(var)) then
806 7 bindExp := BackendVariable.varStartValue(var);
807 7 (v, _) := BackendVariable.getVarSingle(Expression.expCref(bindExp), dae.shared.globalKnownVars);
808 7 var := BackendVariable.setVarStartValueOption(var, v.bindExp);
809 end if;
810 globalKnownVarList := var :: globalKnownVarList;
811 end for;
812 1086 dae := BackendDAEUtil.setDAEGlobalKnownVars(dae, BackendVariable.listVar(globalKnownVarList));
813
814 // lochel: workaround to align all elements
815 1086 globalKnownVars := BackendVariable.listVar(BackendVariable.varList(dae.shared.globalKnownVars));
816
817 1086 outInitVars := selectInitializationVariables(dae.eqs);
818 1086 outInitVars := BackendVariable.traverseBackendDAEVars(dae.shared.globalKnownVars, selectInitializationVariables2, outInitVars);
819 1086 outInitVars := BackendVariable.traverseBackendDAEVars(dae.shared.aliasVars, selectInitializationVariables2, outInitVars);
820
821 1086 globalKnownVars := BackendVariable.traverseBackendDAEVars(dae.shared.externalObjects, addExtObjToGlobalKnownVars, globalKnownVars);
822 1086 nGlobalKnownVars := BackendVariable.varsSize(globalKnownVars);
823 1086 otherVariables := BackendVariable.emptyVarsSized(nGlobalKnownVars);
824 1086 globalKnownVarsEqns := BackendEquation.emptyEqnsSized(nGlobalKnownVars);
825 1086 globalKnownVarsEqns := BackendVariable.traverseBackendDAEVars(globalKnownVars, createGlobalKnownVarsEquations, globalKnownVarsEqns);
826
827
2/2
✓ Branch 0 taken 227 times.
✓ Branch 1 taken 859 times.
1086 if nGlobalKnownVars > 0 then
828 859 globalKnownVarsSystem := BackendDAEUtil.createEqSystem(globalKnownVars, globalKnownVarsEqns);
829 859 (m, mT) := BackendDAEUtil.adjacencyMatrix(globalKnownVarsSystem, BackendDAE.NORMAL(), NONE(), BackendDAEUtil.isInitializationDAE(dae.shared));
830 //BackendDump.dumpAdjacencyMatrix(m);
831 //BackendDump.dumpAdjacencyMatrixT(mT);
832
833 // match the system
834 // ass1 and ass2 should be {1, 2, ..., nGlobalKnownVars}
835 859 (ass1, ass2) := Matching.PerfectMatching(m);
836 //BackendDump.dumpMatchingVars(ass1);
837 //BackendDump.dumpMatchingEqns(ass2);
838
839 859 comps := Sorting.Tarjan(m, ass1);
840 //BackendDump.dumpComponentsOLD(comps);
841 859 comps := mapListIndices(comps, ass2) "map to var indices (not really needed, since ass2 should be {1, 2, ..., nParam})" ;
842 //BackendDump.dumpComponentsOLD(comps);
843
844 // flattern list and look for cyclic dependencies
845
4/4
✓ Branch 0 taken 184549 times.
✓ Branch 1 taken 858 times.
✓ Branch 2 taken 184549 times.
✓ Branch 3 taken 858 times.
185407 flatComps := list(flattenParamComp(comp, globalKnownVars) for comp in comps);
846 //BackendDump.dumpAdjacencyRow(flatComps);
847 //BackendDump.dumpVariables(globalKnownVars, "globalKnownVars");
848
849 // select secondary parameters
850 858 secondary := arrayCreate(nGlobalKnownVars, 0);
851 858 secondary := selectSecondaryParameters(flatComps, globalKnownVars, mT, secondary);
852
853 // get primary and secondary parameters and variables
854 858 primary := BackendVariable.emptyVarsSized(nGlobalKnownVars);
855
2/2
✓ Branch 0 taken 184546 times.
✓ Branch 1 taken 858 times.
185404 for i in flatComps loop
856 184546 v := BackendVariable.getVarAt(globalKnownVars, i);
857 184546 bindExp := BackendVariable.varBindExpStartValueNoFail(v);
858 184546 crefs := Expression.extractCrefsFromExp(bindExp);
859 //BackendDump.dumpVarList({v}, intString(i));
860
861 () := match v
862 // primary parameter
863 case BackendDAE.VAR(varKind=BackendDAE.PARAM()) guard 0 == secondary[i] and allPrimary(crefs, primary)
864 algorithm
865 outAllPrimaryParameters := v::outAllPrimaryParameters;
866 131805 primary := BackendVariable.addVar(v, primary);
867 then ();
868
869 // primary external object
870 case BackendDAE.VAR(varKind=BackendDAE.EXTOBJ(), bindExp=SOME(bindExp)) guard 0 == secondary[i] and allPrimary(crefs, primary)
871 algorithm
872 outAllPrimaryParameters := v::outAllPrimaryParameters;
873 61 v := BackendVariable.setVarFixed(v, true);
874 61 outGlobalKnownVars := BackendVariable.addVar(v, outGlobalKnownVars);
875 61 primary := BackendVariable.addVar(v, primary);
876 then ();
877
878 // secondary parameter
879 case BackendDAE.VAR(varKind=BackendDAE.PARAM())
880 algorithm
881 1415 otherVariables := BackendVariable.addVar(v, otherVariables);
882 1415 v := BackendVariable.setVarFixed(v, false);
883 1415 outInitVars := BackendVariable.addVar(v, outInitVars);
884 1415 outGlobalKnownVars := BackendVariable.addVar(v, outGlobalKnownVars);
885 then ();
886
887 // primary variable
888 case _ guard BackendVariable.isVarAlg(v) and 0 == secondary[i] and allPrimary(crefs, primary)
889 algorithm
890 43195 otherVariables := BackendVariable.addVar(v, otherVariables);
891 43195 v := BackendVariable.setVarFixed(v, true);
892 43195 v := BackendVariable.setVarFinal(v, true);
893 43195 outGlobalKnownVars := BackendVariable.addVar(v, outGlobalKnownVars);
894 43195 primary := BackendVariable.addVar(v, primary);
895 then ();
896
897 // secondary variable
898 case _ guard BackendVariable.isVarAlg(v)
899 algorithm
900 22 otherVariables := BackendVariable.addVar(v, otherVariables);
901 22 v := BackendVariable.setVarFixed(v, false);
902 22 outGlobalKnownVars := BackendVariable.addVar(v, outGlobalKnownVars);
903 then ();
904
905 else
906 algorithm
907 8048 otherVariables := BackendVariable.addVar(v, otherVariables);
908 then ();
909 end match;
910 end for;
911
912 858 GCExt.free(secondary);
913 858 outAllPrimaryParameters := listReverse(outAllPrimaryParameters);
914 858 dae := BackendDAEUtil.setDAEGlobalKnownVars(dae, otherVariables);
915
916 //BackendDump.dumpVarList(outAllPrimaryParameters, "outAllPrimaryParameters");
917 //BackendDump.dumpVariables(otherVariables, "otherVariables");
918 end if;
919 end selectInitializationVariablesDAE;
920
921 protected function allPrimary
922 "Whether every element of every variable the crefs name is in primary;
923 a whole array or record counts only when all its elements are."
924 input list<DAE.ComponentRef> crefs;
925 input BackendDAE.Variables primary;
926 output Boolean b = true;
927 protected
928 list<BackendDAE.Var> vars;
929 algorithm
930
2/2
✓ Branch 0 taken 29990 times.
✓ Branch 1 taken 175061 times.
205051 for cr in crefs loop
931
1/2
✓ Branch 1 taken 29990 times.
✗ Branch 2 not taken.
29990 if not ComponentReferenceBasics.crefEqual(cr, DAE.crefTime) then
932 try
933 29990 vars := BackendVariable.getVar(cr, primary);
934 29555 b := listLength(vars) == elementCount(ComponentReference.crefTypeFull(cr));
935 else
936 b := false;
937 end try;
938
2/2
✓ Branch 0 taken 438 times.
✓ Branch 1 taken 29552 times.
29990 if not b then
939 438 return;
940 end if;
941 end if;
942 end for;
943 end allPrimary;
944
945 protected function elementCount
946 "The scalar variables a component of this type is made of: arrays and
947 records are expanded, anything else (an external object too) is one."
948 input DAE.Type ty;
949 output Integer n;
950 algorithm
951 n := match ty
952
4/4
✓ Branch 0 taken 210 times.
✓ Branch 1 taken 118 times.
✓ Branch 2 taken 210 times.
✓ Branch 3 taken 118 times.
328 case DAE.T_ARRAY() then elementCount(ty.ty) * product(Expression.dimensionSize(d) for d in ty.dims);
953
4/4
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 23 times.
✓ Branch 3 taken 11 times.
34 case DAE.T_COMPLEX(complexClassType = ClassInf.RECORD()) then sum(elementCount(v.ty) for v in ty.varLst);
954 else 1;
955 end match;
956 end elementCount;
957
958 function addExtObjToGlobalKnownVars "
959 Sets fixed=true for external objects with binding and adds them to globalKnownVars
960 author: ptaeuber"
961 input output BackendDAE.Var extObj;
962 input output BackendDAE.Variables globalKnownVars;
963 algorithm
964 globalKnownVars := match extObj
965 local
966 BackendDAE.Var var;
967 // external object with binding
968 case BackendDAE.VAR(varKind=BackendDAE.EXTOBJ(), bindExp=SOME(_)) algorithm
969 62 var := BackendVariable.setVarFixed(extObj, true);
970 62 globalKnownVars := BackendVariable.addVar(var, globalKnownVars);
971 then (globalKnownVars);
972 else
973 then (globalKnownVars);
974 end match;
975 end addExtObjToGlobalKnownVars;
976
977 protected function createGlobalKnownVarsEquations
978 "Creates BackendDAE.EQUATION()s from the globalKnownVars
979 author: ptaeuber"
980 input output BackendDAE.Var var;
981 input output BackendDAE.EquationArray parameterEqns;
982 protected
983 DAE.Exp lhs, rhs, startValue;
984 BackendDAE.Equation eqn;
985 BackendDAE.Var v;
986 String s, str;
987 SourceInfo info;
988 algorithm
989 184550 lhs := BackendVariable.varExp(var);
990
991
6/6
✓ Branch 1 taken 133500 times.
✓ Branch 2 taken 51050 times.
✓ Branch 4 taken 1017 times.
✓ Branch 5 taken 132483 times.
✓ Branch 7 taken 82 times.
✓ Branch 8 taken 935 times.
184550 if BackendVariable.isParam(var) and not BackendVariable.varHasBindExp(var) and BackendVariable.varFixed(var) then
992 82 s := ExpressionBasics.printExpStr(lhs);
993 82 startValue := BackendVariable.varStartValue(var);
994 82 str := ExpressionBasics.printExpStr(startValue);
995 82 v := BackendVariable.setVarKind(var, BackendDAE.VARIABLE());
996 82 v := BackendVariable.setBindExp(v, SOME(startValue));
997 82 v := BackendVariable.setVarFixed(v, true);
998 82 info := ElementSource.getElementSourceFileInfo(BackendVariable.getVarSource(v));
999 82 Error.addSourceMessage(Error.UNBOUND_PARAMETER_WITH_START_VALUE_WARNING, {s, str}, info);
1000 end if;
1001
1002 184550 rhs := BackendVariable.varBindExpStartValueNoFail(var);
1003 184550 eqn := BackendDAE.EQUATION(lhs, rhs, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_BINDING);
1004 184550 parameterEqns := BackendEquation.add(eqn, parameterEqns);
1005 end createGlobalKnownVarsEquations;
1006
1007 protected function markIndex
1008 input Integer inIndex;
1009 input array<Integer> inArray;
1010 output array<Integer> outArray = inArray;
1011 algorithm
1012 1352 outArray[inIndex] := 1;
1013 end markIndex;
1014
1015 protected function selectSecondaryParameters
1016 input list<Integer> inOrdering;
1017 input BackendDAE.Variables inParameters;
1018 input BackendDAE.AdjacencyMatrix inM;
1019 input array<Integer> inSecondaryParams;
1020 output array<Integer> outSecondaryParams = inSecondaryParams;
1021 protected
1022 BackendDAE.Var param;
1023 algorithm
1024
2/2
✓ Branch 0 taken 184546 times.
✓ Branch 1 taken 858 times.
185404 for i in inOrdering loop
1025 184546 param := BackendVariable.getVarAt(inParameters, i);
1026 // fixed=false
1027
6/6
✓ Branch 1 taken 141329 times.
✓ Branch 2 taken 43217 times.
✓ Branch 4 taken 140112 times.
✓ Branch 5 taken 1217 times.
✓ Branch 7 taken 59 times.
✓ Branch 8 taken 183270 times.
184546 outSecondaryParams := if (if BackendVariable.isVarAlg(param) then false else not BackendVariable.varFixed(param)) or 1 == outSecondaryParams[i]
1028 then List.fold(inM[i], markIndex, outSecondaryParams) else outSecondaryParams;
1029 end for;
1030 end selectSecondaryParameters;
1031
1032 public function flattenParamComp
1033 input list<Integer> paramIndices;
1034 input BackendDAE.Variables inAllParameters;
1035 output Integer outFlatComp;
1036 algorithm
1037 outFlatComp := match paramIndices
1038 local
1039 Integer i;
1040 list<BackendDAE.Var> paramLst;
1041 BackendDAE.Var param;
1042
1043 case {i} then i;
1044
1045 else algorithm
1046 paramLst := {};
1047
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 time.
3 for i in paramIndices loop
1048 2 param := BackendVariable.getVarAt(inAllParameters, i);
1049 paramLst := param::paramLst;
1050 end for;
1051 1 Error.addCompilerError("Cyclically dependent parameters found:\n" + warnAboutVars2(paramLst));
1052 1 then fail();
1053 end match;
1054 end flattenParamComp;
1055
1056 protected function selectInitializationVariables "author: lochel"
1057 input list<BackendDAE.EqSystem> inEqSystems;
1058 output BackendDAE.Variables outVars;
1059 algorithm
1060 1086 outVars := BackendVariable.emptyVars();
1061 1086 outVars := List.fold(inEqSystems, selectInitializationVariables1, outVars);
1062 end selectInitializationVariables;
1063
1064 protected function selectInitializationVariables1 "author: lochel"
1065 input BackendDAE.EqSystem inEqSystem;
1066 input BackendDAE.Variables inVars;
1067 output BackendDAE.Variables outVars;
1068 algorithm
1069 1584 outVars := BackendVariable.traverseBackendDAEVars(inEqSystem.orderedVars, selectInitializationVariables2, inVars);
1070 end selectInitializationVariables1;
1071
1072 protected function selectInitializationVariables2 "author: lochel"
1073 input BackendDAE.Var inVar;
1074 input BackendDAE.Variables inVars;
1075 output BackendDAE.Var outVar;
1076 output BackendDAE.Variables outVars;
1077 algorithm
1078 (outVar, outVars) := matchcontinue (inVar, inVars)
1079 local
1080 BackendDAE.Var preVar;
1081 BackendDAE.Variables vars;
1082 DAE.ComponentRef cr, preCR;
1083 DAE.Type ty;
1084 DAE.InstDims arryDim;
1085
1086 // unfixed state
1087 case (BackendDAE.VAR(varKind=BackendDAE.STATE()), vars) algorithm
1088
2/2
✓ Branch 1 taken 4389 times.
✓ Branch 2 taken 3139 times.
7528 false := BackendVariable.varFixed(inVar);
1089 3139 vars := BackendVariable.addVar(inVar, vars);
1090 then (inVar, vars);
1091
1092 // unfixed discrete -> pre(vd)
1093 case (BackendDAE.VAR(varName=cr, varKind=BackendDAE.DISCRETE(), varType=ty, arryDim=arryDim), vars) algorithm
1094
2/2
✓ Branch 1 taken 1695 times.
✓ Branch 2 taken 10548 times.
12243 false := BackendVariable.varFixed(inVar);
1095 10548 preCR := ComponentReference.crefPrefixPre(cr); // cr => $PRE.cr
1096 10548 preVar := BackendDAE.VAR(preCR, BackendDAE.VARIABLE(), DAE.BIDIR(), DAE.NON_PARALLEL(), ty, NONE(), NONE(), arryDim, DAE.emptyElementSource, NONE(), NONE(), NONE(), NONE(), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER(), false, false, false);
1097 10548 vars := BackendVariable.addVar(preVar, vars);
1098 then (inVar, vars);
1099
1100 else (inVar, inVars);
1101 end matchcontinue;
1102 end selectInitializationVariables2;
1103
1104 // =============================================================================
1105 // section for simplifying initial functions
1106 //
1107 // =============================================================================
1108
1109 protected function simplifyInitialFunctions
1110 input DAE.Exp inExp;
1111 input Boolean inUseHomotopy;
1112 output DAE.Exp outExp;
1113 output Boolean outUseHomotopy;
1114 algorithm
1115
3/4
✓ Branch 0 taken 192199 times.
✓ Branch 1 taken 23685 times.
✓ Branch 3 taken 215884 times.
✗ Branch 4 not taken.
408083 (outExp, outUseHomotopy) := Expression.traverseExpBottomUp(inExp, simplifyInitialFunctionsExp, inUseHomotopy);
1116 end simplifyInitialFunctions;
1117
1118 protected function simplifyInitialFunctionsExp
1119 input DAE.Exp inExp;
1120 input Boolean inUseHomotopy;
1121 output DAE.Exp outExp;
1122 output Boolean outUseHomotopy;
1123 algorithm
1124 (outExp, outUseHomotopy) := match inExp
1125 local
1126 DAE.Exp expr;
1127
1128 case DAE.CALL(path=Absyn.IDENT(name="initial"))
1129 then (DAE.BCONST(true), inUseHomotopy);
1130
1131 case DAE.CALL(path=Absyn.IDENT(name="sample"))
1132 then (DAE.BCONST(false), inUseHomotopy);
1133
1134 case DAE.CALL(path=Absyn.IDENT(name="delay"), expLst=_::expr::_)
1135 then (expr, inUseHomotopy);
1136
1137 case DAE.CALL(path=Absyn.IDENT(name="homotopy"))
1138 then (inExp, true);
1139
1140 else (inExp, inUseHomotopy);
1141 end match;
1142 end simplifyInitialFunctionsExp;
1143
1144 // =============================================================================
1145 // section for pre-balancing the initial system
1146 //
1147 // This section removes unused pre variables and auto-fixes non-pre variables,
1148 // which occur in no equation.
1149 // =============================================================================
1150
1151 protected function preBalanceInitialSystem "author: lochel"
1152 input BackendDAE.EqSystem inEqSystem;
1153 input BackendDAE.Variables initVars;
1154 input Boolean isLambda0;
1155 output BackendDAE.EqSystem outEqSystem = inEqSystem;
1156 output list<BackendDAE.Var> outDumpVars;
1157 protected
1158 BackendDAE.Variables orderedVars;
1159 BackendDAE.EquationArray orderedEqs;
1160 Boolean b;
1161 BackendDAE.AdjacencyMatrix mt;
1162 algorithm
1163 1120 (_, mt) := BackendDAEUtil.adjacencyMatrix(inEqSystem, BackendDAE.NORMAL(), NONE(), true);
1164
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1120 times.
2240 (orderedVars, orderedEqs, b, outDumpVars) := preBalanceInitialSystem1(arrayLength(mt), mt, inEqSystem.orderedVars, inEqSystem.orderedEqs, initVars, isLambda0, false, {});
1165
2/2
✓ Branch 0 taken 1088 times.
✓ Branch 1 taken 32 times.
1120 if b then
1166 32 outEqSystem.orderedEqs := orderedEqs;
1167 outEqSystem.orderedVars := orderedVars;
1168 32 outEqSystem := BackendDAEUtil.clearEqSyst(outEqSystem);
1169 end if;
1170 end preBalanceInitialSystem;
1171
1172 protected function preBalanceInitialSystem1 "author: lochel"
1173 input Integer n;
1174 input BackendDAE.AdjacencyMatrix mt;
1175 input BackendDAE.Variables inVars;
1176 input BackendDAE.EquationArray inEqs;
1177 input BackendDAE.Variables initVars;
1178 input Boolean isLambda0;
1179 input Boolean inB;
1180 input list<BackendDAE.Var> inDumpVars;
1181 output BackendDAE.Variables outVars;
1182 output BackendDAE.EquationArray outEqs;
1183 output Boolean outB;
1184 output list<BackendDAE.Var> outDumpVars;
1185 algorithm
1186 (outVars, outEqs, outB, outDumpVars) := match (n, inB)
1187 local
1188 Boolean b;
1189 BackendDAE.Variables vars;
1190 BackendDAE.EquationArray eqs;
1191 list<BackendDAE.Var> dumpVars;
1192
1193 case (0, false)
1194 then (inVars, inEqs, false, inDumpVars);
1195
1196 case (0, true) algorithm
1197 32 vars := BackendVariable.listVar1(BackendVariable.varList(inVars));
1198 then (vars, inEqs, true, inDumpVars);
1199
1200 else algorithm
1201
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 131606 times.
131606 true := n > 0;
1202 131606 (vars, eqs, b, dumpVars) := preBalanceInitialSystem2(n, mt, inVars, inEqs, initVars, isLambda0, inB, inDumpVars);
1203 131606 (vars, eqs, b, dumpVars) := preBalanceInitialSystem1(n-1, mt, vars, eqs, initVars, isLambda0, b, dumpVars);
1204 then (vars, eqs, b, dumpVars);
1205 end match;
1206 end preBalanceInitialSystem1;
1207
1208 protected function preBalanceInitialSystem2 "author: lochel"
1209 input Integer n;
1210 input BackendDAE.AdjacencyMatrix mt;
1211 input BackendDAE.Variables inVars;
1212 input BackendDAE.EquationArray inEqs;
1213 input BackendDAE.Variables initVars;
1214 input Boolean isLambda0;
1215 input Boolean inB;
1216 input list<BackendDAE.Var> inDumpVars;
1217 output BackendDAE.Variables outVars = inVars;
1218 output BackendDAE.EquationArray outEqs = inEqs;
1219 output Boolean outB = inB;
1220 output list<BackendDAE.Var> outDumpVars = inDumpVars;
1221 protected
1222 list<Integer> row;
1223 BackendDAE.Var var;
1224 DAE.ComponentRef cref;
1225 String str, err_str = " with unknown reason.";
1226 algorithm
1227 try
1228 131606 row := mt[n];
1229
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 131550 times.
131606 if listEmpty(row) then
1230 56 outB := true;
1231 56 var := BackendVariable.getVarAt(inVars, n);
1232 56 cref := BackendVariable.varCref(var);
1233
1234
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 56 times.
56 if ComponentReference.isPreCref(cref) then
1235 ✗ (outVars, _) := BackendVariable.removeVars({n}, inVars, {});
1236 elseif BackendVariable.containsVar(var, initVars) then
1237 56 (outEqs, outDumpVars) := addStartValueEquations({var}, inEqs, inDumpVars);
1238 else
1239 ✗ str := if isLambda0 then "lambda 0 " else "";
1240 ✗ err_str := " because variable " + BackendDump.varString(var)
1241 + " does not appear in any equation in the " + str + "initial system and is not fixable.";
1242 ✗ fail();
1243 end if;
1244 end if;
1245 else
1246 ✗ Error.addInternalError(getInstanceName() + " failed" + err_str, sourceInfo());
1247 ✗ fail();
1248 end try;
1249 end preBalanceInitialSystem2;
1250
1251 protected function analyzeInitialSystem "author: lochel
1252 This function fixes discrete and state variables to balance the initial equation system."
1253 input BackendDAE.BackendDAE inInitDAE;
1254 input BackendDAE.Variables inInitVars;
1255 input constraintHandlerFunc func = balanceInitialSystem;
1256 output BackendDAE.BackendDAE outDAE;
1257 output list<BackendDAE.Var> outDumpVars;
1258 output list<BackendDAE.Equation> outRemovedEqns;
1259 protected
1260 BackendDAE.BackendDAE dae;
1261 BackendDAE.EqSystem syst;
1262 list<BackendDAE.EqSystem> eqs;
1263 DoubleEnded.MutableList<BackendDAE.Var> dumpVars;
1264 DoubleEnded.MutableList<BackendDAE.Equation> removedEqns;
1265 list<BackendDAE.Equation> filtered_initial_eqs;
1266 algorithm
1267 // filter empty systems
1268 eqs := {};
1269 1120 dumpVars := DoubleEnded.fromList({});
1270 1120 removedEqns := DoubleEnded.fromList({});
1271
2/2
✓ Branch 0 taken 48392 times.
✓ Branch 1 taken 1120 times.
49512 for syst in inInitDAE.eqs loop
1272
2/2
✓ Branch 1 taken 48369 times.
✓ Branch 2 taken 23 times.
48392 if BackendDAEUtil.nonEmptySystem(syst) then
1273 eqs := syst::eqs;
1274 else
1275
4/6
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 23 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 23 times.
25 filtered_initial_eqs := list(eqn for eqn guard(BackendEquation.hasAnyUnknown(eqn, inInitVars)) in BackendEquation.equationList(syst.orderedEqs));
1276 23 DoubleEnded.push_list_back(removedEqns, filtered_initial_eqs);
1277 23 DoubleEnded.push_list_back(removedEqns, BackendEquation.equationList(syst.removedEqs));
1278 end if;
1279 end for;
1280 1120 dae := BackendDAE.DAE(eqs, inInitDAE.shared);
1281
1282 //execStat("reset analyzeInitialSystem (initialization)");
1283 1120 outDAE := BackendDAEUtil.mapEqSystemAndFold(dae, function func(initVars=inInitVars, dumpVars=dumpVars, removedEqns=removedEqns), 0);
1284 1120 outRemovedEqns := DoubleEnded.toListAndClear(removedEqns);
1285 1120 outDumpVars := DoubleEnded.toListAndClear(dumpVars);
1286 end analyzeInitialSystem;
1287
1288 protected function getInitEqIndices
1289 input list<BackendDAE.Equation> equations;
1290 output list<Integer> indices = {};
1291 protected
1292 Integer i = 1;
1293 algorithm
1294 ✗ for eq in equations loop
1295 ✗ if BackendEquation.isInitialEquation(eq) then
1296 indices := i :: indices;
1297 end if;
1298
1299 ✗ i := i + 1;
1300 end for;
1301
1302 ✗ indices := listReverseInPlace(indices);
1303 end getInitEqIndices;
1304
1305 protected partial function constraintHandlerFunc
1306 input BackendDAE.EqSystem inEqSystem "initial system to be balanced";
1307 input BackendDAE.Shared inShared "shared information along all systems";
1308 output BackendDAE.EqSystem outEqSystem "balanced initial system";
1309 output BackendDAE.Shared outShared = inShared "possibly adapted shared information";
1310 input output Integer dummy "traverser dummy";
1311 input BackendDAE.Variables initVars "all variables that are allowed to be fixed";
1312 input DoubleEnded.MutableList<BackendDAE.Var> dumpVars "new fixed variables";
1313 input DoubleEnded.MutableList<BackendDAE.Equation> removedEqns "redundant equations";
1314 end constraintHandlerFunc;
1315
1316 protected function balanceInitialSystem "author: kabdelhak
1317 New algorithm to handle under-, over-, and mixed-determined systems.
1318 1. split off initial equations and match the system without them
1319 (ensures that the correct equations are left unmatched)
1320 2. sort fixables to be matched last
1321 (ensures that the correct variables are left unmatched)
1322 3. compute adjacency matrix
1323 4. inverse match (var->eq)
1324 5. add initial equations and continue matching
1325 6. use subroutine resolveOverAndUnderconstraints for unmatched variables and equations
1326 7. use ASSC algorithm to resolve analytical singularities
1327 If ASSC changed anything:
1328 7.1 inverse match (var->eq)
1329 7.2 use subroutine resolveOverAndUnderconstraints for unmatched variables and equations
1330 8. success"
1331 extends constraintHandlerFunc;
1332 protected
1333 Boolean debug = false;
1334 list<BackendDAE.Equation> init_eqns, sim_eqns;
1335 AvlTreePathFunction.Tree funcs;
1336 BackendDAE.AdjacencyMatrix m, mT;
1337 Integer nVars, nEqns;
1338 array<Integer> scal_to_arr, var_to_eqn, eqn_to_var;
1339 Boolean changed = false;
1340 list<list<Integer>> comps;
1341 list<Integer> redundantEqns, unfixedVars;
1342 Boolean initASSC = Flags.getConfigBool(Flags.INIT_ASSC);
1343 algorithm
1344
2/2
✓ Branch 1 taken 47540 times.
✓ Branch 2 taken 829 times.
48369 if BackendVariable.varsSize(inEqSystem.orderedVars) > 0 then
1345 // 1. split off initial equations and match the system without them
1346 47540 (init_eqns, sim_eqns) := List.splitOnTrue(BackendEquation.equationList(inEqSystem.orderedEqs), BackendEquation.isInitialEquation);
1347
1348 // 2. sort fixables to be matched last
1349 47540 outEqSystem := BackendDAEUtil.createEqSystem(BackendVariable.sortInitialVars(inEqSystem.orderedVars, initVars), BackendEquation.listEquation(sim_eqns));
1350 47540 outEqSystem.removedEqs := inEqSystem.removedEqs;
1351 47540 funcs := BackendDAEUtil.getFunctions(inShared);
1352
1353 // 3. compute adjacency matrix
1354 47540 (outEqSystem, m, mT, _, scal_to_arr) := BackendDAEUtil.getAdjacencyMatrixScalar(outEqSystem, BackendDAE.SOLVABLE(), SOME(funcs), true);
1355
1356 // 4. inverse match (var->eq)
1357 47540 nVars := BackendVariable.varsSize(outEqSystem.orderedVars);
1358 // take original size here so that we can freely add the initial equations later
1359 47540 nEqns := BackendEquation.equationArraySize(inEqSystem.orderedEqs);
1360 47540 (eqn_to_var, var_to_eqn, _, _, _) := Matching.RegularMatching(mT, nEqns, nVars);
1361
1362 // 5. add initial equations and continue matching
1363 47540 outEqSystem.orderedEqs := BackendEquation.addList(init_eqns, outEqSystem.orderedEqs);
1364 47540 (outEqSystem, m, mT, _, scal_to_arr) := BackendDAEUtil.getAdjacencyMatrixScalar(outEqSystem, BackendDAE.SOLVABLE(), SOME(funcs), true);
1365 47540 (eqn_to_var, var_to_eqn, _, _, _) := Matching.ContinueMatching(mT, nEqns, nVars, eqn_to_var, var_to_eqn);
1366
1367
8/10
✗ Branch 0 not taken.
✓ Branch 1 taken 47540 times.
✓ Branch 3 taken 129538 times.
✓ Branch 4 taken 2068 times.
✓ Branch 5 taken 131606 times.
✓ Branch 6 taken 47540 times.
✓ Branch 7 taken 2068 times.
✓ Branch 8 taken 47540 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 47540 times.
226686 unfixedVars := list(i for i guard(var_to_eqn[i] < 0) in 1:arrayLength(var_to_eqn));
1368
6/6
✓ Branch 1 taken 129538 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 129566 times.
✓ Branch 4 taken 47540 times.
✓ Branch 5 taken 28 times.
✓ Branch 6 taken 47540 times.
177106 redundantEqns := list(i for i guard(eqn_to_var[i] < 0) in 1:arrayLength(eqn_to_var));
1369
1370
4/4
✓ Branch 0 taken 47522 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 444 times.
✓ Branch 3 taken 47078 times.
47540 if not (listEmpty(redundantEqns) and listEmpty(unfixedVars)) then
1371 // 6. use subroutine resolveOverAndUnderconstraints for unmatched variables and equations
1372
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 444 times.
462 if not listEmpty(redundantEqns) then
1373 18 consistencyCheck(redundantEqns, outEqSystem.orderedEqs, outEqSystem.orderedVars, inShared, 0, m, enhancedRows(outEqSystem, inShared), var_to_eqn, eqn_to_var, scal_to_arr);
1374
4/4
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 18 times.
46 redundantEqns := List.unique(list(scal_to_arr[i] for i in redundantEqns));
1375 end if;
1376 462 outEqSystem := resolveOverAndUnderconstraints(outEqSystem, initVars, unfixedVars, redundantEqns, dumpVars, removedEqns);
1377 462 (outEqSystem, m, mT, _, scal_to_arr) := BackendDAEUtil.getAdjacencyMatrixScalar(outEqSystem, BackendDAE.SOLVABLE(), SOME(funcs), true);
1378 462 nVars := BackendVariable.varsSize(outEqSystem.orderedVars);
1379 462 nEqns := BackendEquation.equationArraySize(outEqSystem.orderedEqs);
1380 462 (eqn_to_var, var_to_eqn, _, _, _) := Matching.RegularMatching(mT, nEqns, nVars);
1381 elseif not initASSC then
1382 47078 outEqSystem := inEqSystem;
1383 end if;
1384
1385 if debug then
1386 BackendDump.dumpEqSystem(outEqSystem, "fixInitialSystem");
1387 BackendDump.dumpAdjacencyMatrixT(mT);
1388 BackendDump.dumpMatchingVars(var_to_eqn);
1389 BackendDump.dumpMatchingEqns(eqn_to_var);
1390 end if;
1391
1392 // 7. use ASSC algorithm to resolve analytical singularities
1393
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47540 times.
47540 if initASSC then
1394 ✗ comps := Sorting.Tarjan(m, var_to_eqn, nEqns);
1395
1396 ✗ for comp in comps loop
1397 ✗ (eqn_to_var, var_to_eqn, outEqSystem, changed) := BackendDAEUtil.analyticalToStructuralSingularity(comp, eqn_to_var, var_to_eqn, outEqSystem, changed, true);
1398 end for;
1399
1400 ✗ if changed then
1401 // 7.1 inverse match (var->eq)
1402 ✗ BackendDAE.EQSYSTEM(m=SOME(m),mT=SOME(mT)) := outEqSystem;
1403 ✗ (outEqSystem, m, mT, _, scal_to_arr) := BackendDAEUtil.getAdjacencyMatrixScalar(outEqSystem, BackendDAE.NORMAL(), SOME(funcs), true);
1404 ✗ (eqn_to_var, var_to_eqn, _, _, _) := Matching.ContinueMatching(mT, nEqns, nVars, eqn_to_var, var_to_eqn);
1405
1406 ✗ unfixedVars := list(i for i guard(var_to_eqn[i] < 0) in 1:arrayLength(var_to_eqn));
1407 ✗ redundantEqns := list(i for i guard(eqn_to_var[i] < 0) in 1:arrayLength(eqn_to_var));
1408 ✗ redundantEqns := List.unique(list(scal_to_arr[i] for i in redundantEqns));
1409
1410 ✗ if not (listEmpty(redundantEqns) and listEmpty(unfixedVars)) then
1411 // 7.2 use subroutine resolveOverAndUnderconstraints for unmatched variables and equations
1412 ✗ if not listEmpty(redundantEqns) then
1413 ✗ consistencyCheck(redundantEqns, outEqSystem.orderedEqs, outEqSystem.orderedVars, inShared, 0, m, enhancedRows(outEqSystem, inShared), var_to_eqn, eqn_to_var, scal_to_arr);
1414 end if;
1415 ✗ outEqSystem := resolveOverAndUnderconstraints(outEqSystem, initVars, unfixedVars, redundantEqns, dumpVars, removedEqns);
1416 ✗ (outEqSystem, m, mT, _, scal_to_arr) := BackendDAEUtil.getAdjacencyMatrixScalar(outEqSystem, BackendDAE.SOLVABLE(), SOME(funcs), true);
1417 end if;
1418 end if;
1419 end if;
1420 else
1421 829 outEqSystem := inEqSystem;
1422 end if;
1423 end balanceInitialSystem;
1424
1425 protected function resolveOverAndUnderconstraints "author: kabdelhak
1426 Subroutine for balanceInitialSystem
1427 New algorithm to handle under-, over-, and mixed-determined systems.
1428 1. remove unmatched equations
1429 2. fix unmatched initialVars"
1430 input output BackendDAE.EqSystem syst "possibly mixed determined system to be resolved";
1431 input BackendDAE.Variables initVars "variables that are allowed to be fixed";
1432 input list<Integer> unfixedVars "indices of variables that have to be fixed";
1433 input list<Integer> redundantEqns "indices of equations that have to be removed";
1434 input DoubleEnded.MutableList<BackendDAE.Var> dumpVars "variables that have been fixed (debug report)";
1435 input DoubleEnded.MutableList<BackendDAE.Equation> removedEqns "equations that have been removed (debug report)";
1436 protected
1437 Boolean debug = false;
1438 list<BackendDAE.Equation> redundant_lst = {};
1439 list<BackendDAE.Var> failed_var_lst, var_lst = {};
1440 BackendDAE.EquationArray new_eqns;
1441 algorithm
1442 // 6. remove unmatched equations
1443 462 redundant_lst := BackendEquation.getList(redundantEqns, syst.orderedEqs);
1444
1445 462 DoubleEnded.push_list_back(removedEqns, redundant_lst);
1446 462 new_eqns := BackendEquation.deleteList(syst.orderedEqs, redundantEqns);
1447 if debug then
1448 BackendDump.dumpEquationList(redundant_lst, "removed eqns");
1449 end if;
1450
1451 // 7. fix unmatched states and discrete states
1452
4/4
✓ Branch 0 taken 2068 times.
✓ Branch 1 taken 462 times.
✓ Branch 2 taken 2068 times.
✓ Branch 3 taken 462 times.
2530 var_lst := list(BackendVariable.getVarAt(syst.orderedVars, i) for i in unfixedVars);
1453 462 (new_eqns, var_lst) := addStartValueEquations(var_lst, new_eqns, {});
1454 462 DoubleEnded.push_list_back(dumpVars, var_lst);
1455 if debug then
1456 failed_var_lst := list(var for var guard(not BackendVariable.containsVar(var, initVars)) in var_lst);
1457 BackendDump.dumpVarList(var_lst, "fixed vars");
1458 // report these in general?
1459 BackendDump.dumpVarList(failed_var_lst, "failed vars");
1460 end if;
1461
1462 // 8. success
1463 462 syst := BackendDAEUtil.setEqSystEqs(syst, BackendEquation.sortInitialEqns(new_eqns));
1464 end resolveOverAndUnderconstraints;
1465
1466 protected function fixInitialSystem "author: lochel
1467 This function handles under-, over-, and mixed-determined systems with a given index."
1468 extends constraintHandlerFunc;
1469 protected
1470 BackendDAE.EquationArray eqns2;
1471 list<BackendDAE.Var> dumpVars2 = {};
1472 list<BackendDAE.Equation> removedEqns2;
1473 Integer nVars, nEqns, nAddEqs, nAddVars;
1474 list<Integer> stateIndices, range, redundantEqns;
1475 list<BackendDAE.Var> initVarList;
1476 array<Integer> ass1 = listArray({}), ass2 = listArray({});
1477 BackendDAE.AdjacencyMatrix m "adjacency matrix of modified system";
1478 BackendDAE.AdjacencyMatrix m_ "adjacency matrix of original system (TODO: fix this one)";
1479 BackendDAE.EqSystem syst = BackendDAEUtil.createEqSystem(inEqSystem.orderedVars, inEqSystem.orderedEqs);
1480 AvlTreePathFunction.Tree funcs;
1481 array<Integer> mapIncRowEqn = listArray({});
1482 Boolean perfectMatching;
1483 Integer maxMixedDeterminedIndex = intMax(0, Flags.getConfigInt(Flags.MAX_MIXED_DETERMINED_INDEX));
1484
1485 array<Boolean> eMarks = arrayCreate(0, false), vMarks = arrayCreate(0, false);
1486 list<Integer> singular_eqns_idx, singular_vars_idx;
1487 Integer overDetIndex, underDetIndex, scalarEqnSize;
1488 BackendDAE.Equation eq;
1489 constant Boolean debug = false;
1490 algorithm
1491 ✗ for index in 0:maxMixedDeterminedIndex loop
1492 //print("index-" + intString(index) + " start\n");
1493
1494 // nVars = nEqns
1495 ✗ nVars := BackendVariable.varsSize(inEqSystem.orderedVars);
1496 ✗ nEqns := BackendEquation.equationArraySize(inEqSystem.orderedEqs);
1497 ✗ syst := BackendDAEUtil.createEqSystem(inEqSystem.orderedVars, inEqSystem.orderedEqs);
1498 ✗ funcs := BackendDAEUtil.getFunctions(inShared);
1499 ✗ (m_, _, _, mapIncRowEqn) := BackendDAEUtil.adjacencyMatrixScalar(syst, BackendDAE.SOLVABLE(), SOME(funcs), BackendDAEUtil.isInitializationDAE(inShared)); // Should always be true, just to be sure
1500 if debug then
1501 BackendDump.dumpEqSystem(syst, "fixInitialSystem");
1502 BackendDump.dumpVariables(initVars, "selected initialization variables");
1503 BackendDump.dumpVariables(inEqSystem.orderedVars, "vars in the system");
1504 BackendDump.dumpAdjacencyMatrix(m_);
1505 end if;
1506
1507 // get state-index list
1508 ✗ stateIndices := BackendVariable.getVarIndexFromVariablesIndexInFirstSet(inEqSystem.orderedVars, initVars);
1509
1510 // modify adjacency matrix for under-determined systems
1511 ✗ nAddEqs := intMax(nVars-nEqns + index, index);
1512 if debug then print("nAddEqs: " + intString(nAddEqs) + "\n"); end if;
1513 ✗ m := fixUnderDeterminedSystem(m_, stateIndices, nEqns, nAddEqs);
1514
1515 // modify adjacency matrix for over-determined systems
1516 ✗ nAddVars := intMax(nEqns-nVars + index, index);
1517 if debug then print("nAddVars: " + intString(nAddVars) + "\n"); end if;
1518 ✗ m := fixOverDeterminedSystem(m, inEqSystem.orderedEqs, nVars, nAddVars);
1519
1520 // match the system (nVars+nAddVars == nEqns+nAddEqs)
1521 //ass1 := arrayCreate(nVars+nAddVars, -1);
1522 //ass2 := arrayCreate(nEqns+nAddEqs, -1);
1523 //Matching.matchingExternalsetAdjacencyMatrix(nVars+nAddVars, nEqns+nAddEqs, m);
1524 //BackendDAEEXT.matching(nVars+nAddVars, nEqns+nAddEqs, 5, 0, 0.0, 1);
1525 //BackendDAEEXT.getAssignment(ass2, ass1);
1526 //perfectMatching := listEmpty(Matching.getUnassigned(nVars+nAddVars, ass1, {}));
1527 ✗ (ass1, ass2, perfectMatching, eMarks, vMarks) := Matching.RegularMatching(m, nVars+nAddVars, nEqns+nAddEqs);
1528 if debug then
1529 BackendDump.dumpMatchingVars(ass1);
1530 BackendDump.dumpMatchingEqns(ass2);
1531 end if;
1532
1533 // check whether or not a complete matching was found
1534 ✗ if perfectMatching then
1535 ✗ if index > 0 then
1536 ✗ Error.addCompilerNotification("The given system is mixed-determined. [index = " + intString(index) + "]");
1537 end if;
1538
1539 ✗ if nAddVars > 0 then
1540 // map artificial variables to redundant equations
1541 ✗ range := List.intRange2(nVars+1, nVars+nAddVars);
1542 ✗ redundantEqns := mapIndices(range, ass1);
1543 //print("{" + stringDelimitList(List.map(redundantEqns, intString), ",") + "}\n");
1544
1545 // symbolic consistency check
1546 ✗ consistencyCheck(redundantEqns, inEqSystem.orderedEqs, inEqSystem.orderedVars, inShared, nAddVars, m_, enhancedRows(syst, inShared), ass1, ass2, mapIncRowEqn);
1547
1548 // remove redundant equations
1549 ✗ removedEqns2 := BackendEquation.getList(redundantEqns, inEqSystem.orderedEqs);
1550 //BackendDump.dumpEquationList(removedEqns2, "removed equations");
1551 ✗ eqns2 := BackendEquation.deleteList(inEqSystem.orderedEqs, redundantEqns);
1552 //BackendDump.dumpEquationArray(eqns2, "remaining equations");
1553 ✗ DoubleEnded.push_list_back(removedEqns, removedEqns2);
1554 else
1555 ✗ eqns2 := inEqSystem.orderedEqs;
1556 end if;
1557
1558 ✗ if nAddEqs > 0 then
1559 // map artificial equations to unfixed states
1560 ✗ range := List.intRange2(nEqns+1, nEqns+nAddEqs);
1561 ✗ range := mapIndices(range, ass2);
1562 //print("{" + stringDelimitList(List.map(range, intString), ",") + "}\n");
1563
1564 // introduce additional initial equations
1565 ✗ initVarList := List.map1r(range, BackendVariable.getVarAt, inEqSystem.orderedVars);
1566 ✗ (eqns2, dumpVars2) := addStartValueEquations(initVarList, eqns2, {});
1567 //BackendDump.dumpEquationArray(eqns2, "remaining equations");
1568 //BackendDump.dumpVarList(dumpVars2,"Check fixed attribute in vars");
1569 ✗ DoubleEnded.push_list_back(dumpVars, dumpVars2);
1570 end if;
1571 ✗ outEqSystem := BackendDAEUtil.setEqSystEqs(inEqSystem, eqns2);
1572
1573 //print("index-" + intString(index) + " ende\n");
1574 //execStat("fixInitialSystem (initialization) [nEqns: " + intString(nEqns) + ", nAddEqs: " + intString(nAddEqs) + ", nAddVars: " + intString(nAddVars) + "]");
1575 ✗ return;
1576 end if;
1577 if debug then
1578 print("index-" + intString(index) + " ende\n");
1579 end if;
1580 end for;
1581
1582 ✗ if Flags.isSet(Flags.INITIALIZATION) then
1583 ✗ overDetIndex := listLength(list(i for i guard(ass1[i] < 0) in 1:arrayLength(ass1)));
1584 ✗ underDetIndex := listLength(list(i for i guard(ass2[i] < 0) in 1:arrayLength(ass2)));
1585
1586 // get singular indices from markings after pantelides matching
1587 // take care to crop the end such that the artificial variables are not taken into account
1588 ✗ singular_eqns_idx := list(i for i guard(eMarks[i]) in 1:arrayLength(mapIncRowEqn));
1589 ✗ singular_vars_idx := list(i for i guard(vMarks[i]) in 1:BackendVariable.varsSize(syst.orderedVars));
1590
1591 // get array indices from scalar indices
1592 ✗ scalarEqnSize := listLength(singular_eqns_idx);
1593 ✗ singular_eqns_idx := List.uniqueOnTrue(list(mapIncRowEqn[i] for i in singular_eqns_idx), intEq);
1594
1595 ✗ print("\n------------ UNBALANCED INITIAL SYSTEM ------------\n");
1596 ✗ print("The initial system is over- as well as underdetermined and it could not be resolved after " + intString(maxMixedDeterminedIndex) + " iterations.\n\n");
1597 ✗ print("==== OVERDETERMINATION BY " + intString(overDetIndex) + " EQUATION(S)\n");
1598 ✗ print("==== UNDERDETERMINATION OF " + intString(underDetIndex) + " VARIABLE(S)\n");
1599 ✗ print("\n---- involved set eqns (" + intString(scalarEqnSize) + "/" + intString(listLength(singular_eqns_idx)) + "):\n");
1600 ✗ for eqn in singular_eqns_idx loop
1601 ✗ eq := BackendEquation.get(syst.orderedEqs, mapIncRowEqn[eqn]);
1602 ✗ print(" " + intString(eqn) + "(" + intString(BackendEquation.equationSize(eq)) + "):\t" + BackendDump.equationString(eq) + "\n");
1603 end for;
1604 ✗ print("\n---- involved set vars (" + intString(listLength(singular_vars_idx)) + "):\n");
1605 ✗ for var in singular_vars_idx loop
1606 ✗ print(" " + intString(var) + ":\t" + BackendDump.varString(BackendVariable.getVarAt(syst.orderedVars, var)) + "\n");
1607 end for;
1608 ✗ print("--------------------------------------------------\n");
1609 end if;
1610
1611 ✗ Error.addMessage(Error.MIXED_DETERMINED, {intString(maxMixedDeterminedIndex)});
1612 ✗ fail();
1613 end fixInitialSystem;
1614
1615 protected function updateFixedAttribute
1616 "function which updates the fixed attribute of a variable"
1617 input output BackendDAE.Var var;
1618 input output BackendDAE.Variables vars;
1619 protected
1620 DAE.ComponentRef cr;
1621 algorithm
1622 350579 cr := BackendVariable.varCref(var);
1623
2/2
✓ Branch 1 taken 348476 times.
✓ Branch 2 taken 2103 times.
350579 if BackendVariable.containsCref(cr, vars) then
1624 2103 var := BackendVariable.setVarFixed(var, true);
1625 end if;
1626 end updateFixedAttribute;
1627
1628 protected function fixUnderDeterminedSystem "author: lochel"
1629 input BackendDAE.AdjacencyMatrix inM;
1630 input list<Integer> inInitVarIndices;
1631 input Integer inNEqns;
1632 input Integer inNAddEqns;
1633 output BackendDAE.AdjacencyMatrix outM;
1634 protected
1635 list<Integer> newEqIndices;
1636 algorithm
1637 ✗ if inNAddEqns < 0 then
1638 ✗ Error.addInternalError("function fixUnderDeterminedSystem failed due to invalid input", sourceInfo());
1639 ✗ fail();
1640 end if;
1641
1642 ✗ if inNAddEqns > 0 then
1643 ✗ outM := arrayCreate(inNEqns+inNAddEqns, {});
1644 ✗ outM := Array.copy(inM, outM);
1645 ✗ newEqIndices := List.intRange2(inNEqns+1, inNEqns+inNAddEqns);
1646 ✗ outM := List.fold1(newEqIndices, squareAdjacencyMatrix1, inInitVarIndices, outM);
1647 else
1648 ✗ outM := arrayCopy(inM) "deep copy";
1649 end if;
1650 end fixUnderDeterminedSystem;
1651
1652 protected function squareAdjacencyMatrix1 "author: lochel"
1653 input Integer inPos;
1654 input list<Integer> inDependency;
1655 input BackendDAE.AdjacencyMatrix inM;
1656 output BackendDAE.AdjacencyMatrix outM = inM;
1657 algorithm
1658 ✗ outM[inPos] := inDependency;
1659 end squareAdjacencyMatrix1;
1660
1661 protected function fixOverDeterminedSystem "author: lochel"
1662 input BackendDAE.AdjacencyMatrix inM;
1663 input BackendDAE.EquationArray orderedEqs;
1664 input Integer inNVars;
1665 input Integer inNAddVars;
1666 output BackendDAE.AdjacencyMatrix outM;
1667 protected
1668 list<Integer> newVarIndices, initEqsIndices;
1669 algorithm
1670 ✗ if inNAddVars < 0 then
1671 ✗ Error.addInternalError("function fixOverDeterminedSystem failed due to invalid input", sourceInfo());
1672 ✗ fail();
1673 end if;
1674
1675 ✗ if inNAddVars > 0 then
1676 ✗ initEqsIndices := getInitEqIndices(BackendEquation.equationList(orderedEqs));
1677 ✗ newVarIndices := List.intRange2(inNVars+1, inNVars+inNAddVars);
1678 ✗ outM := List.fold1(initEqsIndices, squareAdjacencyMatrix2, newVarIndices, inM);
1679 else
1680 outM := inM;
1681 end if;
1682 end fixOverDeterminedSystem;
1683
1684 protected function squareAdjacencyMatrix2 "author: lochel"
1685 input Integer inPos;
1686 input list<Integer> inRange;
1687 input BackendDAE.AdjacencyMatrix inM;
1688 output BackendDAE.AdjacencyMatrix outM = inM;
1689 algorithm
1690 ✗ outM[inPos] := listAppend(inM[inPos], inRange);
1691 end squareAdjacencyMatrix2;
1692
1693 protected function addStartValueEquations "author: lochel"
1694 input list<BackendDAE.Var> inVarLst;
1695 input BackendDAE.EquationArray inEqns;
1696 input list<BackendDAE.Var> inDumpVars;
1697 output BackendDAE.EquationArray outEqns = inEqns;
1698 output list<BackendDAE.Var> outDumpVars = inDumpVars "this are the variables that get fixed (not the same as inVarLst!)";
1699 protected
1700 BackendDAE.Var dumpVar;
1701 BackendDAE.Equation eqn;
1702 DAE.Exp e, crefExp, startExp;
1703 DAE.ComponentRef cref;
1704 DAE.Type tp;
1705 Boolean isPreCref;
1706 algorithm
1707
2/2
✓ Branch 0 taken 2124 times.
✓ Branch 1 taken 518 times.
2642 for var in inVarLst loop
1708 2124 cref := BackendVariable.varCref(var);
1709 2124 tp := BackendVariable.varType(var);
1710 2124 crefExp := DAE.CREF(cref, tp);
1711 2124 isPreCref := ComponentReference.isPreCref(cref);
1712
1713
2/2
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 1894 times.
2124 if isPreCref then
1714 230 cref := ComponentReference.popPreCref(cref);
1715 end if;
1716
1717 2124 e := Expression.crefExp(cref);
1718 2124 tp := Expression.typeof(e);
1719 2124 startExp := Expression.crefExp(ComponentReference.crefPrefixStart(cref));
1720
1721 2124 eqn := BackendDAE.EQUATION(crefExp, startExp, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
1722 2124 outEqns := BackendEquation.add(eqn, outEqns);
1723
1724
2/2
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 1894 times.
2124 if isPreCref then
1725 230 dumpVar := BackendVariable.copyVarNewName(cref, var);
1726 // crStr = BackendDump.varString(dumpVar);
1727 // fcall(Flags.INITIALIZATION, Error.addCompilerWarning, " " + crStr);
1728 230 dumpVar := BackendVariable.setVarFixed(dumpVar, true);
1729 outDumpVars := dumpVar::outDumpVars;
1730 else
1731 // crStr = BackendDump.varString(var);
1732 // fcall(Flags.INITIALIZATION, Error.addCompilerWarning, " " + crStr);
1733 1894 dumpVar := BackendVariable.setVarFixed(var, true);
1734 outDumpVars := dumpVar::outDumpVars;
1735 end if;
1736 end for;
1737 end addStartValueEquations;
1738
1739 // =============================================================================
1740 // section for symbolic consistency check
1741 //
1742 // =============================================================================
1743
1744 protected uniontype EnhancedRows
1745 "The enhanced adjacency rows of a system, computed for the equations the
1746 consistency check marks; the whole matrix differentiates every equation."
1747 record ENHANCED_ROWS
1748 BackendDAE.Variables vars;
1749 BackendDAE.EquationArray eqns;
1750 BackendDAE.Shared shared;
1751 array<Option<BackendDAE.AdjacencyMatrixElementEnhanced>> rows;
1752 array<Integer> rowmark;
1753 end ENHANCED_ROWS;
1754 end EnhancedRows;
1755
1756 protected function enhancedRows
1757 input BackendDAE.EqSystem syst;
1758 input BackendDAE.Shared shared;
1759 output EnhancedRows me;
1760 algorithm
1761 18 me := ENHANCED_ROWS(syst.orderedVars, syst.orderedEqs, shared,
1762 arrayCreate(BackendEquation.getNumberOfEquations(syst.orderedEqs), NONE()),
1763 arrayCreate(BackendVariable.varsSize(syst.orderedVars), 0));
1764 end enhancedRows;
1765
1766 protected function enhancedRow
1767 input EnhancedRows me;
1768 input Integer eqn "array equation index";
1769 output BackendDAE.AdjacencyMatrixElementEnhanced row;
1770 algorithm
1771 row := match arrayGet(me.rows, eqn)
1772 case SOME(row) then row;
1773 else
1774 algorithm
1775 43 (row, _, _) := BackendDAEUtil.adjacencyRowEnhanced(me.vars, BackendEquation.get(me.eqns, eqn), eqn, me.rowmark, me.shared.globalKnownVars, false, me.shared);
1776 43 arrayUpdate(me.rows, eqn, SOME(row));
1777 then row;
1778 end match;
1779 end enhancedRow;
1780
1781 protected function consistencyCheck "
1782 This function performs a symbolic consistency check of all detected redundant
1783 initial equations and returns three lists:
1784 - The first list contains all consistent initial conditions.
1785 - The second list contains all inconsistent initial conditions.
1786 - The third list contains all initial conditions that couldn't be checked."
1787 input list<Integer> inRedundantEqns "these are the indices of the redundant equations";
1788 input BackendDAE.EquationArray inEqns "this are all equations of the given system";
1789 input BackendDAE.Variables inVars;
1790 input BackendDAE.Shared inShared;
1791 input Integer nAddVars;
1792 input BackendDAE.AdjacencyMatrix inM;
1793 input EnhancedRows me;
1794 input array<Integer> vecVarToEqs;
1795 input array<Integer> vecEqsToVar;
1796 input array<Integer> mapIncRowEqn;
1797 output list<Integer> outConsistentEquations "These equations are consistent and can be removed from the initialization problem without any issue.";
1798 output list<Integer> outInconsistentEquations "If this list is not empty then the initialization problem is inconsistent and has no solution.";
1799 output list<Integer> outUncheckedEquations "These equations need to be checked numerically.";
1800 algorithm
1801 (outConsistentEquations, outInconsistentEquations, outUncheckedEquations) := matchcontinue inRedundantEqns
1802 local
1803 list<Integer> outRange, flatComps, markedComps;
1804 list<Integer> outLoopListComps, restRedundantEqns;
1805 list<Integer> consistentEquations, consistentEquations2, inconsistentEquations, uncheckedEquations, uncheckedEquations2;
1806 Integer nEqns, currRedundantEqn, redundantEqn;
1807 list<list<Integer>> comps;
1808 BackendVarTransform.VariableReplacements repl;
1809 BackendDAE.EquationArray substEqns;
1810
1811 case {}
1812 then ({}, {}, {});
1813
1814 case currRedundantEqn::restRedundantEqns algorithm
1815 28 nEqns := BackendEquation.equationArraySize(inEqns);
1816 //BackendDump.dumpMatchingVars(vecVarToEqs);
1817 //BackendDump.dumpMatchingEqns(vecEqsToVar);
1818 //BackendDump.dumpVariables(inVars, "inVars");
1819 //BackendDump.dumpEquationArray(inEqns, "inEqns");
1820 //BackendDump.dumpList(inRedundantEqns, "inRedundantEqns: ");
1821 //BackendDump.dumpAdjacencyMatrix(inM);
1822
1823 // get the sorting and algebraic loops
1824 28 comps := Sorting.Tarjan(inM, vecVarToEqs, nEqns);
1825 28 flatComps := List.flatten(comps);
1826 //BackendDump.dumpComponentsOLD(comps);
1827
1828 // split comps in a list with all equations that are part of a algebraic
1829 // loop and in one list with all other equations
1830 28 (_, outLoopListComps) := splitStrongComponents(comps);
1831 //BackendDump.dumpList(outListComps, "outListComps: ");
1832 //BackendDump.dumpList(outLoopListComps, "outLoopListComps: ");
1833
1834 // map indices to take care of array equations
1835 28 redundantEqn := mapIndex(currRedundantEqn, mapIncRowEqn);
1836 28 flatComps := mapIndices(flatComps, mapIncRowEqn);
1837 28 outLoopListComps := mapIndices(outLoopListComps, mapIncRowEqn);
1838 //BackendDump.dumpList(flatComps, "flatComps: ");
1839 //BackendDump.dumpList(arrayList(mapIncRowEqn), "mapIncRowEqn: ");
1840
1841 28 markedComps := compsMarker(currRedundantEqn, vecVarToEqs, inM, flatComps, outLoopListComps);
1842 //BackendDump.dumpList(markedComps, "markedComps: ");
1843
1844 25 repl := BackendVarTransform.emptyReplacements();
1845 25 repl := setupVarReplacements(markedComps, inEqns, inVars, vecEqsToVar, repl, mapIncRowEqn, me, inShared);
1846 //BackendVarTransform.dumpReplacements(repl);
1847 25 substEqns := applyVarReplacements(redundantEqn, inEqns, repl);
1848
1849
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 24 times.
25 (outRange, true, uncheckedEquations) := getConsistentEquation(redundantEqn, substEqns, inEqns, inM, vecVarToEqs, inVars, inShared, 1);
1850 24 (consistentEquations, inconsistentEquations, uncheckedEquations2) := consistencyCheck(restRedundantEqns, inEqns, inVars, inShared, nAddVars, inM, me, vecVarToEqs, vecEqsToVar, mapIncRowEqn);
1851
1852 24 consistentEquations2 := listAppend(consistentEquations, outRange);
1853 24 uncheckedEquations2 := listAppend(uncheckedEquations, uncheckedEquations2);
1854 //BackendDump.dumpList(outRange, "outRange: ");
1855 //BackendDump.dumpEquationArray(inEqns, "inEqns");
1856 //BackendDump.dumpEquationArray(substEqns, "substEqns");
1857 24 then (consistentEquations2, inconsistentEquations, uncheckedEquations2);
1858
1859 // add current equation to list of inconsistent equations
1860 case currRedundantEqn::restRedundantEqns algorithm
1861 4 (consistentEquations, inconsistentEquations, uncheckedEquations) := consistencyCheck(restRedundantEqns, inEqns, inVars, inShared, nAddVars, inM, me, vecVarToEqs, vecEqsToVar, mapIncRowEqn);
1862 4 then (consistentEquations, currRedundantEqn::inconsistentEquations, uncheckedEquations);
1863 end matchcontinue;
1864 end consistencyCheck;
1865
1866 protected function isVarExplicitSolvable
1867 input BackendDAE.AdjacencyMatrixElementEnhanced inElem;
1868 input Integer inVarID;
1869 output Boolean outSolvable;
1870 algorithm
1871 outSolvable := match inElem
1872 local
1873 Integer id;
1874 BackendDAE.AdjacencyMatrixElementEnhanced elem;
1875 Boolean b;
1876
1877 case {}
1878 then true;
1879
1880 //case (id, BackendDAE.SOLVABILITY_SOLVED())::elem guard intEq(id, inVarID)
1881 //then false;
1882
1883 case (id, BackendDAE.SOLVABILITY_UNSOLVABLE(),_)::_ guard intEq(id, inVarID)
1884 then false;
1885
1886 case (id, BackendDAE.SOLVABILITY_NONLINEAR(),_)::_ guard intEq(id, inVarID)
1887 then false;
1888
1889 case (_, _, _)::elem algorithm
1890 73 b := isVarExplicitSolvable(elem, inVarID);
1891 then b;
1892 end match;
1893 end isVarExplicitSolvable;
1894
1895 protected function splitStrongComponents "author: mwenzler"
1896 input list<list<Integer>> inComps "list of strong components";
1897 output list<Integer> outListComps "all components of size 1";
1898 output list<Integer> outLoopListComps "all components of size > 1";
1899 algorithm
1900 (outListComps, outLoopListComps) := match inComps
1901 local
1902 Integer currIndex;
1903 list<Integer> currComp, listComps, loopListComps;
1904 list<list<Integer>> restComps;
1905
1906 case {}
1907 then ({}, {});
1908
1909 case {currIndex}::restComps algorithm
1910 1626 (listComps, loopListComps) := splitStrongComponents(restComps);
1911 1626 then (currIndex::listComps, loopListComps);
1912
1913 case currComp::restComps algorithm
1914 20 (listComps, loopListComps) := splitStrongComponents(restComps);
1915 20 loopListComps := listAppend(currComp, loopListComps);
1916 then (listComps, loopListComps);
1917 end match;
1918 end splitStrongComponents;
1919
1920 protected function mapIndex "author: lochel
1921 This function applies 'inMapping' to the input index."
1922 input Integer inIndex;
1923 input array<Integer> inMapping;
1924 output Integer outIndex;
1925 algorithm
1926 189052 outIndex := inMapping[inIndex];
1927 end mapIndex;
1928
1929 protected function mapIndices "author: lochel
1930 This function applies 'inMapping' to the input index list."
1931 input list<Integer> inIndices;
1932 input array<Integer> inMapping;
1933 output list<Integer> outIndices;
1934 algorithm
1935 184605 outIndices := List.map1(inIndices, mapIndex, inMapping);
1936 end mapIndices;
1937
1938 protected function mapListIndices "author: lochel
1939 This function applies 'inMapping' to the input index list list."
1940 input list<list<Integer>> inListIndices;
1941 input array<Integer> inMapping;
1942 output list<list<Integer>> outListIndices;
1943 algorithm
1944 859 outListIndices := List.map1(inListIndices, mapIndices, inMapping);
1945 end mapListIndices;
1946
1947 protected function compsMarker "author: mwenzler"
1948 input Integer inUnassignedEqn;
1949 input array<Integer> inVecVarToEq;
1950 input BackendDAE.AdjacencyMatrix inM;
1951 input list<Integer> inFlatComps;
1952 input list<Integer> inLoopListComps "not used yet";
1953 output list<Integer> outMarkedEqns "contains all the indices of the equations that need to be considered";
1954 protected
1955 list<Integer> varList;
1956 list<Integer> markedEqns;
1957 algorithm
1958 try
1959
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
28 false := listMember(inUnassignedEqn, inLoopListComps);
1960 28 varList := inM[inUnassignedEqn];
1961 28 markedEqns := compsMarker2(varList, inVecVarToEq, inM, inFlatComps, {}, inLoopListComps);
1962
1963 28 outMarkedEqns := downCompsMarker(listReverse(inFlatComps), inVecVarToEq, inM, inFlatComps, markedEqns, inLoopListComps);
1964 else
1965 3 Error.addCompilerNotification("It was not possible to check the given initialization system for consistency symbolically, because the relevant equations are part of an algebraic loop. This is not supported yet.");
1966 3 fail();
1967 end try;
1968 end compsMarker;
1969
1970 protected function compsMarker2
1971 input list<Integer> inVarList;
1972 input array<Integer> inVecVarToEq;
1973 input BackendDAE.AdjacencyMatrix inM;
1974 input list<Integer> inFlatComps;
1975 input list<Integer> inMarkedEqns;
1976 input list<Integer> inLoopListComps;
1977 output list<Integer> outMarkedEqns;
1978 algorithm
1979 outMarkedEqns := matchcontinue inVarList
1980 local
1981 Integer indexVar, indexEq;
1982 list<Integer> var_list2;
1983 list<Integer> markedEqns;
1984
1985 case {} algorithm
1986 then inMarkedEqns;
1987
1988 case indexVar::var_list2 algorithm
1989 104 indexEq := inVecVarToEq[indexVar];
1990
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 101 times.
104 false := listMember(indexEq, inLoopListComps);
1991
2/2
✓ Branch 1 taken 49 times.
✓ Branch 2 taken 52 times.
101 false := listMember(indexEq, inMarkedEqns);
1992 52 markedEqns := compsMarker2(var_list2, inVecVarToEq, inM, inFlatComps, inMarkedEqns, inLoopListComps);
1993 then indexEq::markedEqns;
1994
1995 case indexVar::var_list2 algorithm
1996 52 indexEq := inVecVarToEq[indexVar];
1997
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 49 times.
52 false := listMember(indexEq, inLoopListComps);
1998
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 49 times.
49 true := listMember(indexEq, inMarkedEqns);
1999 49 markedEqns := compsMarker2(var_list2, inVecVarToEq, inM, inFlatComps, inMarkedEqns, inLoopListComps);
2000 then markedEqns;
2001
2002 else algorithm
2003 3 Error.addCompilerNotification("It was not possible to check the given initialization system for consistency symbolically, because the relevant equations are part of an algebraic loop. This is not supported yet.");
2004 3 then fail();
2005 end matchcontinue;
2006 end compsMarker2;
2007
2008 protected function downCompsMarker
2009 input list<Integer> unassignedEqns;
2010 input array<Integer> vecVarToEq;
2011 input BackendDAE.AdjacencyMatrix m;
2012 input list<Integer> flatComps;
2013 input output list<Integer> inMarkedEqns;
2014 input list<Integer> inLoopListComps;
2015 algorithm
2016
2/2
✓ Branch 0 taken 2857 times.
✓ Branch 1 taken 25 times.
2882 for indexUnassigned in unassignedEqns loop
2017
2/2
✓ Branch 1 taken 52 times.
✓ Branch 2 taken 2805 times.
2857 if listMember(indexUnassigned, inMarkedEqns) then
2018 52 inMarkedEqns := compsMarker2(m[indexUnassigned], vecVarToEq, m, flatComps, inMarkedEqns, inLoopListComps);
2019 end if;
2020 end for;
2021 end downCompsMarker;
2022
2023 protected function setupVarReplacements
2024 input list<Integer> inMarkedEqns;
2025 input BackendDAE.EquationArray inEqns;
2026 input BackendDAE.Variables inVars;
2027 input array<Integer> inVecEqToVar "matching";
2028 input BackendVarTransform.VariableReplacements inRepls "initially call this with empty replacements";
2029 input array<Integer> inMapIncRowEqn;
2030 input EnhancedRows inME;
2031 input BackendDAE.Shared inShared;
2032 output BackendVarTransform.VariableReplacements outRepls;
2033 algorithm
2034 outRepls := matchcontinue inMarkedEqns
2035 local
2036 Integer markedEqn;
2037 list<Integer> markedEqns;
2038 Integer indexVar, indexEq;
2039 BackendVarTransform.VariableReplacements repls;
2040 BackendDAE.Var var;
2041 DAE.ComponentRef varName;
2042 BackendDAE.Equation eqn;
2043 DAE.ComponentRef cref;
2044 BackendDAE.Type type_;
2045 DAE.Exp exp, exp1, x;
2046
2047 case {}
2048 then inRepls;
2049
2050 case markedEqn::markedEqns algorithm
2051 49 indexVar := inVecEqToVar[markedEqn];
2052 49 indexEq := inMapIncRowEqn[markedEqn];
2053
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 49 times.
49 true := isVarExplicitSolvable(enhancedRow(inME, indexEq), indexVar);
2054 49 var := BackendVariable.getVarAt(inVars, indexVar);
2055 49 eqn := BackendEquation.get(inEqns, indexEq);
2056
2057 49 cref := BackendVariable.varCref(var);
2058 49 type_ := BackendVariable.varType(var);
2059 49 x := DAE.CREF(cref, type_);
2060
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 49 times.
49 eqn as BackendDAE.EQUATION(scalar=exp) := BackendEquation.solveEquation(eqn, x, SOME(inShared.functionTree));
2061
2062 49 varName := BackendVariable.varCref(var);
2063 49 (exp1, _) := Expression.traverseExpBottomUp(exp, BackendDAEUtil.replaceCrefsWithValues, (inVars, varName));
2064 49 repls := BackendVarTransform.addReplacement(inRepls, varName, exp1, NONE());
2065 49 repls := setupVarReplacements(markedEqns, inEqns, inVars, inVecEqToVar, repls, inMapIncRowEqn, inME, inShared);
2066 then repls;
2067
2068 case _::markedEqns algorithm
2069 ✗ repls := setupVarReplacements(markedEqns, inEqns, inVars, inVecEqToVar, inRepls, inMapIncRowEqn, inME, inShared);
2070 then repls;
2071 end matchcontinue;
2072 end setupVarReplacements;
2073
2074 protected function applyVarReplacements "author: lochel
2075 This function applies variable replacements to one equation out of an equation
2076 array.
2077 Side-effects are omitted by doing a deep copy."
2078 input Integer inEqnIndex;
2079 input BackendDAE.EquationArray inEqnList;
2080 input BackendVarTransform.VariableReplacements inVarRepls;
2081 output BackendDAE.EquationArray outEqnList;
2082 protected
2083 BackendDAE.Equation eqn;
2084 algorithm
2085 25 outEqnList := BackendEquation.copyEquationArray(inEqnList) "avoid side-effects";
2086 25 eqn := BackendEquation.get(outEqnList, inEqnIndex);
2087
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 25 times.
25 ({eqn}, _) := BackendVarTransform.replaceEquations({eqn}, inVarRepls, NONE());
2088 25 outEqnList := BackendEquation.setAtIndex(outEqnList, inEqnIndex, eqn);
2089 end applyVarReplacements;
2090
2091 protected function getConsistentEquation "author: mwenzler"
2092 input Integer inUnassignedEqn;
2093 input BackendDAE.EquationArray inEqns;
2094 input BackendDAE.EquationArray inEqnsOrig;
2095 input BackendDAE.AdjacencyMatrix inM;
2096 input array<Integer> vecVarToEqs;
2097 input BackendDAE.Variables vars;
2098 input BackendDAE.Shared shared;
2099 input Integer counter;
2100 output list<Integer> outUnassignedEqns; // consistent equation
2101 output Boolean outConsistent;
2102 output list<Integer> outRemovedEqns; // problem with parameter in the equation
2103 algorithm
2104 (outUnassignedEqns, outConsistent, outRemovedEqns) := matchcontinue inUnassignedEqn
2105 local
2106 Integer nVars, nEqns;
2107 list<Integer> listVar;
2108 BackendDAE.EquationArray eqns;
2109 BackendDAE.Equation eqn, eqn2;
2110 DAE.Exp lhs, rhs, exp;
2111 list<String> listParameter;
2112 BackendDAE.AdjacencyMatrix m;
2113 BackendDAE.EqSystem system;
2114 AvlTreePathFunction.Tree funcs;
2115 list<BackendDAE.Equation> list_inEqns;
2116 Boolean anyStartValue;
2117
2118 case _ algorithm
2119 25 nVars := BackendVariable.varsSize(vars);
2120 25 nEqns := BackendEquation.equationArraySize(inEqnsOrig);
2121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 true := intLe(counter, nEqns-nVars);
2122 25 eqn := BackendEquation.get(inEqns, inUnassignedEqn);
2123
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 BackendDAE.EQUATION(exp=lhs, scalar=rhs) := eqn;
2124 25 exp := DAE.BINARY(lhs, DAE.SUB(DAE.T_REAL_DEFAULT), rhs);
2125 25 (exp, _) := ExpressionSimplify.simplify(exp);
2126
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 18 times.
25 true := Expression.isZero(exp);
2127 //listParameter = parameterCheck(exp);
2128 //true = listEmpty(listParameter);
2129 18 BackendEquation.get(inEqnsOrig, inUnassignedEqn);
2130 // Error.addCompilerNotification("The following equation is consistent and got removed from the initialization problem: " + BackendDump.equationString(eqn));
2131 then ({inUnassignedEqn}, true, {});
2132
2133 case _ algorithm
2134 7 nVars := BackendVariable.varsSize(vars);
2135 7 nEqns := BackendEquation.equationArraySize(inEqnsOrig);
2136
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 true := intGt(counter, nEqns-nVars);
2137
2138 ✗ Error.addCompilerError("Initialization problem is structural singular. Please, check the initial conditions.");
2139 then ({}, true, {});
2140
2141 case _ algorithm
2142 7 nVars := BackendVariable.varsSize(vars);
2143 7 nEqns := BackendEquation.equationArraySize(inEqnsOrig);
2144
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
13 true := intLe(counter, nEqns-nVars);
2145
2146 7 eqn := BackendEquation.get(inEqns, inUnassignedEqn);
2147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 BackendDAE.EQUATION(exp=lhs, scalar=rhs) := eqn;
2148 7 exp := DAE.BINARY(lhs, DAE.SUB(DAE.T_REAL_DEFAULT), rhs);
2149 7 (exp, _) := ExpressionSimplify.simplify(exp);
2150
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 false := Expression.isZero(exp);
2151
2152
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 2 times.
7 (listParameter, false) := parameterCheck(exp);
2153
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
2 true := listEmpty(listParameter);
2154
2155 1 eqn2 := BackendEquation.get(inEqnsOrig, inUnassignedEqn);
2156 1 Error.addCompilerError("The initialization problem is inconsistent due to the following equation: " + BackendDump.equationString(eqn2) + " (" + BackendDump.equationString(eqn) + ")");
2157 then ({}, false, {});
2158
2159 case _ algorithm
2160 6 nVars := BackendVariable.varsSize(vars);
2161 6 nEqns := BackendEquation.equationArraySize(inEqnsOrig);
2162
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 true := intLe(counter, nEqns-nVars);
2163 6 eqn := BackendEquation.get(inEqns, inUnassignedEqn);
2164
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 BackendDAE.EQUATION(exp=lhs, scalar=rhs) := eqn;
2165 6 exp := DAE.BINARY(lhs, DAE.SUB(DAE.T_REAL_DEFAULT), rhs);
2166 6 (exp, _) := ExpressionSimplify.simplify(exp);
2167
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 false := Expression.isZero(exp);
2168
2169 6 listParameter := parameterCheck(exp);
2170
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 false := listEmpty(listParameter);
2171
2172 2 list_inEqns := BackendEquation.equationList(inEqns);
2173 2 list_inEqns := List.set(list_inEqns, inUnassignedEqn, eqn);
2174 2 eqns := BackendEquation.listEquation(list_inEqns);
2175 2 funcs := BackendDAEUtil.getFunctions(shared);
2176 2 system := BackendDAEUtil.createEqSystem(vars, eqns);
2177 4 (m, _) := BackendDAEUtil.adjacencyMatrix(system, BackendDAE.NORMAL(), SOME(funcs), BackendDAEUtil.isInitializationDAE(shared));
2178 2 listVar := m[inUnassignedEqn];
2179
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 false := listEmpty(listVar);
2180
2181 ✗ BackendEquation.get(inEqnsOrig, inUnassignedEqn);
2182 ✗ Error.addCompilerNotification("It was not possible to check the given initialization system for consistency symbolically, because the relevant equations are part of an algebraic loop. This is not supported yet.");
2183 then ({}, false, {});
2184
2185 case _ algorithm
2186 //true = listEmpty(inM[inUnassignedEqn]);
2187 6 nVars := BackendVariable.varsSize(vars);
2188 6 nEqns := BackendEquation.equationArraySize(inEqnsOrig);
2189
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 true := intLe(counter, nEqns-nVars);
2190 6 eqn := BackendEquation.get(inEqns, inUnassignedEqn);
2191
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 BackendDAE.EQUATION(exp=lhs, scalar=rhs) := eqn;
2192 6 exp := DAE.BINARY(lhs, DAE.SUB(DAE.T_REAL_DEFAULT), rhs);
2193 6 (exp, _) := ExpressionSimplify.simplify(exp);
2194
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 false := Expression.isZero(exp);
2195
2196 6 (listParameter, anyStartValue) := parameterCheck(exp);
2197
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
6 true := not listEmpty(listParameter) or anyStartValue;
2198
2199 6 eqn2 := BackendEquation.get(inEqnsOrig, inUnassignedEqn);
2200 6 Error.addCompilerWarning("It was not possible to determine if the initialization problem is consistent, because of not evaluable parameters/start values during compile time: " + BackendDump.equationString(eqn2) + " (" + BackendDump.equationString(eqn) + ")");
2201 then ({}, true, {inUnassignedEqn});
2202 end matchcontinue;
2203 end getConsistentEquation;
2204
2205 protected function parameterCheck "author: mwenzler"
2206 input DAE.Exp inExp;
2207 output list<String> outParameters;
2208 output Boolean outAnyStartValue;
2209 algorithm
2210
2/2
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 6 times.
19 (_, (outParameters, outAnyStartValue)) := Expression.traverseExpTopDown(inExp, parameterCheck2, ({}, false));
2211 end parameterCheck;
2212
2213 protected function parameterCheck2
2214 input DAE.Exp inExp;
2215 input tuple<list<String> /*parameters*/, Boolean /*anyStartValue*/> inParams;
2216 output DAE.Exp outExp = inExp;
2217 output Boolean outContinue;
2218 output tuple<list<String> /*parameters*/, Boolean /*anyStartValue*/> outParams;
2219 protected
2220 DAE.ComponentRef componentRef;
2221 list<String> parameters;
2222 Boolean anyStartValue;
2223 algorithm
2224 64 (parameters, anyStartValue) := inParams;
2225 (outParams, outContinue) := match inExp
2226 case DAE.CREF(componentRef=componentRef) algorithm
2227
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 21 times.
33 if ComponentReference.isStartCref(componentRef) then
2228 anyStartValue := true;
2229 else
2230 12 parameters := ComponentReference.crefStr(componentRef)::parameters;
2231 end if;
2232
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
39 then ((parameters, anyStartValue), not anyStartValue);
2233
2234 else (inParams, true);
2235 end match;
2236 end parameterCheck2;
2237
2238
2239 // =============================================================================
2240 // section for introducing pre-variables for alias variables
2241 //
2242 // =============================================================================
2243
2244 protected function introducePreVarsForAliasVariables "author: lochel
2245 This function introduces all the pre-vars for the initial system that belong to alias vars."
2246 input BackendDAE.Var inVar;
2247 input tuple<BackendDAE.Variables, BackendDAE.Variables, BackendDAE.EquationArray, HashSet.HashSet> inTpl;
2248 output BackendDAE.Var outVar;
2249 output tuple<BackendDAE.Variables, BackendDAE.Variables, BackendDAE.EquationArray, HashSet.HashSet> outTpl;
2250 algorithm
2251 (outVar, outTpl) := matchcontinue(inVar, inTpl)
2252 local
2253 BackendDAE.Var var;
2254 DAE.ComponentRef cr;
2255 DAE.Type ty;
2256 DAE.InstDims arryDim;
2257 BackendDAE.Variables vars, fixvars;
2258 BackendDAE.EquationArray eqns;
2259 HashSet.HashSet hs;
2260
2261 Boolean preUsed, isFixed;
2262 DAE.Exp startValue;
2263 DAE.ComponentRef preCR;
2264 BackendDAE.Var preVar;
2265 BackendDAE.Equation eqn;
2266
2267 // discrete-time
2268 case (var as BackendDAE.VAR(varName=cr, varKind=BackendDAE.DISCRETE(), varType=ty, arryDim=arryDim), (vars, fixvars, eqns, hs)) algorithm
2269 4945 preUsed := BaseHashSet.has(cr, hs);
2270 4945 isFixed := BackendVariable.varFixed(var);
2271 4945 startValue := BackendVariable.varStartValue(var);
2272
2273 4945 preCR := ComponentReference.crefPrefixPre(cr); // cr => $PRE.cr
2274 4945 preVar := BackendDAE.VAR(preCR, BackendDAE.DISCRETE(), DAE.BIDIR(), DAE.NON_PARALLEL(), ty, NONE(), NONE(), arryDim, DAE.emptyElementSource, NONE(), NONE(), NONE(), NONE(), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER(), false, false, false);
2275 4945 preVar := BackendVariable.setVarFixed(preVar, false);
2276 4945 preVar := BackendVariable.setVarStartValueOption(preVar, SOME(startValue));
2277
2278 // pre(v) = v.start
2279 4945 eqn := BackendDAE.EQUATION(DAE.CREF(preCR, ty), startValue, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
2280
2281
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4945 times.
4945 vars := if preUsed then BackendVariable.addVar(preVar, vars) else vars;
2282
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4945 times.
4945 eqns := if preUsed and isFixed then BackendEquation.add(eqn, eqns) else eqns;
2283 4945 then (var, (vars, fixvars, eqns, hs));
2284
2285 // continuous-time
2286 case (var as BackendDAE.VAR(varName=cr, varType=ty, arryDim=arryDim), (vars, fixvars, eqns, hs)) algorithm
2287 100028 preUsed := BaseHashSet.has(cr, hs);
2288
2289 100028 preCR := ComponentReference.crefPrefixPre(cr); // cr => $PRE.cr
2290 100028 preVar := BackendDAE.VAR(preCR, BackendDAE.VARIABLE(), DAE.BIDIR(), DAE.NON_PARALLEL(), ty, NONE(), NONE(), arryDim, DAE.emptyElementSource, NONE(), NONE(), NONE(), NONE(), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER(), false, false, false);
2291 100028 preVar := BackendVariable.setVarFixed(preVar, false);
2292 200056 preVar := BackendVariable.setVarStartValueOption(preVar, SOME(DAE.CREF(cr, ty)));
2293
2294 // pre(v) = v
2295 100028 eqn := BackendDAE.EQUATION(DAE.CREF(preCR, ty), DAE.CREF(cr, ty), DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
2296
2297
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100028 times.
100028 vars := if preUsed then BackendVariable.addVar(preVar, vars) else vars;
2298
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100028 times.
100028 eqns := if preUsed then BackendEquation.add(eqn, eqns) else eqns;
2299 100028 then (var, (vars, fixvars, eqns, hs));
2300
2301 else (inVar, inTpl);
2302 end matchcontinue;
2303 end introducePreVarsForAliasVariables;
2304
2305 // =============================================================================
2306 // section for collecting initial vars/eqns
2307 //
2308 // =============================================================================
2309
2310 protected function collectInitialVarsEqnsSystem
2311 "This function collects variables and equations for the initial system out of an given EqSystem."
2312 input list<BackendDAE.EqSystem> eqSystems;
2313 input output BackendDAE.Variables vars;
2314 input output BackendDAE.Variables fixVars;
2315 input output BackendDAE.EquationArray eqns;
2316 input output BackendDAE.EquationArray reEqns;
2317 input HashSet.HashSet hs;
2318 input UnorderedSet<DAE.ComponentRef> allPrimaryParams;
2319 input Boolean datareconFlag;
2320 protected
2321 array<Integer> stateSetFixCounts;
2322 algorithm
2323
2/2
✓ Branch 0 taken 1583 times.
✓ Branch 1 taken 1085 times.
2668 for eq in eqSystems loop
2324 () := match eq
2325 case BackendDAE.EQSYSTEM(partitionKind = BackendDAE.CLOCKED_PARTITION())
2326 algorithm
2327 61 (vars, eqns) := BackendVariable.traverseBackendDAEVars(eq.orderedVars,
2328 collectInitialClockedVarsEqns, (vars, eqns));
2329 then
2330 ();
2331
2332 else
2333 algorithm
2334 1522 stateSetFixCounts := arrayCreate(listLength(eq.stateSets), 0);
2335
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 38 times.
3006 (vars, fixVars, eqns, stateSetFixCounts, _, _, _) := BackendVariable.traverseBackendDAEVars(eq.orderedVars,
2336 collectInitialVars, (vars, fixVars, eqns, stateSetFixCounts, hs, allPrimaryParams, datareconFlag));
2337 1522 (eqns, reEqns) := BackendEquation.traverseEquationArray(eq.orderedEqs, collectInitialEqns, (eqns, reEqns));
2338
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1522 times.
1522 if Flags.getConfigBool(Flags.INITIAL_STATE_SELECTION) then
2339 ✗ (vars, eqns) := collectInitialStateSets(eq.stateSets, stateSetFixCounts, vars, eqns);
2340 end if;
2341 1522 GCExt.free(stateSetFixCounts);
2342 then
2343 ();
2344 end match;
2345 end for;
2346 end collectInitialVarsEqnsSystem;
2347
2348 protected function collectInitialStateSets "author: kabdelhak
2349 This function collects all information from stateSets for the initial system.
2350 TODO: Implement better algorithm for stateSets which are not selfdependent."
2351 input BackendDAE.StateSets stateSets;
2352 input array<Integer> stateSetFixCounts;
2353 input BackendDAE.Variables iVars;
2354 input BackendDAE.EquationArray iEqns;
2355 output BackendDAE.Variables oVars;
2356 output BackendDAE.EquationArray oEqns;
2357
2358 protected
2359 BackendDAE.StateSet stateSet;
2360 BackendDAE.Equation eqn, initEqn;
2361 DAE.Exp lhs, rhs, exp;
2362 list<DAE.Exp> expLst = {};
2363 list<DAE.ComponentRef> crLst;
2364 list<BackendDAE.Var> statesToFix = {}, unfixedStates = {};
2365 DAE.Type tp;
2366 Integer toFix;
2367 Option<Integer> recordSize;
2368 DAE.ElementSource source;
2369 algorithm
2370 ✗ (oVars, oEqns) := (iVars, iEqns);
2371 ✗ for stateSet in stateSets loop
2372 ✗ oVars := BackendVariable.addVars(stateSet.varA, oVars);
2373 ✗ lhs := Expression.crefToExp(stateSet.crA);
2374 ✗ tp := ComponentReference.crefTypeFull(stateSet.crA);
2375 ✗ tp := DAEUtil.expTypeElementType(tp);
2376 ✗ if DAEUtil.expTypeComplex(tp) then
2377 ✗ recordSize := SOME(Expression.sizeOf(tp));
2378 else
2379 recordSize := NONE();
2380 end if;
2381
2382 expLst:={};
2383
2384 ✗ crLst := SymbolicJacobian.getJacobianDependencies(stateSet.jacobian);
2385 ✗ expLst := list(Expression.crefToExp(cr) for cr in crLst);
2386 ✗ expLst := DAE.ICONST(integer=stateSet.index-1)::expLst;
2387
2388 ✗ rhs := DAE.CALL(path=Absyn.IDENT(name="$stateSelectionSet"),expLst=expLst,attr=DAE.callAttrBuiltinOther);
2389 ✗ eqn := BackendDAE.ARRAY_EQUATION(dimSize={listLength(stateSet.varA)}, left=lhs, right=rhs,source=DAE.emptyElementSource,attr=BackendDAE.EQ_ATTR_DEFAULT_INITIAL, recordSize=recordSize);
2390 ✗ oEqns := ExpandableArray.add(eqn,oEqns);
2391
2392 ✗ if Flags.isSet(Flags.BLT_DUMP) or Flags.isSet(Flags.INITIALIZATION) then
2393 ✗ BackendDump.dumpEquationList({eqn}, "initial state selection equation generated:");
2394 end if;
2395
2396 ✗ if arrayLength(stateSetFixCounts) >= stateSet.index and arrayGet(stateSetFixCounts,stateSet.index) > 0 then
2397 unfixedStates := {};
2398 ✗ for state in stateSet.statescandidates loop
2399 ✗ if not BackendVariable.varFixed(state) then
2400 unfixedStates := state::unfixedStates;
2401 end if;
2402 end for;
2403 ✗ toFix := arrayGet(stateSetFixCounts,stateSet.index);
2404 statesToFix := {};
2405
2406 // ToDo: If selfdependent -> heuristic, if not -> add new vars and write new pivot algorithm c
2407 //if IndexReduction.isSelfDependent(stateSet) then
2408 ✗ statesToFix := SymbolicJacobian.getFixedStatesForSelfdependentSets(stateSet,unfixedStates,toFix);
2409
2410 //oVars := BackendVariable.addVars(statesToFix, oVars);
2411 //oFixVars := BackendVariable.addVars(statesToFix, oFixVars);
2412 ✗ for state in statesToFix loop
2413 ✗ lhs := Expression.crefToExp(state.varName);
2414 ✗ rhs := IndexReduction.makeStartExp(state.varName);
2415 ✗ initEqn := BackendDAE.EQUATION(exp=lhs,scalar=rhs,source=DAE.emptyElementSource,attr=BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
2416 ✗ oEqns := ExpandableArray.add(initEqn,oEqns);
2417 end for;
2418
2419 ✗ if Flags.isSet(Flags.BLT_DUMP) or Flags.isSet(Flags.INITIALIZATION) then
2420 ✗ print("StateSet " + intString(stateSet.index) + " is underconstraint for the initial system.\n");
2421 ✗ print("======================================\n");
2422 ✗ print("# States left to fix: " + intString(toFix) + ".\n");
2423 ✗ print("# Unfixed candidates: " + intString(listLength(stateSet.statescandidates)-toFix) + ".\n");
2424 ✗ BackendDump.dumpVarList(statesToFix, "Chosen states to fix:");
2425 end if;
2426 end if;
2427 end for;
2428 end collectInitialStateSets;
2429
2430 protected function collectInitialVars "author: lochel
2431 This function collects all the vars for the initial system.
2432 TODO: return additional equations for pre-variables"
2433 input BackendDAE.Var inVar;
2434 input tuple<BackendDAE.Variables, BackendDAE.Variables, BackendDAE.EquationArray, array<Integer>, HashSet.HashSet, UnorderedSet<DAE.ComponentRef>, Boolean> inTpl;
2435 output BackendDAE.Var outVar;
2436 output tuple<BackendDAE.Variables, BackendDAE.Variables, BackendDAE.EquationArray, array<Integer>, HashSet.HashSet, UnorderedSet<DAE.ComponentRef>, Boolean> outTpl;
2437 algorithm
2438 (outVar, outTpl) := matchcontinue (inVar, inTpl)
2439 local
2440 BackendDAE.Var var, preVar, derVar, startVar;
2441 BackendDAE.Variables vars, fixvars;
2442 BackendDAE.EquationArray eqns;
2443 array<Integer> stateSetFixCounts;
2444 BackendDAE.Equation eqn;
2445 DAE.ComponentRef cr, preCR, derCR, startCR;
2446 Boolean isFixed, isInput, preUsed, datarecon;
2447 DAE.Type ty;
2448 Option<DAE.Exp> startValue;
2449 DAE.Exp startValue_;
2450 DAE.Exp startExp, bindExp, crefExp;
2451 BackendDAE.VarKind varKind;
2452 HashSet.HashSet hs;
2453 String s, str, sv, stateSetIdxString;
2454 list<String> stateSetSplit;
2455 Integer stateSetIdx;
2456 SourceInfo info;
2457 UnorderedSet<DAE.ComponentRef> allPrimaryParameters;
2458 list<DAE.ComponentRef> parameters;
2459
2460 // state
2461 case (var as BackendDAE.VAR(varName=cr, varKind=BackendDAE.STATE(), varType=ty), (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters,datarecon)) algorithm
2462 7528 isFixed := BackendVariable.varFixed(var);
2463 //_ = BackendVariable.varStartValueOption(var);
2464 7528 preUsed := BaseHashSet.has(cr, hs);
2465
2466 7528 crefExp := Expression.crefExp(cr);
2467
2468 7528 startCR := ComponentReference.crefPrefixStart(cr);
2469 7528 startVar := BackendVariable.copyVarNewName(startCR, var);
2470 7528 startVar := BackendVariable.setBindExp(startVar, NONE());
2471 7528 startVar := BackendVariable.setVarDirection(startVar, DAE.BIDIR());
2472 7528 startVar := BackendVariable.setVarFixed(startVar, false);
2473 7528 startVar := BackendVariable.setVarKind(startVar, BackendDAE.VARIABLE());
2474 7528 startVar := BackendVariable.setVarStartValueOption(startVar, NONE());
2475
2476 7528 startExp := BackendVariable.varStartValue(var);
2477 7528 parameters := Expression.getAllCrefs(startExp);
2478
2479
6/6
✓ Branch 0 taken 2062 times.
✓ Branch 1 taken 7528 times.
✓ Branch 2 taken 2062 times.
✓ Branch 3 taken 7528 times.
✓ Branch 5 taken 35 times.
✓ Branch 6 taken 7493 times.
9590 if not min(UnorderedSet.contains(p, allPrimaryParameters) for p in parameters) then
2480 35 eqn := BackendDAE.EQUATION(Expression.crefExp(startCR), startExp, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
2481 35 eqns := BackendEquation.add(eqn, eqns);
2482
2483 35 vars := BackendVariable.addVar(startVar, vars);
2484 end if;
2485
2486
2/2
✓ Branch 0 taken 4389 times.
✓ Branch 1 taken 3139 times.
7528 if isFixed then
2487 // Special case for initial state selection
2488
1/4
✗ Branch 2 not taken.
✓ Branch 3 taken 4389 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
4389 if StringUtil.startsWith(ComponentReferenceBasics.crefFirstIdent(cr), "$STATESET") and Flags.getConfigBool(Flags.INITIAL_STATE_SELECTION) then
2489 ✗ stateSetSplit := Util.stringSplitAtChar(ComponentReferenceBasics.crefFirstIdent(cr),".");
2490 ✗ stateSetIdxString::stateSetSplit := stateSetSplit;
2491 ✗ stateSetIdxString := substring(stateSetIdxString,10,stringLength(stateSetIdxString));
2492 ✗ stateSetIdx := stringInt(stateSetIdxString);
2493 ✗ arrayUpdate(stateSetFixCounts, stateSetIdx, arrayGet(stateSetFixCounts, stateSetIdx) + 1);
2494 else
2495 // if startExp is constant, generate "cref = $START.cref" otherwise "cref = startExp"
2496
2/2
✓ Branch 1 taken 4313 times.
✓ Branch 2 taken 76 times.
4389 if Expression.isConstValue(startExp) then
2497 4313 eqn := BackendDAE.EQUATION(crefExp, Expression.crefExp(startCR), DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
2498 else
2499 76 eqn := BackendDAE.EQUATION(crefExp, startExp, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
2500 end if;
2501 4389 eqns := BackendEquation.add(eqn, eqns);
2502 end if;
2503 end if;
2504
2505 7528 var := BackendVariable.setVarKind(var, BackendDAE.VARIABLE());
2506
2507 7528 derCR := ComponentReference.crefPrefixDer(cr); // cr => $DER.cr
2508 7528 derVar := BackendVariable.copyVarNewName(derCR, var);
2509 7528 derVar := BackendVariable.setVarDirection(derVar, DAE.BIDIR());
2510 7528 derVar := BackendVariable.setBindExp(derVar, NONE());
2511
2512 7528 preCR := ComponentReference.crefPrefixPre(cr); // cr => $PRE.cr
2513 7528 preVar := BackendVariable.copyVarNewName(preCR, var);
2514 7528 preVar := BackendVariable.setVarDirection(preVar, DAE.BIDIR());
2515 7528 preVar := BackendVariable.setBindExp(preVar, NONE());
2516 7528 preVar := BackendVariable.setVarFixed(preVar, true);
2517 15056 preVar := BackendVariable.setVarStartValueOption(preVar, SOME(DAE.CREF(cr, ty)));
2518
2519 7528 eqn := BackendDAE.EQUATION(DAE.CREF(cr, ty), DAE.CREF(preCR, ty), DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
2520
2521 7528 vars := BackendVariable.addVar(derVar, vars);
2522 7528 vars := BackendVariable.addVar(var, vars);
2523
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 7524 times.
7528 vars := if preUsed then BackendVariable.addVar(preVar, vars) else vars;
2524
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 7524 times.
7528 eqns := if preUsed then BackendEquation.add(eqn, eqns) else eqns;
2525
2/2
✓ Branch 0 taken 7527 times.
✓ Branch 1 taken 1 time.
15055 then (var, (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters, datarecon));
2526
2527 // discrete (preUsed=true)
2528 case (var as BackendDAE.VAR(varName=cr, varKind=BackendDAE.DISCRETE(), varType=ty), (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters, datarecon)) algorithm
2529
2/2
✓ Branch 1 taken 5615 times.
✓ Branch 2 taken 1502 times.
7117 true := BaseHashSet.has(cr, hs);
2530
2/2
✓ Branch 1 taken 503 times.
✓ Branch 2 taken 999 times.
1502 true := BackendVariable.varFixed(var);
2531 999 startValue_ := BackendVariable.varStartValue(var);
2532
2533 999 var := BackendVariable.setVarFixed(var, false);
2534
2535 999 preCR := ComponentReference.crefPrefixPre(cr); // cr => $PRE.cr
2536 999 preVar := BackendVariable.copyVarNewName(preCR, var);
2537 999 preVar := BackendVariable.setVarDirection(preVar, DAE.BIDIR());
2538 999 preVar := BackendVariable.setBindExp(preVar, NONE());
2539 999 preVar := BackendVariable.setVarFixed(preVar, false);
2540 999 preVar := BackendVariable.setVarStartValueOption(preVar, SOME(startValue_));
2541
2542 999 eqn := BackendDAE.EQUATION(DAE.CREF(preCR, ty), startValue_, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
2543
2544 999 vars := BackendVariable.addVar(var, vars);
2545 999 vars := BackendVariable.addVar(preVar, vars);
2546 999 eqns := BackendEquation.add(eqn, eqns);
2547
1/2
✓ Branch 0 taken 999 times.
✗ Branch 1 not taken.
1998 then (var, (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters, datarecon));
2548
2549 // discrete
2550 case (var as BackendDAE.VAR(varName=cr, varKind=BackendDAE.DISCRETE()), (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters, datarecon)) algorithm
2551 6118 preUsed := BaseHashSet.has(cr, hs);
2552 6118 startValue := BackendVariable.varStartValueOption(var);
2553
2554 6118 var := BackendVariable.setVarFixed(var, false);
2555
2556 6118 preCR := ComponentReference.crefPrefixPre(cr); // cr => $PRE.cr
2557 6118 preVar := BackendVariable.copyVarNewName(preCR, var);
2558 6118 preVar := BackendVariable.setVarDirection(preVar, DAE.BIDIR());
2559 6118 preVar := BackendVariable.setBindExp(preVar, NONE());
2560 6118 preVar := BackendVariable.setVarFixed(preVar, false);
2561 6118 preVar := BackendVariable.setVarStartValueOption(preVar, startValue);
2562
2563 6118 vars := BackendVariable.addVar(var, vars);
2564
2/2
✓ Branch 0 taken 503 times.
✓ Branch 1 taken 5615 times.
6118 vars := if preUsed then BackendVariable.addVar(preVar, vars) else vars;
2565
1/2
✓ Branch 0 taken 6118 times.
✗ Branch 1 not taken.
12236 then (var, (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters, datarecon));
2566
2567 // parameter without binding and fixed=true
2568 case (var as BackendDAE.VAR(varName=cr, varKind=BackendDAE.PARAM(), bindExp=NONE()), (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters, datarecon)) algorithm
2569
1/2
✓ Branch 1 taken 935 times.
✗ Branch 2 not taken.
935 true := BackendVariable.varFixed(var);
2570 ✗ startExp := BackendVariable.varStartValueType(var);
2571
2572 ✗ s := ComponentReferenceBasics.printComponentRefStr(cr);
2573 ✗ str := ExpressionBasics.printExpStr(startExp);
2574
2575 // e = Expression.crefExp(cr);
2576 // ty = Expression.typeof(e);
2577 // startExp = Expression.crefExp(ComponentReference.crefPrefixStart(cr));
2578
2579 ✗ var := BackendVariable.setVarKind(var, BackendDAE.VARIABLE());
2580 ✗ var := BackendVariable.setBindExp(var, SOME(startExp));
2581 ✗ var := BackendVariable.setVarFixed(var, true);
2582
2583 ✗ info := ElementSource.getElementSourceFileInfo(BackendVariable.getVarSource(var));
2584 ✗ Error.addSourceMessage(Error.UNBOUND_PARAMETER_WITH_START_VALUE_WARNING, {s, str}, info);
2585
2586 //vars = BackendVariable.addVar(var, vars);
2587 ✗ then (var, (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters, datarecon));
2588
2589 // parameter with binding and fixed=false
2590 case (var as BackendDAE.VAR(varName=cr, varKind=BackendDAE.PARAM(), bindExp=SOME(bindExp), varType=ty), (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters, datarecon)) algorithm
2591
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 480 times.
480 true := intGt(Flags.getConfigEnum(Flags.LANGUAGE_STANDARD), 31);
2592
2/2
✓ Branch 1 taken 474 times.
✓ Branch 2 taken 6 times.
480 false := BackendVariable.varFixed(var);
2593 6 var := BackendVariable.setVarKind(var, BackendDAE.VARIABLE());
2594 6 var := BackendVariable.setBindExp(var, NONE());
2595
2596 6 s := ComponentReferenceBasics.printComponentRefStr(cr);
2597 6 str := ExpressionBasics.printExpStr(bindExp);
2598 6 info := ElementSource.getElementSourceFileInfo(BackendVariable.getVarSource(var));
2599 6 Error.addSourceMessage(Error.UNFIXED_PARAMETER_WITH_BINDING, {s, s, str}, info);
2600
2601 6 eqn := BackendDAE.EQUATION(DAE.CREF(cr, ty), bindExp, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
2602 6 eqns := BackendEquation.add(eqn, eqns);
2603
2604 6 vars := BackendVariable.addVar(var, vars);
2605
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
12 then (var, (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters, datarecon));
2606
2607 // *** MODELICA 3.1 COMPATIBLE ***
2608 // parameter with binding and fixed=false and no start value
2609 // use the binding as start value
2610 case (var as BackendDAE.VAR(varName=cr, varKind=BackendDAE.PARAM(), bindExp=SOME(bindExp)), (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters, datarecon)) algorithm
2611
1/2
✓ Branch 1 taken 474 times.
✗ Branch 2 not taken.
474 true := intLe(Flags.getConfigEnum(Flags.LANGUAGE_STANDARD), 31);
2612 ✗ false := BackendVariable.varFixed(var);
2613 ✗ var := BackendVariable.setVarKind(var, BackendDAE.VARIABLE());
2614 ✗ var := BackendVariable.setBindExp(var, NONE());
2615 ✗ NONE() := BackendVariable.varStartValueOption(var);
2616 ✗ var := BackendVariable.setVarStartValue(var, bindExp);
2617
2618 ✗ s := ComponentReferenceBasics.printComponentRefStr(cr);
2619 ✗ str := ExpressionBasics.printExpStr(bindExp);
2620 ✗ info := ElementSource.getElementSourceFileInfo(BackendVariable.getVarSource(var));
2621 ✗ Error.addSourceMessage(Error.UNFIXED_PARAMETER_WITH_BINDING_31, {s, s, str}, info);
2622
2623 ✗ vars := BackendVariable.addVar(var, vars);
2624 ✗ then (var, (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters, datarecon));
2625
2626 // *** MODELICA 3.1 COMPATIBLE ***
2627 // parameter with binding and fixed=false and a start value
2628 // ignore the binding and use the start value
2629 case (var as BackendDAE.VAR(varName=cr, varKind=BackendDAE.PARAM(), bindExp=SOME(bindExp)), (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters, datarecon)) algorithm
2630
1/2
✓ Branch 1 taken 474 times.
✗ Branch 2 not taken.
474 true := intLe(Flags.getConfigEnum(Flags.LANGUAGE_STANDARD), 31);
2631 ✗ false := BackendVariable.varFixed(var);
2632 ✗ var := BackendVariable.setVarKind(var, BackendDAE.VARIABLE());
2633 ✗ var := BackendVariable.setBindExp(var, NONE());
2634 ✗ SOME(startExp) := BackendVariable.varStartValueOption(var);
2635
2636 ✗ s := ComponentReferenceBasics.printComponentRefStr(cr);
2637 ✗ str := ExpressionBasics.printExpStr(bindExp);
2638 ✗ sv := ExpressionBasics.printExpStr(startExp);
2639 ✗ info := ElementSource.getElementSourceFileInfo(BackendVariable.getVarSource(var));
2640 ✗ Error.addSourceMessage(Error.UNFIXED_PARAMETER_WITH_BINDING_AND_START_VALUE_31, {s, sv, s, str}, info);
2641
2642 ✗ vars := BackendVariable.addVar(var, vars);
2643 ✗ then (var, (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters, datarecon));
2644
2645 // secondary parameter
2646 case (var as BackendDAE.VAR(varKind=BackendDAE.PARAM()), (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters, datarecon)) algorithm
2647 //true = BackendVariable.varFixed(var);
2648 1409 var := BackendVariable.setVarKind(var, BackendDAE.VARIABLE());
2649 1409 vars := BackendVariable.addVar(var, vars);
2650
1/2
✓ Branch 0 taken 1409 times.
✗ Branch 1 not taken.
2818 then (var, (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters, datarecon));
2651
2652 // external objects
2653 case (var as BackendDAE.VAR(varKind=BackendDAE.EXTOBJ()), (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters, datarecon)) algorithm
2654 //var = BackendVariable.setVarFixed(var, false);
2655 //var = BackendVariable.setVarKind(var, BackendDAE.VARIABLE());
2656 1 vars := BackendVariable.addVar(var, vars);
2657
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
2 then (var, (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters, datarecon));
2658
2659 // skip constant
2660 case (var as BackendDAE.VAR(varKind=BackendDAE.CONST()), _) // equation
2661 // fixvars = BackendVariable.addVar(var, fixvars);
2662 then (var, inTpl);
2663
2664 // VARIABLE (fixed=true)
2665 // DUMMY_STATE
2666 case (var as BackendDAE.VAR(varName=cr, varType=ty), (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters, datarecon)) algorithm
2667
2/2
✓ Branch 1 taken 89252 times.
✓ Branch 2 taken 127 times.
89379 true := BackendVariable.varFixed(var);
2668 // check if dataReconciliation is present and set the Input variables to true, as Qualified components are not handled as toplevel inputs
2669
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 127 times.
127 if datarecon then
2670 ✗ isInput := checkComponentNames(var.varDirection, cr);
2671 else
2672 127 isInput := BackendVariable.isVarOnTopLevelAndInput(var);
2673 end if;
2674 127 preUsed := BaseHashSet.has(cr, hs);
2675
2676 127 startCR := ComponentReference.crefPrefixStart(cr);
2677 127 startVar := BackendVariable.copyVarNewName(startCR, var);
2678 127 startVar := BackendVariable.setBindExp(startVar, NONE());
2679 127 startVar := BackendVariable.setVarDirection(startVar, DAE.BIDIR());
2680 127 startVar := BackendVariable.setVarFixed(startVar, false);
2681 127 startVar := BackendVariable.setVarKind(startVar, BackendDAE.VARIABLE());
2682 127 startVar := BackendVariable.setVarStartValueOption(startVar, NONE());
2683
2684 127 startExp := BackendVariable.varStartValue(var);
2685 127 parameters := Expression.getAllCrefs(startExp);
2686
2687
5/6
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 127 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 127 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 127 times.
139 if not min(UnorderedSet.contains(p, allPrimaryParameters) for p in parameters) then
2688 ✗ eqn := BackendDAE.EQUATION(Expression.crefExp(startCR), startExp, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
2689 ✗ eqns := BackendEquation.add(eqn, eqns);
2690
2691 ✗ vars := BackendVariable.addVar(startVar, vars);
2692 end if;
2693
2694 127 var := BackendVariable.setVarFixed(var, false);
2695
2696 127 preCR := ComponentReference.crefPrefixPre(cr); // cr => $PRE.cr
2697 127 preVar := BackendVariable.copyVarNewName(preCR, var);
2698 127 preVar := BackendVariable.setVarDirection(preVar, DAE.BIDIR());
2699 127 preVar := BackendVariable.setBindExp(preVar, NONE());
2700 127 preVar := BackendVariable.setVarFixed(preVar, true);
2701 254 preVar := BackendVariable.setVarStartValueOption(preVar, SOME(DAE.CREF(cr, ty)));
2702
2703 // if startExp is constant, generate "cref = $START.cref" otherwise "cref = startExp"
2704
2/2
✓ Branch 1 taken 115 times.
✓ Branch 2 taken 12 times.
127 if Expression.isConstValue(startExp) then
2705 115 eqn := BackendDAE.EQUATION(DAE.CREF(cr, ty), Expression.crefExp(startCR), DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
2706 else
2707 12 eqn := BackendDAE.EQUATION(DAE.CREF(cr, ty), startExp, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
2708 end if;
2709
2710
1/2
✓ Branch 0 taken 127 times.
✗ Branch 1 not taken.
127 vars := if not isInput then BackendVariable.addVar(var, vars) else vars;
2711
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 127 times.
127 fixvars := if isInput then BackendVariable.addVar(var, fixvars) else fixvars;
2712
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 127 times.
127 vars := if preUsed then BackendVariable.addVar(preVar, vars) else vars;
2713 127 eqns := BackendEquation.add(eqn, eqns);
2714
2715 // Error.addCompilerNotification("VARIABLE (fixed=true): " + BackendDump.varString(var));
2716
1/2
✓ Branch 0 taken 127 times.
✗ Branch 1 not taken.
254 then (var, (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters, datarecon));
2717
2718 // VARIABLE (fixed=false)
2719 // DUMMY_STATE
2720 case (var as BackendDAE.VAR(varName=cr, varType=ty), (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters, datarecon)) algorithm
2721
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 89252 times.
89252 false := BackendVariable.varFixed(var);
2722 // check if dataReconciliation is present and set the Input variables to true, as Qualified components are not handled as toplevel inputs
2723
2/2
✓ Branch 0 taken 691 times.
✓ Branch 1 taken 88561 times.
89252 if datarecon then
2724 691 isInput := checkComponentNames(var.varDirection, cr);
2725 else
2726 88561 isInput := BackendVariable.isVarOnTopLevelAndInput(var);
2727 end if;
2728 89252 preUsed := BaseHashSet.has(cr, hs);
2729
2730 89252 startCR := ComponentReference.crefPrefixStart(cr);
2731 89252 startVar := BackendVariable.copyVarNewName(startCR, var);
2732 89252 startVar := BackendVariable.setBindExp(startVar, NONE());
2733 89252 startVar := BackendVariable.setVarDirection(startVar, DAE.BIDIR());
2734 89252 startVar := BackendVariable.setVarFixed(startVar, false);
2735 89252 startVar := BackendVariable.setVarKind(startVar, BackendDAE.VARIABLE());
2736 89252 startVar := BackendVariable.setVarStartValueOption(startVar, NONE());
2737
2738 89252 startExp := BackendVariable.varStartValue(var);
2739 89252 parameters := Expression.getAllCrefs(startExp);
2740
2741
6/6
✓ Branch 0 taken 6050 times.
✓ Branch 1 taken 89252 times.
✓ Branch 2 taken 6050 times.
✓ Branch 3 taken 89252 times.
✓ Branch 5 taken 297 times.
✓ Branch 6 taken 88955 times.
95302 if not min(UnorderedSet.contains(p, allPrimaryParameters) for p in parameters) then
2742 297 eqn := BackendDAE.EQUATION(Expression.crefExp(startCR), startExp, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
2743 297 eqns := BackendEquation.add(eqn, eqns);
2744
2745 297 vars := BackendVariable.addVar(startVar, vars);
2746 end if;
2747
2748 89252 preCR := ComponentReference.crefPrefixPre(cr); // cr => $PRE.cr
2749 89252 preVar := BackendVariable.copyVarNewName(preCR, var);
2750 89252 preVar := BackendVariable.setVarDirection(preVar, DAE.BIDIR());
2751 89252 preVar := BackendVariable.setBindExp(preVar, NONE());
2752 89252 preVar := BackendVariable.setVarFixed(preVar, true);
2753 178504 preVar := BackendVariable.setVarStartValueOption(preVar, SOME(DAE.CREF(cr, ty)));
2754
2755 // if startExp is constant, generate "cref = $START.cref" otherwise "cref = startExp"
2756
2/2
✓ Branch 1 taken 85295 times.
✓ Branch 2 taken 3957 times.
89252 if Expression.isConstValue(startExp) then
2757 85295 eqn := BackendDAE.EQUATION(DAE.CREF(preCR, ty), DAE.CREF(cr, ty), DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
2758 else
2759 3957 eqn := BackendDAE.EQUATION(DAE.CREF(preCR, ty), startExp, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
2760 end if;
2761
2762
2/2
✓ Branch 0 taken 88957 times.
✓ Branch 1 taken 295 times.
89252 vars := if not isInput then BackendVariable.addVar(var, vars) else vars;
2763
2/2
✓ Branch 0 taken 295 times.
✓ Branch 1 taken 88957 times.
89252 fixvars := if isInput then BackendVariable.addVar(var, fixvars) else fixvars;
2764
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 89251 times.
89252 vars := if preUsed then BackendVariable.addVar(preVar, vars) else vars;
2765
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 89251 times.
89252 eqns := if preUsed then BackendEquation.add(eqn, eqns) else eqns;
2766
2767 // Error.addCompilerNotification("VARIABLE (fixed=false); " + BackendDump.varString(var));
2768
2/2
✓ Branch 0 taken 88561 times.
✓ Branch 1 taken 691 times.
177813 then (var, (vars, fixvars, eqns, stateSetFixCounts, hs, allPrimaryParameters, datarecon));
2769
2770 else algorithm
2771 ✗ Error.addInternalError("function collectInitialVars failed for: " + BackendDump.varString(inVar), sourceInfo());
2772 ✗ then fail();
2773 end matchcontinue;
2774 end collectInitialVars;
2775
2776 protected function checkComponentNames "author: arun
2777 This is a special function which sets the inputs for dataReconciliation
2778 Inorder to handle Qualified component names as inputs."
2779 input DAE.VarDirection inVarDirection;
2780 input DAE.ComponentRef inComponentRef;
2781 output Boolean isTopLevel;
2782 algorithm
2783 isTopLevel := match (inVarDirection, inComponentRef)
2784 case (DAE.INPUT(), DAE.CREF_IDENT()) then true;
2785 case (DAE.INPUT(), DAE.CREF_QUAL()) then true;
2786 case (_ , _) then false;
2787 end match;
2788 end checkComponentNames;
2789
2790 protected function collectInitialClockedVarsEqns "author: rfranke
2791 This function creates initial equations for a clocked partition.
2792 Previous states are initialized with the respective states, states with their start values."
2793 input BackendDAE.Var inVar;
2794 input tuple<BackendDAE.Variables, BackendDAE.EquationArray> inTpl;
2795 output BackendDAE.Var outVar;
2796 output tuple<BackendDAE.Variables, BackendDAE.EquationArray> outTpl;
2797 protected
2798 BackendDAE.Variables vars;
2799 BackendDAE.EquationArray eqns;
2800 algorithm
2801 529 (vars, eqns) := inTpl;
2802 (outVar, outTpl) := match inVar
2803 local
2804 BackendDAE.Var var;
2805 BackendDAE.VarKind kind;
2806 DAE.ComponentRef cr;
2807 DAE.Type ty;
2808 DAE.Exp crExp, startExp;
2809 case var as BackendDAE.VAR(varName=cr, varType=ty, varKind=kind) algorithm
2810 529 crExp := Expression.crefExp(cr);
2811 // create previous variable and initial equation for discrete states
2812 (vars, eqns) := match kind
2813 local
2814 BackendDAE.Var previousVar;
2815 DAE.ComponentRef previousCR;
2816 DAE.Exp previousExp;
2817 case BackendDAE.CLOCKED_STATE(previousName=previousCR) algorithm
2818 197 previousVar := BackendVariable.copyVarNewName(previousCR, var);
2819 197 previousVar := BackendVariable.setVarKind(previousVar, BackendDAE.VARIABLE());
2820 197 previousVar := BackendVariable.setVarDirection(previousVar, DAE.BIDIR());
2821 197 previousVar := BackendVariable.setBindExp(previousVar, NONE());
2822 197 previousVar := BackendVariable.setVarFixed(previousVar, true);
2823 394 previousVar := BackendVariable.setVarStartValueOption(previousVar, SOME(DAE.CREF(cr, ty)));
2824 197 previousExp := Expression.crefExp(previousCR);
2825 197 vars := BackendVariable.addVar(previousVar, vars);
2826 197 eqns := BackendEquation.add(BackendDAE.EQUATION(previousExp, crExp, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_INITIAL), eqns);
2827 // add clocked state and initial equation
2828 197 startExp := BackendVariable.varStartValue(var);
2829 197 vars := BackendVariable.addVar(var, vars);
2830 197 eqns := BackendEquation.add(BackendDAE.EQUATION(crExp, startExp, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_INITIAL), eqns);
2831 then (vars, eqns);
2832 else (vars, eqns);
2833 end match;
2834 529 then (var, (vars, eqns));
2835 end match;
2836 end collectInitialClockedVarsEqns;
2837
2838 protected function collectInitialEqns "author: lochel"
2839 input BackendDAE.Equation inEq;
2840 input tuple<BackendDAE.EquationArray, BackendDAE.EquationArray> inTpl;
2841 output BackendDAE.Equation outEq = inEq;
2842 output tuple<BackendDAE.EquationArray, BackendDAE.EquationArray> outTpl;
2843 protected
2844 BackendDAE.Equation eqn1;
2845 BackendDAE.EquationArray eqns, reeqns;
2846 Integer size;
2847 Boolean b;
2848 algorithm
2849 57798 (eqns, reeqns) := inTpl;
2850
2851 // replace der(x) with $DER.x and replace pre(x) with $PRE.x
2852 57798 (eqn1, _) := BackendEquation.traverseExpsOfEquation(inEq, Expression.traverseSubexpressionsDummyHelper, replaceDerPreCref);
2853
2854 // add it, if size is zero (terminate, assert, noretcall) move to removed equations
2855 57798 size := BackendEquation.equationSize(eqn1);
2856 b := intGt(size, 0);
2857
2858
2/2
✓ Branch 0 taken 57046 times.
✓ Branch 1 taken 752 times.
57798 eqns := if b then BackendEquation.add(eqn1, eqns) else eqns;
2859
2/2
✓ Branch 0 taken 752 times.
✓ Branch 1 taken 57046 times.
57798 reeqns := if not b then BackendEquation.add(eqn1, reeqns) else reeqns;
2860 57798 outTpl := (eqns, reeqns);
2861 end collectInitialEqns;
2862
2863 protected function replaceDerPreCref
2864 input DAE.Exp inExp;
2865 output DAE.Exp outExp;
2866 algorithm
2867 outExp := match inExp
2868 local
2869 DAE.ComponentRef dummyder, cr;
2870 DAE.Type ty;
2871
2872 case DAE.CALL(path = Absyn.IDENT(name="der"), expLst = {DAE.CREF(componentRef=cr)}, attr=DAE.CALL_ATTR(ty=ty)) algorithm
2873 10144 dummyder := ComponentReference.crefPrefixDer(cr);
2874 10144 then DAE.CREF(dummyder, ty);
2875
2876 case DAE.CALL(path = Absyn.IDENT(name="pre"), expLst = {DAE.CREF(componentRef=cr)}, attr=DAE.CALL_ATTR(ty=ty)) algorithm
2877 2027 dummyder := ComponentReference.crefPrefixPre(cr);
2878 2027 then DAE.CREF(dummyder, ty);
2879
2880 case DAE.CALL(path = Absyn.IDENT(name="previous"), expLst = {DAE.CREF(componentRef=cr)}, attr=DAE.CALL_ATTR(ty=ty)) algorithm
2881 ✗ dummyder := ComponentReference.crefPrefixPrevious(cr);
2882 ✗ then DAE.CREF(dummyder, ty);
2883
2884 else inExp;
2885 end match;
2886 end replaceDerPreCref;
2887
2888 // =============================================================================
2889 // section for bindings
2890 //
2891 // =============================================================================
2892
2893 protected function collectInitialBindings "author: lochel
2894 This function collects all the vars for the initial system."
2895 input BackendDAE.Var inVar;
2896 input tuple<BackendDAE.EquationArray, BackendDAE.EquationArray> inTpl;
2897 output BackendDAE.Var outVar;
2898 output tuple<BackendDAE.EquationArray, BackendDAE.EquationArray> outTpl;
2899 algorithm
2900 (outVar, outTpl) := match (inVar, inTpl)
2901 local
2902 BackendDAE.Var var;
2903 DAE.ComponentRef cr;
2904 DAE.Type ty, basic_ty;
2905 BackendDAE.EquationArray eqns, reeqns;
2906 DAE.Exp bindExp, crefExp;
2907 DAE.ElementSource source;
2908 BackendDAE.Equation eqn;
2909 Option<Integer> record_size;
2910
2911 // no binding
2912 case (var as BackendDAE.VAR(bindExp=NONE()), _) algorithm
2913 then (var, inTpl);
2914
2915 // external object with binding
2916 case (var as BackendDAE.VAR(varName=cr, bindExp=SOME(bindExp), varKind=BackendDAE.EXTOBJ(), source=source), (eqns, reeqns)) algorithm
2917 1 eqn := BackendDAE.SOLVED_EQUATION(cr, bindExp, source, BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
2918 1 eqns := BackendEquation.add(eqn, eqns);
2919 1 then (var, (eqns, reeqns));
2920
2921 // binding
2922 case (var as BackendDAE.VAR(varName=cr, bindExp=SOME(bindExp), varType=ty, source=source), (eqns, reeqns)) algorithm
2923 43674 crefExp := DAE.CREF(cr, ty);
2924
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 43671 times.
43674 if Types.isArray(ty) then
2925 3 basic_ty := Types.getBasicType(ty);
2926
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 record_size := if Types.isRecord(basic_ty) then SOME(Types.getDimensionProduct(basic_ty)) else NONE();
2927 3 eqn := BackendDAE.ARRAY_EQUATION(Types.getDimensionSizes(ty), crefExp, bindExp, source, BackendDAE.EQ_ATTR_DEFAULT_INITIAL, record_size);
2928 else
2929 43671 eqn := BackendDAE.EQUATION(crefExp, bindExp, source, BackendDAE.EQ_ATTR_DEFAULT_INITIAL);
2930 end if;
2931 43674 eqns := BackendEquation.add(eqn, eqns);
2932 43674 then (var, (eqns, reeqns));
2933
2934 else algorithm
2935 ✗ Error.addInternalError("function collectInitialBindings failed for: " + BackendDump.varString(inVar), sourceInfo());
2936 ✗ then fail();
2937 end match;
2938 end collectInitialBindings;
2939
2940
2941 // =============================================================================
2942 // section for post-optimization module "removeInitializationStuff"
2943 //
2944 // =============================================================================
2945
2946 public function removeInitializationStuff
2947 input BackendDAE.BackendDAE inDAE;
2948 output BackendDAE.BackendDAE outDAE = inDAE;
2949 protected
2950 list<BackendDAE.Equation> removedEqsList = {};
2951 BackendDAE.Shared shared = inDAE.shared;
2952 algorithm
2953
2/2
✓ Branch 0 taken 1583 times.
✓ Branch 1 taken 1085 times.
2668 for eqs in outDAE.eqs loop
2954 1583 BackendDAEUtil.traverseBackendDAEExpsEqns(eqs.orderedEqs, removeInitializationStuff1, false);
2955 1583 BackendDAEUtil.traverseBackendDAEExpsEqns(eqs.removedEqs, removeInitializationStuff1, false);
2956 end for;
2957
2958 1085 BackendDAEUtil.traverseBackendDAEExpsEqns(shared.removedEqs, removeInitializationStuff1, false);
2959
2/2
✓ Branch 2 taken 706 times.
✓ Branch 3 taken 1085 times.
1791 for eq in BackendEquation.equationList(shared.removedEqs) loop
2960 removedEqsList := match BackendEquation.equationKind(eq)
2961 case BackendDAE.INITIAL_EQUATION() then removedEqsList;
2962 706 else filterWhenEquation(eq, removedEqsList);
2963 end match;
2964 end for;
2965 1085 shared.removedEqs := BackendEquation.listEquation(listReverse(removedEqsList));
2966 shared.initialEqs := BackendEquation.emptyEqns();
2967 1085 outDAE.shared := shared;
2968 end removeInitializationStuff;
2969
2970 protected function filterWhenEquation
2971 input BackendDAE.Equation inEqn;
2972 input list<BackendDAE.Equation> inEqnLst;
2973 output list<BackendDAE.Equation> outEqnLst;
2974 protected
2975 DAE.Exp condition;
2976 algorithm
2977 outEqnLst := match inEqn
2978 case BackendDAE.WHEN_EQUATION(whenEquation=BackendDAE.WHEN_STMTS(condition=condition, elsewhenPart=NONE())) guard listEmpty(BackendDAEUtil.getConditionList(condition)) then inEqnLst;
2979 else inEqn::inEqnLst;
2980 end match;
2981 end filterWhenEquation;
2982
2983 protected function removeInitializationStuff1
2984 input DAE.Exp inExp;
2985 input Boolean inUseHomotopy;
2986 output DAE.Exp outExp;
2987 output Boolean outUseHomotopy;
2988 algorithm
2989
3/4
✓ Branch 0 taken 101549 times.
✓ Branch 1 taken 19180 times.
✓ Branch 3 taken 120729 times.
✗ Branch 4 not taken.
222278 (outExp, outUseHomotopy) := Expression.traverseExpBottomUp(inExp, removeInitializationStuff2, inUseHomotopy);
2990 end removeInitializationStuff1;
2991
2992 protected function removeInitializationStuff2
2993 input DAE.Exp inExp;
2994 input Boolean inUseHomotopy;
2995 output DAE.Exp outExp;
2996 output Boolean outUseHomotopy;
2997 algorithm
2998 (outExp, outUseHomotopy) := match inExp
2999 local
3000 DAE.Exp actual;
3001
3002 // replace initial() with false
3003 case DAE.CALL(path=Absyn.IDENT(name="initial"))
3004 then (DAE.BCONST(false), inUseHomotopy);
3005
3006 // replace homotopy(actual, simplified) with actual, EXCEPT in DAE mode where
3007 // we keep homotopy() in the simulation residual so the runtime can
3008 // regularize a (possibly singular) initial DAE Jacobian via a lambda
3009 // continuation. The homotopy macro is simplified*(1-lambda)+actual*lambda;
3010 // once lambda=1 this is identical to using actual, so normal DAE-mode
3011 // behaviour is unchanged.
3012 case DAE.CALL(path=Absyn.IDENT(name="homotopy"), expLst=actual::_::_)
3013
2/2
✓ Branch 1 taken 275 times.
✓ Branch 2 taken 8 times.
283 then (if Flags.getConfigBool(Flags.DAE_MODE) then inExp else actual, true);
3014
3015 else (inExp, inUseHomotopy);
3016 end match;
3017 end removeInitializationStuff2;
3018
3019
3020 // =============================================================================
3021 // section for post-optimization module "replaceHomotopyWithSimplified"
3022 //
3023 // =============================================================================
3024
3025 public function replaceHomotopyWithSimplified
3026 input BackendDAE.BackendDAE inDAE;
3027 output BackendDAE.BackendDAE outDAE = inDAE;
3028 algorithm
3029 ✗ outDAE.eqs := list(replaceHomotopyWithSimplifiedEqs(eqs) for eqs in outDAE.eqs);
3030 end replaceHomotopyWithSimplified;
3031
3032 public function replaceHomotopyWithSimplifiedEqs
3033 input output BackendDAE.EqSystem eqs;
3034 algorithm
3035 35 BackendDAEUtil.traverseBackendDAEExpsEqns(eqs.orderedEqs, replaceHomotopyWithSimplified1, false);
3036 35 BackendDAEUtil.traverseBackendDAEExpsEqns(eqs.removedEqs, replaceHomotopyWithSimplified1, false);
3037 35 eqs := BackendDAEUtil.clearEqSyst(eqs);
3038 end replaceHomotopyWithSimplifiedEqs;
3039
3040 protected function replaceHomotopyWithSimplified1
3041 input DAE.Exp inExp;
3042 input Boolean inUseHomotopy;
3043 output DAE.Exp outExp;
3044 output Boolean outUseHomotopy;
3045 algorithm
3046
3/4
✓ Branch 0 taken 10070 times.
✓ Branch 1 taken 23636 times.
✓ Branch 3 taken 33706 times.
✗ Branch 4 not taken.
43776 (outExp, outUseHomotopy) := Expression.traverseExpBottomUp(inExp, replaceHomotopyWithSimplified2, inUseHomotopy);
3047 end replaceHomotopyWithSimplified1;
3048
3049 protected function replaceHomotopyWithSimplified2
3050 input DAE.Exp inExp;
3051 input Boolean inUseHomotopy;
3052 output DAE.Exp outExp;
3053 output Boolean outUseHomotopy;
3054 algorithm
3055 (outExp, outUseHomotopy) := match inExp
3056 local
3057 DAE.Exp simplified;
3058
3059 // replace homotopy(actual, simplified) with simplified
3060 case DAE.CALL(path=Absyn.IDENT(name="homotopy"), expLst=_::simplified::_)
3061 then (simplified, true);
3062
3063 else (inExp, inUseHomotopy);
3064 end match;
3065 end replaceHomotopyWithSimplified2;
3066
3067 annotation(__OpenModelica_Interface="backend");
3068 end Initialization;
3069