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