Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 55.9% 95 / 0 / 170
Functions: -% 0 / 1 / 1
Branches: 44.0% 44 / 0 / 100

OMCompiler/Compiler/BackEnd/DAEMode.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 DAEMode
37 " file: DAEMode.mo
38 package: DAEMode
39 description: This module prepares BackendDAE equations to solve
40 to pass them directly to a DAE solver.
41
42 Therefor all equations are transformed to residual form:
43 residualVar = eqRHS - eqLHS
44
45 "
46 public
47
48 import BackendDAE;
49
50 protected
51
52 import Array;
53 import BackendDAEOptimize;
54 import BackendDAEUtil;
55 import BackendDAEFunc;
56 import BackendDump;
57 import BackendEquation;
58 import BackendVariable;
59 import CheckModel;
60 import ComponentReference;
61 import Config;
62 import DAE;
63 import Error;
64 import ErrorExt;
65 import ExecStat.execStat;
66 import Expression;
67 import ExpressionDump;
68 import ExpressionSolve;
69 import Flags;
70 import FlagsUtil;
71 import Global;
72 import Initialization;
73 import List;
74 import Matching;
75 import StackOverflow;
76 import Util;
77
78 public function getEqSystemDAEmode "Run the equation system pipeline."
79 input BackendDAE.BackendDAE inDAE;
80 input String fileNamePrefix;
81 input Option<list<String>> strPreOptModules = NONE();
82 input Option<String> strmatchingAlgorithm = NONE();
83 input Option<String> strdaeHandler = NONE();
84 input Option<list<String>> strPostOptModules = NONE();
85 output BackendDAE.BackendDAE outDAEmode;
86 output BackendDAE.BackendDAE outInitDAE;
87 output Option<BackendDAE.BackendDAE> outInitDAE_lambda0_option;
88 output list<BackendDAE.Equation> outRemovedInitialEquationLst;
89 protected
90 BackendDAE.BackendDAE dae, simDAE;
91 list<tuple<BackendDAEFunc.optimizationModule, String>> preOptModules;
92 list<tuple<BackendDAEFunc.optimizationModule, String>> postOptModules;
93 tuple<BackendDAEFunc.StructurallySingularSystemHandlerFunc, String, BackendDAEFunc.stateDeselectionFunc, String> daeHandler;
94 tuple<BackendDAEFunc.matchingAlgorithmFunc, String> matchingAlgorithm;
95 BackendDAE.Variables globalKnownVars;
96 Integer numCheckpoints, oldSize;
97 algorithm
98 9 numCheckpoints:=ErrorExt.getNumCheckpoints();
99 try
100 9 StackOverflow.clearStacktraceMessages();
101 9 preOptModules := BackendDAEUtil.getPreOptModules(strPreOptModules);
102 9 postOptModules := BackendDAEUtil.getPostOptModules(match strPostOptModules case NONE() then SOME(getPostOptModulesDAEString()); else strPostOptModules; end match);
103 9 matchingAlgorithm := BackendDAEUtil.getMatchingAlgorithm(strmatchingAlgorithm);
104 9 FlagsUtil.setConfigString(Flags.INDEX_REDUCTION_METHOD, "dummyDerivatives");
105 9 daeHandler := BackendDAEUtil.getIndexReductionMethod(strdaeHandler);
106
107
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
9 if Flags.isSet(Flags.DUMP_DAE_LOW) then
108 ✗ BackendDump.dumpBackendDAE(inDAE, "dumpdaelow");
109 ✗ if Flags.isSet(Flags.ADDITIONAL_GRAPHVIZ_DUMP) then
110 ✗ BackendDump.graphvizAdjacencyMatrix(inDAE, "dumpdaelow");
111 end if;
112 end if;
113
114 // pre-optimization phase
115 9 dae := BackendDAEUtil.preOptimizeDAE(inDAE, preOptModules);
116
117 9 execStat("pre-optimization done (n="+String(BackendDAEUtil.daeSize(dae))+")");
118 // transformation phase (matching and sorting using index reduction method)
119 9 dae := BackendDAEUtil.causalizeDAE(dae, NONE(), matchingAlgorithm, daeHandler, true);
120 9 execStat("matching and sorting (n="+String(BackendDAEUtil.daeSize(dae))+")");
121
122
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
9 if Flags.isSet(Flags.GRAPHML) then
123 ✗ BackendDump.dumpBipartiteGraphDAE(dae, fileNamePrefix);
124 end if;
125
126
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
9 if Flags.isSet(Flags.EVAL_OUTPUT_ONLY) then
127 ✗ oldSize := BackendDAEUtil.daeSize(dae);
128 ✗ dae := BackendDAEOptimize.evaluateOutputsOnly(dae);
129 ✗ execStat("evaluateOutputsOnly (n=" + intString(oldSize) + " -> n=" + intString(BackendDAEUtil.daeSize(dae)) + ")");
130 end if;
131
132
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
9 if Flags.isSet(Flags.BLT_DUMP) then
133 ✗ BackendDump.bltdump("bltdump", dae);
134 end if;
135
136 // generate system for initialization
137 9 (outInitDAE, outInitDAE_lambda0_option, outRemovedInitialEquationLst, globalKnownVars, dae) := Initialization.solveInitialSystem(dae);
138
139 // use function tree from initDAE further for simDAE
140 9 simDAE := BackendDAEUtil.setFunctionTree(dae, BackendDAEUtil.getFunctions(outInitDAE.shared));
141
142 // Set updated globalKnownVars
143 9 simDAE := BackendDAEUtil.setDAEGlobalKnownVars(simDAE, globalKnownVars);
144 9 simDAE := BackendDAEOptimize.addInitialStmtsToAlgorithms(simDAE, false);
145 9 simDAE := Initialization.removeInitializationStuff(simDAE);
146
147 // post-optimization phase
148 // use preOpt instead
149 9 simDAE := BackendDAEUtil.postOptimizeDAE(simDAE, postOptModules, matchingAlgorithm, daeHandler);
150
151 // sort the globalKnownVars
152 9 simDAE := BackendDAEUtil.sortGlobalKnownVarsInDAE(simDAE);
153
154 // debug dump
155
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
9 if Flags.isSet(Flags.DUMP_INDX_DAE) then
156 ✗ BackendDump.dumpBackendDAE(simDAE, "dumpindxdae");
157 end if;
158
159 outDAEmode := simDAE;
160
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 return;
161 else
162 ✗ setGlobalRoot(Global.stackoverFlowIndex, NONE());
163 ✗ ErrorExt.rollbackNumCheckpoints(ErrorExt.getNumCheckpoints()-numCheckpoints);
164 ✗ Error.addInternalError(StackOverflow.errorPrefix() + " in "+getInstanceName()+"...\n"+stringDelimitList(StackOverflow.readableStacktraceMessages(), "\n"), sourceInfo());
165 /* Do not fail or we can loop too much */
166 ✗ StackOverflow.clearStacktraceMessages();
167 end try annotation(__OpenModelica_stackOverflowCheckpoint=true);
168 ✗ fail();
169 end getEqSystemDAEmode;
170
171 /*
172 get config function
173 */
174 protected function getPostOptModulesDAEString
175 output list<String> strpostOptModules;
176 algorithm
177 9 strpostOptModules := Config.getPostOptModulesDAE();
178 end getPostOptModulesDAEString;
179
180
181 // =============================================================================
182 // public section for createDAEmodeBDAE
183 //
184 // =============================================================================
185 public
186
187 function createDAEmodeBDAE
188 " This modules creates a BDAE with residual Variables."
189 input BackendDAE.BackendDAE inDAE;
190 output BackendDAE.BackendDAE outDAE;
191 algorithm
192 9 outDAE := BackendDAEUtil.mapEqSystem(inDAE, createDAEmodeEqSystem);
193 end createDAEmodeBDAE;
194
195
196 // =============================================================================
197 // protected section for createDAEmodeBDAE
198 //
199 // =============================================================================
200 protected
201
202 uniontype TraverseEqnAryFold
203 record TRAVERSER_CREATE_DAE
204 BackendDAE.BackendDAEModeData globalDAEData;
205 BackendDAE.Variables newDAEVars;
206 BackendDAE.EquationArray newDAEEquations;
207 BackendDAE.Variables systemVars;
208 AvlTreePathFunction.Tree functionTree;
209 Boolean recursiveStrongComponentRun;
210 BackendDAE.Shared shared;
211 end TRAVERSER_CREATE_DAE;
212 end TraverseEqnAryFold;
213
214 function createDAEmodeEqSystem
215 "The main to create equations by adding auxiliary variables
216 and auxiliary equations of the form $auxExp = rhs, $resVar = $auxExp - lhs"
217 input output BackendDAE.EqSystem syst;
218 input output BackendDAE.Shared shared;
219 protected
220 TraverseEqnAryFold travArgs;
221 BackendDAE.BackendDAEModeData globalDAEData;
222 BackendDAE.EqSystem retSystem;
223 BackendDAE.Variables newDAEVars;
224 BackendDAE.EquationArray newDAEEquations;
225 Integer systemSize;
226 Boolean debug = Flags.isSet(Flags.DEBUG_DAEMODE);
227 constant Boolean exec = false;
228 algorithm
229 13 globalDAEData := shared.daeModeData;
230 13 systemSize := BackendDAEUtil.systemSize(syst);
231 13 newDAEVars := BackendVariable.emptyVars();
232 13 newDAEEquations := BackendEquation.emptyEqnsSized(systemSize);
233 13 travArgs := TRAVERSER_CREATE_DAE(globalDAEData, newDAEVars, newDAEEquations, syst.orderedVars, shared.functionTree, false, shared);
234
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if debug then BackendDump.printEqSystem(syst); end if;
235 // for every equation create corresponding residiual variable(s)
236 13 travArgs := BackendDAEUtil.traverseEqSystemStrongComponents(syst, traverserStrongComponents, travArgs);
237 if exec then execStat("DAEmode: created residual equations for system size : " + intString(BackendDAEUtil.systemSize(syst)) + ": " ); end if;
238 13 globalDAEData := travArgs.globalDAEData;
239
240 // add systemVars to modelVars
241
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 4 times.
13 if isSome(globalDAEData.modelVars) then
242 8 globalDAEData.modelVars := SOME(BackendVariable.addVariables(travArgs.systemVars, Util.getOption(globalDAEData.modelVars)));
243 else
244 9 globalDAEData.modelVars := SOME(travArgs.systemVars);
245 end if;
246 if exec then execStat("DAEmode: adding residual variables: " + intString(BackendVariable.varsSize(Util.getOption(globalDAEData.modelVars))) + ": " ); end if;
247
248 // create residual system
249 13 retSystem := BackendDAEUtil.createEqSystem(travArgs.newDAEVars);
250 13 retSystem := BackendDAEUtil.setEqSystEqs(retSystem, travArgs.newDAEEquations);
251 13 retSystem := BackendDAEUtil.setEqSystRemovedEqns(retSystem, syst.removedEqs);
252 13 retSystem := BackendEquation.requationsAddDAE(ExpandableArray.toList(shared.removedEqs), retSystem);
253
254 if exec then execStat("DAEmode: created system: " + intString(BackendDAEUtil.systemSize(retSystem)) + ": " ); end if;
255
256 syst := retSystem;
257
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 shared.daeModeData := globalDAEData;
258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if debug then BackendDump.printEqSystem(syst); end if;
259
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if debug then BackendDump.dumpBackendDAEModeData(globalDAEData); end if;
260
261 end createDAEmodeEqSystem;
262
263 function traverserStrongComponents
264 "This function prepares an equation system for
265 the dae mode by dividing the equations into
266 aux equations and residual equations.
267 "
268 input list<BackendDAE.Equation> inEqns;
269 input list<BackendDAE.Var> inVars;
270 input list<Integer> varIdxs;
271 input list<Integer> eqnIdxs;
272 input output TraverseEqnAryFold traverserArgs;
273 protected
274 list<BackendDAE.Var> vars = inVars;
275 list<DAE.ComponentRef> varCrefLst;
276 Boolean recursiveStrongComponentRun;
277 Boolean isStateVarInvolved, isDiscrete;
278 algorithm
279
4/4
✓ Branch 0 taken 5927 times.
✓ Branch 1 taken 5202 times.
✓ Branch 2 taken 5927 times.
✓ Branch 3 taken 5202 times.
11129 varCrefLst := list(v.varName for v in inVars);
280
281
3/4
✓ Branch 1 taken 5202 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3257 times.
✓ Branch 5 taken 1945 times.
5202 isStateVarInvolved := not Flags.getConfigBool(Flags.CAUSALIZE_DAE_MODE) or List.any(inVars, BackendVariable.isStateVar);
282 5202 isDiscrete := List.any(inVars, BackendVariable.isVarDiscrete);
283
284 traverserArgs :=
285 matchcontinue(inEqns, traverserArgs.recursiveStrongComponentRun, isStateVarInvolved, isDiscrete)
286 local
287
288 list<BackendDAE.Equation> newResEqns;
289 list<BackendDAE.Var> newResVars, newAuxVars, discVars, contVars;
290 BackendDAE.Var var;
291 BackendDAE.Variables systemVars;
292 BackendDAE.Equation eq, new_eq, aux_eq;
293 Integer size, newnumResVars;
294 DAE.Exp exp;
295 BackendDAE.BackendDAEModeData globalDAEData;
296 DAE.ComponentRef cref, newCref;
297 list<DAE.ComponentRef> crlst;
298 Boolean b1, b2;
299 list<BackendDAE.Equation> discEqns;
300 list<BackendDAE.Equation> contEqns;
301
302 DAE.Algorithm alg;
303 DAE.ElementSource source;
304 DAE.Expand crefExpand;
305
306 constant Boolean debug = false;
307
308 case ({eq}, false, false, _)
309 guard(List.all(vars, BackendVariable.isCSEVar))
310 algorithm
311
4/4
✓ Branch 0 taken 145 times.
✓ Branch 1 taken 31 times.
✓ Branch 2 taken 145 times.
✓ Branch 3 taken 31 times.
176 newResVars := list(BackendVariable.setVarKind(v, BackendDAE.DAE_AUX_VAR()) for v in vars);
312 31 new_eq := BackendEquation.setEquationAttributes(eq, BackendDAE.EQ_ATTR_DEFAULT_AUX);
313 31 traverserArgs.newDAEVars := BackendVariable.addNewVars(newResVars, traverserArgs.newDAEVars);
314 31 traverserArgs.newDAEEquations := BackendEquation.addList({new_eq}, traverserArgs.newDAEEquations);
315 31 traverserArgs.systemVars := BackendVariable.removeCrefs(varCrefLst, traverserArgs.systemVars);
316 if debug then print("[DAEmode] Added solved aux vars. vars:\n" +
317 BackendDump.varListString(vars, "") + "eq:\n" +
318 BackendDump.equationListString({eq}, "") + "\n"); end if;
319 then
320 (traverserArgs);
321
322 case ({eq}, false, _, true)
323 algorithm
324 17 new_eq := BackendEquation.setEquationAttributes(eq, BackendDAE.EQ_ATTR_DEFAULT_DISCRETE);
325 17 traverserArgs.newDAEVars := BackendVariable.addNewVars(vars, traverserArgs.newDAEVars);
326 17 traverserArgs.newDAEEquations := BackendEquation.addList({new_eq}, traverserArgs.newDAEEquations);
327 if debug then print("[DAEmode] Create solved discrete equation. vars:\n" +
328 BackendDump.varListString(vars, "") + "eq:\n" +
329 BackendDump.equationListString({new_eq}, "") + "\n"); end if;
330 then
331 (traverserArgs);
332
333 case ({eq as BackendDAE.WHEN_EQUATION()}, false, _, _)
334 algorithm
335 ✗ new_eq := BackendEquation.setEquationAttributes(eq, BackendDAE.EQ_ATTR_DEFAULT_DISCRETE);
336 ✗ traverserArgs.newDAEVars := BackendVariable.addNewVars(vars, traverserArgs.newDAEVars);
337 ✗ traverserArgs.newDAEEquations := BackendEquation.addList({new_eq}, traverserArgs.newDAEEquations);
338 if debug then print("[DAEmode] Create solved when equation. vars:\n" +
339 BackendDump.varListString(vars, "") + "eq:\n" +
340 BackendDump.equationListString({new_eq}, "") + "\n"); end if;
341 then
342 (traverserArgs);
343
344 case ({eq as BackendDAE.EQUATION()}, false, false, _)
345 algorithm
346
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1345 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1345 times.
1345 {var} := vars;
347 1345 eq.exp := ExpressionSolve.solve(eq.exp, eq.scalar, Expression.crefExp(var.varName));
348 1344 new_eq := BackendDAE.SOLVED_EQUATION(var.varName, eq.exp, eq.source, eq.attr);
349 1344 new_eq := BackendEquation.setEquationAttributes(new_eq, BackendDAE.EQ_ATTR_DEFAULT_AUX);
350 1344 traverserArgs.newDAEVars := BackendVariable.addNewVars(vars, traverserArgs.newDAEVars);
351 1344 traverserArgs.newDAEEquations := BackendEquation.addList({new_eq}, traverserArgs.newDAEEquations);
352 if debug then print("[DAEmode] Create solved equation. vars:\n" +
353 BackendDump.varListString(vars, "") + "eq:\n" +
354 BackendDump.equationListString({new_eq}, "") + "\n"); end if;
355 then
356 (traverserArgs);
357
358 case ({eq as BackendDAE.COMPLEX_EQUATION()}, false, false, _)
359 algorithm
360 ✗ new_eq := BackendEquation.setEquationAttributes(eq, BackendDAE.EQ_ATTR_DEFAULT_AUX);
361 ✗ traverserArgs.newDAEVars := BackendVariable.addNewVars(vars, traverserArgs.newDAEVars);
362 ✗ traverserArgs.newDAEEquations := BackendEquation.addList({new_eq}, traverserArgs.newDAEEquations);
363 if debug then print("[DAEmode] Create solved complex equation. vars:\n" +
364 BackendDump.varListString(vars, "") + "eq:\n" +
365 BackendDump.equationListString({new_eq}, "") + "\n"); end if;
366 then
367 (traverserArgs);
368
369 case ({eq as BackendDAE.ARRAY_EQUATION()}, false, false, _)
370 algorithm
371 ✗ new_eq := BackendEquation.setEquationAttributes(eq, BackendDAE.EQ_ATTR_DEFAULT_AUX);
372 ✗ traverserArgs.newDAEVars := BackendVariable.addNewVars(vars, traverserArgs.newDAEVars);
373 ✗ traverserArgs.newDAEEquations := BackendEquation.addList({new_eq}, traverserArgs.newDAEEquations);
374 if debug then print("[DAEmode] Create solved array equations. vars:\n" +
375 BackendDump.varListString(vars, "") + "eq:\n" +
376 BackendDump.equationListString({new_eq}, "") + "\n"); end if;
377 then
378 (traverserArgs);
379
380 case ({eq as BackendDAE.ALGORITHM(alg=alg, source=source, expand=crefExpand)}, false, false, _)
381 algorithm
382 // check that all vars
383 ✗ true := CheckModel.isCrefListAlgorithmOutput(varCrefLst, alg, source, crefExpand);
384 ✗ new_eq := BackendEquation.setEquationAttributes(eq, BackendDAE.EQ_ATTR_DEFAULT_AUX);
385 ✗ traverserArgs.newDAEVars := BackendVariable.addNewVars(vars, traverserArgs.newDAEVars);
386 ✗ traverserArgs.newDAEEquations := BackendEquation.addList({new_eq}, traverserArgs.newDAEEquations);
387 if debug then print("[DAEmode] Create solved algorithms. vars:\n" +
388 BackendDump.varListString(vars, "") + "eq:\n" +
389 BackendDump.equationListString({new_eq}, "") + "\n"); end if;
390 then
391 (traverserArgs);
392
393 // a = f(...) and a is an array
394 case ({eq as BackendDAE.ARRAY_EQUATION(left=exp)}, b1, b2, _)
395 guard ( Expression.isCref(exp) and (b1 or b2))
396 algorithm
397 globalDAEData := traverserArgs.globalDAEData;
398
399 ✗ cref := Expression.expCref(exp);
400
401 // create aux variables for recordCref
402 ✗ newAuxVars := BackendVariable.getVar(cref, traverserArgs.systemVars);
403 ✗ crlst := ComponentReference.expandCref(cref, true);
404 ✗ newAuxVars := list(BackendVariable.copyVarNewName(ComponentReference.crefPrefixAux(cr), v) threaded for cr in crlst, v in newAuxVars);
405 ✗ newAuxVars := list(BackendVariable.setVarKind(v, BackendDAE.DAE_AUX_VAR()) for v in newAuxVars);
406 ✗ traverserArgs.newDAEVars := BackendVariable.addNewVars(newAuxVars, traverserArgs.newDAEVars);
407
408 // create aux equation aux = f(...)
409 ✗ newCref := ComponentReference.crefPrefixAux(cref);
410 ✗ eq.left := Expression.crefExp(newCref);
411 aux_eq := eq;
412
413 ✗ aux_eq := BackendEquation.setEquationAttributes(aux_eq, BackendDAE.EQ_ATTR_DEFAULT_AUX);
414 ✗ traverserArgs.newDAEEquations := BackendEquation.addList({aux_eq}, traverserArgs.newDAEEquations);
415
416 // prepare res equation aux = recordCref
417 ✗ globalDAEData := traverserArgs.globalDAEData;
418 ✗ eq.right := Expression.crefToExp(cref);
419 ✗ newResEqns := BackendEquation.equationToScalarResidualForm(eq, traverserArgs.functionTree);
420 //if debug then print("case: new eqns:\n" + BackendDump.dumpEqnsStr(newResEqns) + "\n"); end if;
421 ✗ (newResEqns, newResVars, newnumResVars) := BackendEquation.convertResidualsIntoSolvedEquations(newResEqns,
422 "$DAEres", globalDAEData.numResVars, true);
423 ✗ globalDAEData.numResVars := newnumResVars;
424 ✗ newResEqns := list(BackendEquation.setEquationAttributes(e, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC) for e in newResEqns);
425 ✗ traverserArgs.newDAEVars := BackendVariable.addNewVars(newResVars, traverserArgs.newDAEVars);
426 ✗ traverserArgs.newDAEEquations := BackendEquation.addList(newResEqns, traverserArgs.newDAEEquations);
427 ✗ globalDAEData := addVarsGlobalData(globalDAEData, vars);
428
429 ✗ traverserArgs.globalDAEData := globalDAEData;
430 if debug then print("[DAEmode] Added residual array equation\n" +
431 BackendDump.varListString(newResVars, "") + "states:\n" +
432 BackendDump.varListString(vars, "") + "eqs:\n" +
433 BackendDump.equationListString(newResEqns, "") + "\n"); end if;
434 then
435 (traverserArgs);
436
437 case ({eq}, b1, b2, _)
438 guard ( b1 or b2)
439 algorithm
440 3800 globalDAEData := traverserArgs.globalDAEData;
441 3800 newResEqns := BackendEquation.equationToScalarResidualForm(eq, traverserArgs.functionTree);
442 3800 (newResEqns, newResVars, newnumResVars) := BackendEquation.convertResidualsIntoSolvedEquations(newResEqns,
443 "$DAEres", globalDAEData.numResVars, true);
444 3800 globalDAEData.numResVars := newnumResVars;
445
4/4
✓ Branch 0 taken 3800 times.
✓ Branch 1 taken 3800 times.
✓ Branch 2 taken 3800 times.
✓ Branch 3 taken 3800 times.
7600 newResEqns := list(BackendEquation.setEquationAttributes(e, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC) for e in newResEqns);
446 3800 traverserArgs.newDAEVars := BackendVariable.addNewVars(newResVars, traverserArgs.newDAEVars);
447 3800 traverserArgs.newDAEEquations := BackendEquation.addList(newResEqns, traverserArgs.newDAEEquations);
448 3800 globalDAEData := addVarsGlobalData(globalDAEData, vars);
449 3800 traverserArgs.globalDAEData := globalDAEData;
450 if debug then print("[DAEmode] Added strong component or state eqns\n" +
451 BackendDump.varListString(newResVars, "") + "states:\n" +
452 BackendDump.varListString(vars, "") + "eqs:\n" +
453 BackendDump.equationListString(newResEqns, "") + "\n"); end if;
454 then
455 (traverserArgs);
456
457 // recordCref = f(...)
458 case ({eq as BackendDAE.COMPLEX_EQUATION(left=exp)}, _, _, _)
459 guard(Expression.isCref(exp))
460 //guard( List.all(list(ComponentReference.crefTypeFull(v.varName) for v in vars), Expression.isRecordType))
461 algorithm
462 if debug then print("case: Complex: " + BackendDump.equationListString(inEqns, "") + "\n"); end if;
463 /*
464 if debug then print("case: left: " + ExpressionDump.dumpExpStr(exp ,0) + "\n"); end if;
465 if debug then print("case: right: " + ExpressionDump.dumpExpStr(exp2,0) + "\n"); end if;
466 */
467 ✗ cref := Expression.expCref(exp);
468
469 // create aux variables for recordCref
470 ✗ newAuxVars := list(BackendVariable.copyVarNewName(ComponentReference.crefPrefixAux(cr), v) threaded for cr in varCrefLst, v in vars);
471 ✗ newAuxVars := list(BackendVariable.setVarKind(v, BackendDAE.DAE_AUX_VAR()) for v in newAuxVars);
472 ✗ traverserArgs.newDAEVars := BackendVariable.addNewVars(newAuxVars, traverserArgs.newDAEVars);
473
474 // create aux equation aux = f(...)
475 ✗ newCref := ComponentReference.crefPrefixAux(cref);
476 ✗ eq.left := Expression.crefToExp(newCref);
477 aux_eq := eq;
478
479 ✗ aux_eq := BackendEquation.setEquationAttributes(aux_eq, BackendDAE.EQ_ATTR_DEFAULT_AUX);
480 ✗ traverserArgs.newDAEEquations := BackendEquation.addList({aux_eq}, traverserArgs.newDAEEquations);
481
482 // prepare res equation aux = recordCref
483 ✗ globalDAEData := traverserArgs.globalDAEData;
484 ✗ eq.right := Expression.crefToExp(cref);
485 ✗ newResEqns := BackendEquation.equationToScalarResidualForm(eq, traverserArgs.functionTree);
486 //if debug then print("case: new eqns:\n" + BackendDump.dumpEqnsStr(newResEqns) + "\n"); end if;
487 ✗ (newResEqns, newResVars, newnumResVars) := BackendEquation.convertResidualsIntoSolvedEquations(newResEqns,
488 "$DAEres", globalDAEData.numResVars, true);
489 ✗ globalDAEData.numResVars := newnumResVars;
490 ✗ newResEqns := list(BackendEquation.setEquationAttributes(e, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC) for e in newResEqns);
491 ✗ traverserArgs.newDAEVars := BackendVariable.addNewVars(newResVars, traverserArgs.newDAEVars);
492 ✗ traverserArgs.newDAEEquations := BackendEquation.addList(newResEqns, traverserArgs.newDAEEquations);
493 ✗ globalDAEData := addVarsGlobalData(globalDAEData, vars);
494 ✗ traverserArgs.globalDAEData := globalDAEData;
495 if debug then print("[DAEmode] Added complex residual equation with aux variables. Res-vars:\n" +
496 BackendDump.varListString(newResVars, "") + "eqs:\n" +
497 BackendDump.equationListString(newResEqns, "") + "aux vars:\n" +
498 BackendDump.varListString(newAuxVars, "") + "aux eq:\n" +
499 BackendDump.equationListString({aux_eq}, "") + "\n");
500 end if;
501 then
502 (traverserArgs);
503
504 case(_, false, _, _)
505 algorithm
506
507 10 (discVars, contVars) := List.splitOnTrue(inVars, BackendVariable.isVarDiscrete);
508 10 (discEqns, contEqns) := getDiscAndContEqns(inVars, inEqns, discVars, contVars, traverserArgs.shared.functionTree, BackendDAEUtil.isInitializationDAE(traverserArgs.shared));
509
510 // create discrete
511
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 for e in discEqns loop
512 ✗ size := BackendEquation.equationSize(e);
513 ✗ newAuxVars := List.firstN(discVars, size);
514 ✗ traverserArgs := traverserStrongComponents({e}, newAuxVars, {}, {}, traverserArgs);
515 ✗ discVars := List.stripN(discVars, size);
516 end for;
517
518 // create continuous
519
2/2
✓ Branch 0 taken 561 times.
✓ Branch 1 taken 10 times.
571 for e in contEqns loop
520 561 size := BackendEquation.equationSize(e);
521 561 newAuxVars := List.firstN(contVars, size);
522 561 traverserArgs.recursiveStrongComponentRun := true;
523 561 traverserArgs := traverserStrongComponents({e}, newAuxVars, {}, {}, traverserArgs);
524 561 traverserArgs.recursiveStrongComponentRun := false;
525 561 contVars := List.stripN(contVars, size);
526 end for;
527 10 then
528 (traverserArgs);
529
530 else algorithm
531 ✗ Error.addInternalError("DAEMode.traverserStrongComponents failed on equation:\n" +
532 BackendDump.equationListString(inEqns, "") + "\nVariables:\n" +
533 BackendDump.varListString(inVars, "") + "\n", sourceInfo());
534 ✗ then fail();
535
536 end matchcontinue;
537 end traverserStrongComponents;
538
539 function getDiscAndContEqns
540 input list<BackendDAE.Var> inAllVars;
541 input list<BackendDAE.Equation> inAllEqns;
542 input list<BackendDAE.Var> inDiscVars;
543 input list<BackendDAE.Var> inContVars;
544 input AvlTreePathFunction.Tree functionTree;
545 input Boolean isInitial;
546 output list<BackendDAE.Equation> discEqns;
547 output list<BackendDAE.Equation> contEqns;
548 protected
549 BackendDAE.EqSystem syst;
550 BackendDAE.AdjacencyMatrix adjMatrix;
551
552 list<Integer> varsIndex, eqnIndex;
553 array<Integer> assignVarEqn "eqn := assignVarEqn[var]";
554 array<Integer> assignEqnVar "var := assignEqnVar[eqn]";
555
556 array<Integer> mapEqnScalarArray;
557 constant Boolean debug = false;
558 algorithm
559 try
560 // create syst for a matching
561 10 syst := BackendDAEUtil.createEqSystem(BackendVariable.listVar1(inAllVars), BackendEquation.listEquation(inAllEqns) );
562 if debug then BackendDump.printEqSystem(syst); end if;
563 10 (adjMatrix, _, _, mapEqnScalarArray) := BackendDAEUtil.adjacencyMatrixScalar(syst, BackendDAE.NORMAL(), SOME(functionTree), isInitial);
564 if debug then BackendDump.dumpAdjacencyMatrix(adjMatrix); end if;
565
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
10 (assignVarEqn, assignEqnVar, true, _, _) := Matching.RegularMatching(adjMatrix, BackendDAEUtil.systemSize(syst), BackendDAEUtil.systemSize(syst));
566 if debug then BackendDump.dumpMatching(assignVarEqn); end if;
567
568 // get discrete vars indexes and then the equations
569 10 varsIndex := BackendVariable.getVarIndexFromVars(inDiscVars, syst.orderedVars);
570 if debug then print("discVarsIndex: "); BackendDump.dumpAdjacencyRow(varsIndex); end if;
571 10 eqnIndex := List.map1(varsIndex, Array.getIndexFirst, assignVarEqn);
572 if debug then print("discEqnIndex: "); BackendDump.dumpAdjacencyRow(eqnIndex); end if;
573
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 eqnIndex := List.unique(list(mapEqnScalarArray[i] for i in eqnIndex));
574 10 discEqns := BackendEquation.getList(eqnIndex, syst.orderedEqs);
575 if debug then BackendDump.equationListString(discEqns, "Discrete Equations"); end if;
576
577 // get continuous equations
578 10 varsIndex := BackendVariable.getVarIndexFromVars(inContVars, syst.orderedVars);
579 10 eqnIndex := List.map1(varsIndex, Array.getIndexFirst, assignVarEqn);
580
4/4
✓ Branch 0 taken 561 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 561 times.
✓ Branch 3 taken 10 times.
571 eqnIndex := List.unique(list(mapEqnScalarArray[i] for i in eqnIndex));
581 if debug then print("contEqnIndex: "); BackendDump.dumpAdjacencyRow(eqnIndex); end if;
582 10 contEqns := BackendEquation.getList(eqnIndex, syst.orderedEqs);
583 if debug then BackendDump.equationListString(contEqns, "Continuous Equations"); end if;
584 else
585 ✗ fail();
586 end try;
587 end getDiscAndContEqns;
588
589 function addVarsGlobalData
590 input output BackendDAE.BackendDAEModeData globalDAEData;
591 input list<BackendDAE.Var> inVars;
592 protected
593 list<BackendDAE.Var> vars;
594 algorithm
595 // prepare algebraic states
596 3800 vars := List.filterOnTrue(inVars, BackendVariable.isNonStateVar);
597
4/4
✓ Branch 0 taken 549 times.
✓ Branch 1 taken 3800 times.
✓ Branch 2 taken 549 times.
✓ Branch 3 taken 3800 times.
4349 vars := list(BackendVariable.setVarKind(v, BackendDAE.ALG_STATE()) for v in vars);
598 //print("Alg vars: " + BackendDump.varListString(vars, "") + "\n");
599 3800 globalDAEData.algStateVars := listAppend(vars, globalDAEData.algStateVars);
600 globalDAEData.stateVars := listAppend(List.filterOnTrue(inVars, BackendVariable.isStateVar), globalDAEData.stateVars);
601 end addVarsGlobalData;
602
603 function setNonStateVarAlgState
604 input output list<BackendDAE.Var> varList;
605 algorithm
606 ✗ for v in varList loop
607 v := match v
608 local
609 case BackendDAE.VAR(varKind=BackendDAE.STATE()) then v;
610 case BackendDAE.VAR(varKind=BackendDAE.VARIABLE())
611 algorithm
612 ✗ v := BackendVariable.setVarKind(v, BackendDAE.ALG_STATE());
613 then v;
614 else fail();
615 end match;
616 end for;
617 ✗ varList := listReverse(varList);
618 end setNonStateVarAlgState;
619
620 annotation(__OpenModelica_Interface="backend");
621 end DAEMode;
622