OMCompiler/Compiler/BackEnd/BackendDAEOptimize.mo
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * This file is part of OpenModelica. | ||
| 3 | * | ||
| 4 | * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC), | ||
| 5 | * c/o Linköpings universitet, Department of Computer and Information Science, | ||
| 6 | * SE-58183 Linköping, Sweden. | ||
| 7 | * | ||
| 8 | * All rights reserved. | ||
| 9 | * | ||
| 10 | * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR | ||
| 11 | * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8. | ||
| 12 | * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES | ||
| 13 | * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL | ||
| 14 | * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. | ||
| 15 | * | ||
| 16 | * The OpenModelica software and the OSMC (Open Source Modelica Consortium) | ||
| 17 | * Public License (OSMC-PL) are obtained from OSMC, either from the above | ||
| 18 | * address, from the URLs: | ||
| 19 | * http://www.openmodelica.org or | ||
| 20 | * https://github.com/OpenModelica/ or | ||
| 21 | * http://www.ida.liu.se/projects/OpenModelica, | ||
| 22 | * and in the OpenModelica distribution. | ||
| 23 | * | ||
| 24 | * GNU AGPL version 3 is obtained from: | ||
| 25 | * https://www.gnu.org/licenses/licenses.html#GPL | ||
| 26 | * | ||
| 27 | * This program is distributed WITHOUT ANY WARRANTY; without | ||
| 28 | * even the implied warranty of MERCHANTABILITY or FITNESS | ||
| 29 | * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH | ||
| 30 | * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL. | ||
| 31 | * | ||
| 32 | * See the full OSMC Public License conditions for more details. | ||
| 33 | * | ||
| 34 | */ | ||
| 35 | |||
| 36 | encapsulated package BackendDAEOptimize | ||
| 37 | " file: BackendDAEOptimize.mo | ||
| 38 | package: BackendDAEOptimize | ||
| 39 | description: BackendDAEOptimize contains functions that do some kind of | ||
| 40 | optimization on the BackendDAE datatype: | ||
| 41 | - removing simpleEquations | ||
| 42 | - Tearing/Relaxation | ||
| 43 | - Linearization | ||
| 44 | - Inline Integration | ||
| 45 | - and so on ..." | ||
| 46 | |||
| 47 | public import Absyn; | ||
| 48 | public import AbsynUtil; | ||
| 49 | public import BackendDAE; | ||
| 50 | public import DAE; | ||
| 51 | public import HashTable2; | ||
| 52 | |||
| 53 | protected | ||
| 54 | import AdjacencyMatrix; | ||
| 55 | import Algorithm; | ||
| 56 | import Array; | ||
| 57 | import BackendDAETransform; | ||
| 58 | import BackendDAEUtil; | ||
| 59 | import BackendDump; | ||
| 60 | import BackendEquation; | ||
| 61 | import BackendDAEEXT; | ||
| 62 | import BackendInline; | ||
| 63 | import BackendVarTransform; | ||
| 64 | import BackendVariable; | ||
| 65 | import BaseHashTable; | ||
| 66 | import CheckModel; | ||
| 67 | import ClassInf; | ||
| 68 | import ComponentReference; | ||
| 69 | import ComponentReferenceBasics; | ||
| 70 | import DAEUtil; | ||
| 71 | import DAEDump; | ||
| 72 | import DoubleEnded; | ||
| 73 | import Differentiate; | ||
| 74 | import ElementSource; | ||
| 75 | import ExpandableArray; | ||
| 76 | import Expression; | ||
| 77 | protected import ExpressionBasics; | ||
| 78 | import ExpressionDump; | ||
| 79 | import ExpressionSolve; | ||
| 80 | import ExpressionSimplify; | ||
| 81 | import Error; | ||
| 82 | import Flags; | ||
| 83 | import GCExt; | ||
| 84 | import HashSet; | ||
| 85 | import HashTableExpToIndex; | ||
| 86 | import HpcOmTaskGraph; | ||
| 87 | import Inline; | ||
| 88 | import List; | ||
| 89 | import Matching; | ||
| 90 | import MetaModelica.Dangerous; | ||
| 91 | import Mutable; | ||
| 92 | import RewriteRules; | ||
| 93 | import SCode; | ||
| 94 | import SynchronousFeatures; | ||
| 95 | import Tearing; | ||
| 96 | import Types; | ||
| 97 | import UnorderedMap; | ||
| 98 | import Util; | ||
| 99 | import Values; | ||
| 100 | |||
| 101 | public function simplifyAllExpressions "author: lochel" | ||
| 102 | input BackendDAE.BackendDAE inDAE; | ||
| 103 | output BackendDAE.BackendDAE outDAE = inDAE; | ||
| 104 | protected | ||
| 105 | list<BackendDAE.Equation> removedEqsList = {}; | ||
| 106 | BackendDAE.Shared shared; | ||
| 107 | algorithm | ||
| 108 | 2190 | BackendDAEUtil.traverseBackendDAEExpsNoCopyWithUpdate(outDAE, ExpressionSimplify.simplify1TraverseHelper, 0); | |
| 109 | |||
| 110 | // filter empty algorithms | ||
| 111 | 2190 | shared := outDAE.shared; | |
| 112 |
2/2✓ Branch 1 taken 1656 times.
✓ Branch 2 taken 2190 times.
|
3846 | for eq in BackendEquation.equationList(shared.removedEqs) loop |
| 113 | removedEqsList := match eq | ||
| 114 | case BackendDAE.ALGORITHM(alg=DAE.ALGORITHM_STMTS(statementLst={})) then removedEqsList; | ||
| 115 | else eq::removedEqsList; | ||
| 116 | end match; | ||
| 117 | end for; | ||
| 118 | 2190 | shared.removedEqs := BackendEquation.listEquation(MetaModelica.Dangerous.listReverseInPlace(removedEqsList)); | |
| 119 | 2190 | outDAE.shared := shared; | |
| 120 | end simplifyAllExpressions; | ||
| 121 | |||
| 122 | // ============================================================================= | ||
| 123 | // simplifyInStream | ||
| 124 | // | ||
| 125 | // OM introduces $OMC$PositiveMax which can simplified using min or max attribute | ||
| 126 | // see Modelica spec for inStream | ||
| 127 | // author: Vitalij Ruge | ||
| 128 | // see. #3885, 4441, 5104 | ||
| 129 | // ============================================================================= | ||
| 130 | |||
| 131 | public function simplifyInStream | ||
| 132 | input output BackendDAE.BackendDAE dae; | ||
| 133 | protected | ||
| 134 | BackendDAE.Shared shared = dae.shared; | ||
| 135 | BackendDAE.EqSystems eqs = dae.eqs; | ||
| 136 | list<BackendDAE.Variables> vars = list(eq.orderedVars for eq in eqs); | ||
| 137 | algorithm | ||
| 138 | // from the description inputs are part of globalKnownVars and localKnownVars :( | ||
| 139 | 16 | vars := shared.globalKnownVars :: vars; // need inputs with min = 0 or max = 0 | |
| 140 | 16 | vars := shared.localKnownVars :: vars; | |
| 141 | 16 | BackendDAEUtil.traverseBackendDAEExpsNoCopyWithUpdate(dae, simplifyInStreamWork, vars); | |
| 142 | end simplifyInStream; | ||
| 143 | |||
| 144 | protected function simplifyInStreamWork | ||
| 145 | input DAE.Exp inExp; | ||
| 146 | input list<BackendDAE.Variables> inVars; | ||
| 147 | output DAE.Exp outExp; | ||
| 148 | output list<BackendDAE.Variables> outVars = inVars; | ||
| 149 | algorithm | ||
| 150 | 49374 | outExp := Expression.traverseExpBottomUp(inExp, simplifyInStreamWork2, outVars); | |
| 151 | |||
| 152 | // with #5104 we remove max(x, eps) | ||
| 153 | // so in case max(x,eps)*y/max(x,eps) => x*y/x | ||
| 154 | // now x can be equal 0, so we need simplify x*y/x = y | ||
| 155 | // it's seem no other models silplyfied it | ||
| 156 |
2/2✓ Branch 1 taken 49256 times.
✓ Branch 2 taken 118 times.
|
49374 | if not ExpressionBasics.expEqual(outExp, inExp) then |
| 157 | 118 | outExp := ExpressionSimplify.simplify(outExp); | |
| 158 | end if; | ||
| 159 | end simplifyInStreamWork; | ||
| 160 | |||
| 161 | protected function simplifyInStreamWork2 | ||
| 162 | input DAE.Exp inExp; | ||
| 163 | input list<BackendDAE.Variables> inVars; | ||
| 164 | output DAE.Exp outExp; | ||
| 165 | output list<BackendDAE.Variables> outVars = inVars; | ||
| 166 | algorithm | ||
| 167 | outExp := match inExp | ||
| 168 | local | ||
| 169 | DAE.Type tp; | ||
| 170 | DAE.ComponentRef cr; | ||
| 171 | DAE.Exp e, expr, ret; | ||
| 172 | Option<DAE.Exp> eMin, eMax; | ||
| 173 | |||
| 174 | // positiveMax(cref, eps) = 0 if variable(cref).max <= 0 | ||
| 175 | // positiveMax(cref, eps) = cref if variable(cref).min >= eps | ||
| 176 | case DAE.CALL(path = Absyn.IDENT("$OMC$PositiveMax"), expLst = {e as DAE.CREF(componentRef = cr), expr}) algorithm | ||
| 177 | 294 | (eMin, eMax) := simplifyInStreamGetMinMaxAttributes(cr, outVars); | |
| 178 | 294 | tp := ComponentReference.crefTypeFull(cr); | |
| 179 |
2/4✗ Branch 1 not taken.
✓ Branch 2 taken 294 times.
✓ Branch 7 taken 294 times.
✗ Branch 8 not taken.
|
588 | ret := if Util.applyOptionOrDefault(eMax, Expression.isNegativeOrZero, false) then Expression.createZeroExpression(tp) |
| 180 | elseif Util.applyOptionOrDefault(eMin, function Expression.isGreaterOrEqual(exp2 = expr), false) then e | ||
| 181 | else Expression.makePureBuiltinCall("max", {e, expr}, tp); | ||
| 182 | then ret; | ||
| 183 | |||
| 184 | // positiveMax(-cref, eps) = 0 if variable(cref).min >= 0 | ||
| 185 | // positiveMax(-cref, eps) = -cref if variable(cref).max <= -eps | ||
| 186 | case DAE.CALL(path = Absyn.IDENT("$OMC$PositiveMax"), expLst = {e as DAE.UNARY(DAE.UMINUS(tp), DAE.CREF(componentRef = cr)), expr}) algorithm | ||
| 187 | 274 | (eMin, eMax) := simplifyInStreamGetMinMaxAttributes(cr, outVars); | |
| 188 |
3/4✓ Branch 1 taken 4 times.
✓ Branch 2 taken 270 times.
✓ Branch 8 taken 270 times.
✗ Branch 9 not taken.
|
544 | ret := if Util.applyOptionOrDefault(eMin, Expression.isPositiveOrZero, false) then Expression.createZeroExpression(tp) |
| 189 | elseif Util.applyOptionOrDefault(eMax, function Expression.isGreaterOrEqual(exp1 = Expression.negate(expr)), false) then e | ||
| 190 | else Expression.makePureBuiltinCall("max", {e, expr}, tp); | ||
| 191 | then ret; | ||
| 192 | |||
| 193 | // positiveMax(cref, eps) = max(cref,eps) in the general case | ||
| 194 | case DAE.CALL(path = Absyn.IDENT("$OMC$PositiveMax"), expLst = {e, expr}) | ||
| 195 | ✗ | then Expression.makePureBuiltinCall("max", {e, expr}, Expression.typeof(e)); | |
| 196 | |||
| 197 | case DAE.CALL(path = Absyn.IDENT("$OMC$inStreamDiv"), expLst = {e, expr}) algorithm | ||
| 198 | 123 | e := ExpressionSimplify.simplify(e); | |
| 199 | ret := match e | ||
| 200 | local | ||
| 201 | DAE.Exp a,b; | ||
| 202 | case DAE.BINARY(a, DAE.DIV(), b) guard Expression.isZero(a) and Expression.isZero(b) | ||
| 203 | then expr; | ||
| 204 | else e; | ||
| 205 | end match; | ||
| 206 | then ret; | ||
| 207 | |||
| 208 | else inExp; | ||
| 209 | end match; | ||
| 210 | end simplifyInStreamWork2; | ||
| 211 | |||
| 212 | protected function simplifyInStreamGetMinMaxAttributes | ||
| 213 | input DAE.ComponentRef cr; | ||
| 214 | input list<BackendDAE.Variables> inVars; | ||
| 215 | output Option<DAE.Exp> outMin = NONE(); | ||
| 216 | output Option<DAE.Exp> outMax = NONE(); | ||
| 217 | protected | ||
| 218 | BackendDAE.Var v; | ||
| 219 | algorithm | ||
| 220 |
2/2✓ Branch 0 taken 1784 times.
✓ Branch 1 taken 568 times.
|
2352 | for vars in inVars loop |
| 221 | try | ||
| 222 | 1784 | (v, _) := BackendVariable.getVarSingle(cr, vars); | |
| 223 | 568 | (outMin, outMax) := BackendVariable.getMinMaxAttribute(v); | |
| 224 | break; | ||
| 225 | else | ||
| 226 | // search | ||
| 227 | end try; | ||
| 228 | end for; | ||
| 229 | end simplifyInStreamGetMinMaxAttributes; | ||
| 230 | |||
| 231 | // ============================================================================= | ||
| 232 | // simplify time independent function calls | ||
| 233 | // | ||
| 234 | // public functions: | ||
| 235 | // - simplifyTimeIndepFuncCalls | ||
| 236 | // ============================================================================= | ||
| 237 | |||
| 238 | public function simplifyTimeIndepFuncCalls "author: Frenkel TUD 2012-06 | ||
| 239 | pre(param) -> param | ||
| 240 | der(param) -> 0.0 | ||
| 241 | change(param) -> false | ||
| 242 | edge(param) -> false" | ||
| 243 | input BackendDAE.BackendDAE inDAE; | ||
| 244 | output BackendDAE.BackendDAE outDAE; | ||
| 245 | algorithm | ||
| 246 | 2824 | (outDAE, _) := BackendDAEUtil.mapEqSystemAndFold(inDAE, simplifyTimeIndepFuncCalls0, false); | |
| 247 | 2824 | outDAE := simplifyTimeIndepFuncCallsShared(outDAE); | |
| 248 | end simplifyTimeIndepFuncCalls; | ||
| 249 | |||
| 250 | protected function simplifyTimeIndepFuncCalls0 "author: Frenkel TUD 2012-06" | ||
| 251 | input BackendDAE.EqSystem isyst; | ||
| 252 | input BackendDAE.Shared inShared; | ||
| 253 | input Boolean inChanged; | ||
| 254 | output BackendDAE.EqSystem osyst; | ||
| 255 | output BackendDAE.Shared outShared; | ||
| 256 | output Boolean outChanged; | ||
| 257 | algorithm | ||
| 258 | (osyst, outShared, outChanged) := matchcontinue (isyst, inShared) | ||
| 259 | local | ||
| 260 | BackendDAE.Shared shared; | ||
| 261 | BackendDAE.EqSystem syst; | ||
| 262 | |||
| 263 | case (syst, shared) | ||
| 264 | algorithm | ||
| 265 |
2/2✓ Branch 3 taken 5679 times.
✓ Branch 4 taken 13 times.
|
5692 | (_, (_, _, true)) := BackendDAEUtil.traverseBackendDAEExpsEqns ( |
| 266 | syst.orderedEqs, Expression.traverseSubexpressionsHelper, (traverserExpsimplifyTimeIndepFuncCalls, | ||
| 267 | (shared.globalKnownVars, shared.aliasVars, false)) | ||
| 268 | ); | ||
| 269 |
1/2✓ Branch 3 taken 13 times.
✗ Branch 4 not taken.
|
13 | (_, (_, _, true)) := BackendDAEUtil.traverseBackendDAEExpsEqns ( |
| 270 | syst.removedEqs, Expression.traverseSubexpressionsHelper, (traverserExpsimplifyTimeIndepFuncCalls, | ||
| 271 | (shared.globalKnownVars, shared.aliasVars, false)) | ||
| 272 | ); | ||
| 273 | then (isyst, inShared, true); | ||
| 274 | |||
| 275 | else (isyst, inShared, inChanged); | ||
| 276 | end matchcontinue; | ||
| 277 | end simplifyTimeIndepFuncCalls0; | ||
| 278 | |||
| 279 | protected function traverserExpsimplifyTimeIndepFuncCalls | ||
| 280 | input DAE.Exp inExp; | ||
| 281 | input tuple<BackendDAE.Variables, BackendDAE.Variables, Boolean> inTpl; | ||
| 282 | output DAE.Exp outExp; | ||
| 283 | output tuple<BackendDAE.Variables, BackendDAE.Variables, Boolean> outTpl; | ||
| 284 | algorithm | ||
| 285 | (outExp, outTpl) := matchcontinue (inExp, inTpl) | ||
| 286 | local | ||
| 287 | BackendDAE.Variables globalKnownVars, aliasvars; | ||
| 288 | DAE.Type tp; | ||
| 289 | DAE.Exp e, zero; | ||
| 290 | DAE.ComponentRef cr; | ||
| 291 | BackendDAE.Var var; | ||
| 292 | DAE.CallAttributes attr; | ||
| 293 | Boolean negate; | ||
| 294 | String idn; | ||
| 295 | |||
| 296 | case (DAE.CALL(path=Absyn.IDENT(name="der"), expLst={DAE.CREF(componentRef=cr, ty=tp)}), (globalKnownVars, aliasvars, _)) algorithm | ||
| 297 | 9422 | (var, _) := BackendVariable.getVarSingle(cr, globalKnownVars); | |
| 298 | ✗ | false := BackendVariable.isVarOnTopLevelAndInput(var); | |
| 299 | ✗ | (zero, _) := Expression.makeZeroExpression(Expression.arrayDimension(tp)); | |
| 300 | ✗ | then (zero, (globalKnownVars, aliasvars, true)); | |
| 301 | |||
| 302 | case (DAE.CALL(path=Absyn.IDENT(name=idn), expLst={e as DAE.CREF(componentRef=cr)}), (globalKnownVars, aliasvars, _)) guard idn=="pre" or idn=="previous" | ||
| 303 | algorithm | ||
| 304 | 2561 | (var, _) := BackendVariable.getVarSingle(cr, globalKnownVars); | |
| 305 | /* https://github.com/OpenModelica/OpenModelica/issues/13811 | ||
| 306 | * check if var is a top level input and keep the expression as it pre(param) = pre(param) | ||
| 307 | * for parameter and constat apply pre(param) = param | ||
| 308 | */ | ||
| 309 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 43 times.
|
43 | false := BackendVariable.isInput(var); |
| 310 | 43 | then(e, (globalKnownVars, aliasvars, true)); | |
| 311 | |||
| 312 | case (DAE.CALL(path=Absyn.IDENT(name=idn), expLst={e as DAE.CREF(componentRef=DAE.CREF_IDENT(ident="time"))}), (globalKnownVars, aliasvars, _)) guard idn=="pre" or idn=="previous" | ||
| 313 | ✗ | then (e, (globalKnownVars, aliasvars, true)); | |
| 314 | |||
| 315 | case (DAE.CALL(path=Absyn.IDENT(name=idn), expLst={e as DAE.UNARY(DAE.UMINUS(_), DAE.CREF(componentRef=DAE.CREF_IDENT(ident="time")))}), (globalKnownVars, aliasvars, _)) guard idn=="pre" or idn=="previous" | ||
| 316 | ✗ | then (e, (globalKnownVars, aliasvars, true)); | |
| 317 | |||
| 318 | case (DAE.CALL(path=Absyn.IDENT(name=idn), expLst={DAE.CREF(componentRef=cr, ty=tp)}, attr=attr), (globalKnownVars, aliasvars, _)) guard idn=="pre" or idn=="previous" algorithm | ||
| 319 | 2518 | (var, _) := BackendVariable.getVarSingle(cr, aliasvars); | |
| 320 | ✗ | (cr, negate) := BackendVariable.getAlias(var); | |
| 321 | ✗ | e := DAE.CREF(cr, tp); | |
| 322 | ✗ | e := if negate then Expression.negate(e) else e; | |
| 323 | ✗ | (e, _) := ExpressionSimplify.simplify(DAE.CALL(Absyn.IDENT(idn), {e}, attr)); | |
| 324 | ✗ | (e, _) := Expression.traverseExpBottomUp(e, traverserExpsimplifyTimeIndepFuncCalls, (globalKnownVars, aliasvars, false)); | |
| 325 | ✗ | then (e, (globalKnownVars, aliasvars, true)); | |
| 326 | |||
| 327 | case (DAE.CALL(path=Absyn.IDENT(name=idn), expLst={DAE.CREF(componentRef=cr, ty=tp)}), (globalKnownVars, aliasvars, _)) guard idn=="change" or idn=="edge" algorithm | ||
| 328 | ✗ | (_::_, _) := BackendVariable.getVar(cr, globalKnownVars); | |
| 329 | ✗ | zero := Expression.arrayFill(Expression.arrayDimension(tp), DAE.BCONST(false)); | |
| 330 | ✗ | then (zero, (globalKnownVars, aliasvars, true)); | |
| 331 | |||
| 332 | case (DAE.CALL(path=Absyn.IDENT(name=idn), expLst={DAE.CREF(componentRef=cr, ty=tp)}), (globalKnownVars, aliasvars, _)) guard idn=="change" or idn=="edge" algorithm | ||
| 333 | ✗ | (_::_, _) := BackendVariable.getVar(cr, aliasvars); | |
| 334 | ✗ | zero := Expression.arrayFill(Expression.arrayDimension(tp), DAE.BCONST(false)); | |
| 335 | ✗ | then (zero, (globalKnownVars, aliasvars, true)); | |
| 336 | |||
| 337 | case (DAE.CALL(path=Absyn.IDENT(name=idn), expLst={DAE.CREF(componentRef=DAE.CREF_IDENT(ident="time"))}), (globalKnownVars, aliasvars, _)) guard idn=="change" or idn=="edge" | ||
| 338 | ✗ | then (DAE.BCONST(false), (globalKnownVars, aliasvars, true)); | |
| 339 | |||
| 340 | case (DAE.CALL(path=Absyn.IDENT(name=idn), expLst={DAE.CREF(componentRef=cr, ty=tp)}, attr=attr), (globalKnownVars, aliasvars, _)) guard idn=="change" or idn=="edge" algorithm | ||
| 341 | ✗ | (var, _) := BackendVariable.getVarSingle(cr, aliasvars); | |
| 342 | ✗ | (cr, negate) := BackendVariable.getAlias(var); | |
| 343 | ✗ | e := DAE.CREF(cr, tp); | |
| 344 | ✗ | e := if negate then Expression.negate(e) else e; | |
| 345 | ✗ | (e, _) := ExpressionSimplify.simplify(DAE.CALL(Absyn.IDENT(idn), {e}, attr)); | |
| 346 | ✗ | (e, _) := Expression.traverseExpBottomUp(e, traverserExpsimplifyTimeIndepFuncCalls, (globalKnownVars, aliasvars, false)); | |
| 347 | ✗ | then (e, (globalKnownVars, aliasvars, true)); | |
| 348 | |||
| 349 | else (inExp, inTpl); | ||
| 350 | end matchcontinue; | ||
| 351 | end traverserExpsimplifyTimeIndepFuncCalls; | ||
| 352 | |||
| 353 | protected function simplifyTimeIndepFuncCallsShared "pre(param) -> param | ||
| 354 | der(param) -> 0.0 | ||
| 355 | change(param) -> false | ||
| 356 | edge(param) -> false | ||
| 357 | author: Frenkel TUD 2012-06" | ||
| 358 | input BackendDAE.BackendDAE inDAE; | ||
| 359 | output BackendDAE.BackendDAE outDAE; | ||
| 360 | protected | ||
| 361 | BackendDAE.Shared shared; | ||
| 362 | algorithm | ||
| 363 | 2824 | shared := inDAE.shared; | |
| 364 | 2824 | BackendDAEUtil.traverseBackendDAEExpsVarsWithUpdate(shared.globalKnownVars, Expression.traverseSubexpressionsHelper, (traverserExpsimplifyTimeIndepFuncCalls, (shared.globalKnownVars, shared.aliasVars, false))); | |
| 365 | 2824 | BackendDAEUtil.traverseBackendDAEExpsEqns(shared.initialEqs, Expression.traverseSubexpressionsHelper, (traverserExpsimplifyTimeIndepFuncCalls, (shared.globalKnownVars, shared.aliasVars, false))); | |
| 366 | 2824 | BackendDAEUtil.traverseBackendDAEExpsEqns(shared.removedEqs, Expression.traverseSubexpressionsHelper, (traverserExpsimplifyTimeIndepFuncCalls, (shared.globalKnownVars, shared.aliasVars, false))); | |
| 367 | 5648 | (shared.eventInfo, _) := traverseEventInfoExps(shared.eventInfo, Expression.traverseSubexpressionsHelper, (traverserExpsimplifyTimeIndepFuncCalls, (shared.globalKnownVars, shared.aliasVars, false))); | |
| 368 | 2824 | outDAE := BackendDAE.DAE(inDAE.eqs, shared); | |
| 369 | end simplifyTimeIndepFuncCallsShared; | ||
| 370 | |||
| 371 | protected function traverseEventInfoExps<T> | ||
| 372 | input output BackendDAE.EventInfo eventInfo; | ||
| 373 | input FuncExpType func; | ||
| 374 | input output T arg; | ||
| 375 | partial function FuncExpType | ||
| 376 | input DAE.Exp inExp; | ||
| 377 | input T inTypeA; | ||
| 378 | output DAE.Exp outExp; | ||
| 379 | output T outA; | ||
| 380 | end FuncExpType; | ||
| 381 | algorithm | ||
| 382 | 2824 | arg := DoubleEnded.mapFoldNoCopy(eventInfo.zeroCrossings.zc, function traverseZeroCrossingExps(func=func), arg); | |
| 383 | 2824 | arg := DoubleEnded.mapFoldNoCopy(eventInfo.samples.zc, function traverseZeroCrossingExps(func=func), arg); | |
| 384 | 2824 | arg := DoubleEnded.mapFoldNoCopy(eventInfo.relations.zc, function traverseZeroCrossingExps(func=func), arg); | |
| 385 | end traverseEventInfoExps; | ||
| 386 | |||
| 387 | protected function traverseZeroCrossingExps<T> | ||
| 388 | input output BackendDAE.ZeroCrossing zc; | ||
| 389 | input FuncExpType func; | ||
| 390 | input output T arg; | ||
| 391 | partial function FuncExpType | ||
| 392 | input DAE.Exp inExp; | ||
| 393 | input T inTypeA; | ||
| 394 | output DAE.Exp outExp; | ||
| 395 | output T outA; | ||
| 396 | end FuncExpType; | ||
| 397 | protected | ||
| 398 | DAE.Exp relation; | ||
| 399 | algorithm | ||
| 400 | ✗ | (relation, arg) := Expression.traverseExpBottomUp(zc.relation_, func, arg); | |
| 401 | ✗ | if not referenceEq(relation, zc.relation_) then | |
| 402 | ✗ | zc.relation_ := relation; | |
| 403 | end if; | ||
| 404 | end traverseZeroCrossingExps; | ||
| 405 | |||
| 406 | protected function toplevelInputOrUnfixed | ||
| 407 | input BackendDAE.Var inVar; | ||
| 408 | output Boolean b; | ||
| 409 | algorithm | ||
| 410 | ✗ | b := BackendVariable.isVarOnTopLevelAndInput(inVar) or | |
| 411 | BackendVariable.isParam(inVar) and not BackendVariable.varFixed(inVar); | ||
| 412 | end toplevelInputOrUnfixed; | ||
| 413 | |||
| 414 | protected function traversingTimeEqnsFinder "author: Frenkel 2010-12" | ||
| 415 | input DAE.Exp inExp; | ||
| 416 | input tuple<Boolean,BackendDAE.Variables,BackendDAE.Variables,Boolean,Boolean> inTpl; | ||
| 417 | output DAE.Exp outExp; | ||
| 418 | output Boolean cont; | ||
| 419 | output tuple<Boolean,BackendDAE.Variables,BackendDAE.Variables,Boolean,Boolean> outTpl; | ||
| 420 | algorithm | ||
| 421 | (outExp,cont,outTpl) := matchcontinue (inExp,inTpl) | ||
| 422 | local | ||
| 423 | DAE.Exp e; | ||
| 424 | Boolean b,b1,b2; | ||
| 425 | BackendDAE.Variables vars,globalKnownVars; | ||
| 426 | DAE.ComponentRef cr; | ||
| 427 | BackendDAE.Var var; | ||
| 428 | list<BackendDAE.Var> vlst; | ||
| 429 | |||
| 430 | case (e as DAE.CREF(DAE.CREF_IDENT(ident = "time",subscriptLst = {}),_), (_,vars,globalKnownVars,b1,b2)) | ||
| 431 | ✗ | then (e,false,(true,vars,globalKnownVars,b1,b2)); | |
| 432 | // inputs not constant and parameter(fixed=false) are constant but evaluated after konstant variables are evaluted | ||
| 433 | case (e as DAE.CREF(cr,_), (_,vars,globalKnownVars,b1,b2)) | ||
| 434 | algorithm | ||
| 435 | ✗ | (vlst,_::_):= BackendVariable.getVar(cr, globalKnownVars) "input variables stored in known variables are input on top level"; | |
| 436 | ✗ | false := List.none(vlst, toplevelInputOrUnfixed); | |
| 437 | ✗ | then (e,false,(true,vars,globalKnownVars,b1,b2)); | |
| 438 | ✗ | case (e as DAE.CALL(path = Absyn.IDENT(name = "sample"), expLst = {_,_,_}), (_,vars,globalKnownVars,b1,b2)) then (e,false,(true,vars,globalKnownVars,b1,b2)); | |
| 439 | ✗ | case (e as DAE.CALL(path = Absyn.IDENT(name = "pre"), expLst = {_}), (_,vars,globalKnownVars,b1,b2)) then (e,false,(true,vars,globalKnownVars,b1,b2)); | |
| 440 | ✗ | case (e as DAE.CALL(path = Absyn.IDENT(name = "previous"), expLst = {_}), (_,vars,globalKnownVars,b1,b2)) then (e,false,(true,vars,globalKnownVars,b1,b2)); | |
| 441 | ✗ | case (e as DAE.CALL(path = Absyn.IDENT(name = "change"), expLst = {_}), (_,vars,globalKnownVars,b1,b2)) then (e,false,(true,vars,globalKnownVars,b1,b2)); | |
| 442 | ✗ | case (e as DAE.CALL(path = Absyn.IDENT(name = "edge"), expLst = {_}), (_,vars,globalKnownVars,b1,b2)) then (e,false,(true,vars,globalKnownVars,b1,b2)); | |
| 443 | // case for finding simple equation in jacobians | ||
| 444 | // there are all known variables mark as input | ||
| 445 | // and they are all time-depending | ||
| 446 | case (e as DAE.CREF(cr,_), (_,vars,globalKnownVars,true,b2)) | ||
| 447 | algorithm | ||
| 448 | ✗ | (var::_,_::_):= BackendVariable.getVar(cr, globalKnownVars); | |
| 449 | ✗ | DAE.INPUT() := BackendVariable.getVarDirection(var); | |
| 450 | ✗ | then (e,false,(true,vars,globalKnownVars,true,b2)); | |
| 451 | // unkown var | ||
| 452 | case (e as DAE.CREF(cr,_), (_,vars,globalKnownVars,b1,true)) | ||
| 453 | algorithm | ||
| 454 | ✗ | (_::_,_::_):= BackendVariable.getVar(cr, vars); | |
| 455 | ✗ | then (e,false,(true,vars,globalKnownVars,b1,true)); | |
| 456 | ✗ | case (e,(b,_,_,_,_)) then (e,not b,inTpl); | |
| 457 | |||
| 458 | end matchcontinue; | ||
| 459 | end traversingTimeEqnsFinder; | ||
| 460 | |||
| 461 | public function countSimpleEquations | ||
| 462 | "author: Frenkel TUD 2011-05 | ||
| 463 | This function count the simple equations on the form a=b and a=const and a=f(not time) | ||
| 464 | in BackendDAE.BackendDAE. Note this functions does not use variable replacements, because | ||
| 465 | of this the number of simple equations is maybe smaller than using variable replacements." | ||
| 466 | input BackendDAE.BackendDAE inDlow; | ||
| 467 | input BackendDAE.AdjacencyMatrix inM; | ||
| 468 | output Integer outSimpleEqns; | ||
| 469 | algorithm | ||
| 470 | outSimpleEqns:= | ||
| 471 | match inDlow | ||
| 472 | local | ||
| 473 | BackendDAE.BackendDAE dlow; | ||
| 474 | Integer n; | ||
| 475 | case dlow | ||
| 476 | algorithm | ||
| 477 | // check equations | ||
| 478 | ✗ | (_,(_,n)) := AdjacencyMatrix.traverseAdjacencyMatrix(inM,countSimpleEquationsFinder,(dlow,0)); | |
| 479 | then n; | ||
| 480 | end match; | ||
| 481 | end countSimpleEquations; | ||
| 482 | |||
| 483 | protected function countSimpleEquationsFinder | ||
| 484 | "author: Frenkel TUD 2011-05" | ||
| 485 | input BackendDAE.AdjacencyMatrixElement elem; | ||
| 486 | input Integer pos; | ||
| 487 | input tuple<BackendDAE.BackendDAE,Integer> inTpl; | ||
| 488 | output list<Integer> outList; | ||
| 489 | output tuple<BackendDAE.BackendDAE,Integer> outTpl; | ||
| 490 | algorithm | ||
| 491 | (outList,outTpl) := | ||
| 492 | matchcontinue inTpl | ||
| 493 | local | ||
| 494 | Integer l,n,n_1; | ||
| 495 | BackendDAE.BackendDAE dae; | ||
| 496 | BackendDAE.EqSystem syst; | ||
| 497 | BackendDAE.Shared shared; | ||
| 498 | |||
| 499 | case (dae as BackendDAE.DAE({syst},shared),n) | ||
| 500 | algorithm | ||
| 501 | // check number of vars in eqns | ||
| 502 | ✗ | l := listLength(elem); | |
| 503 | ✗ | true := intLt(l,3); | |
| 504 | ✗ | true := intGt(l,0); | |
| 505 | ✗ | countsimpleEquation(elem,l,pos,syst,shared); | |
| 506 | ✗ | n_1 := n+1; | |
| 507 | ✗ | then ({},(dae,n_1)); | |
| 508 | else ({},inTpl); | ||
| 509 | end matchcontinue; | ||
| 510 | end countSimpleEquationsFinder; | ||
| 511 | |||
| 512 | protected function countsimpleEquation | ||
| 513 | " author: Frenkel TUD 2011-05" | ||
| 514 | input BackendDAE.AdjacencyMatrixElement elem; | ||
| 515 | input Integer length; | ||
| 516 | input Integer pos; | ||
| 517 | input BackendDAE.EqSystem syst; | ||
| 518 | input BackendDAE.Shared shared; | ||
| 519 | algorithm | ||
| 520 | () := matchcontinue(elem, shared) | ||
| 521 | local | ||
| 522 | DAE.ComponentRef cr; | ||
| 523 | Integer i; | ||
| 524 | DAE.Exp cre,e1,e2; | ||
| 525 | BackendDAE.Variables vars,globalKnownVars; | ||
| 526 | BackendDAE.Var var; | ||
| 527 | BackendDAE.EquationArray eqns; | ||
| 528 | BackendDAE.Equation eqn; | ||
| 529 | // a = const | ||
| 530 | // wbraun: | ||
| 531 | // speacial case for Jacobains, since there are all known variablen | ||
| 532 | // time depending input variables | ||
| 533 | case ({i}, BackendDAE.SHARED(backendDAEType = BackendDAE.JACOBIAN())) | ||
| 534 | algorithm | ||
| 535 | ✗ | vars := BackendVariable.daeVars(syst); | |
| 536 | ✗ | var := BackendVariable.getVarAt(vars,intAbs(i)); | |
| 537 | // no State | ||
| 538 | ✗ | false := BackendVariable.isStateorStateDerVar(var); | |
| 539 | // try to solve the equation | ||
| 540 | ✗ | eqns := BackendEquation.getEqnsFromEqSystem(syst); | |
| 541 | ✗ | eqn := BackendEquation.get(eqns,pos); | |
| 542 | ✗ | BackendDAE.EQUATION(exp=e1,scalar=e2) := eqn; | |
| 543 | // variable time not there | ||
| 544 | ✗ | globalKnownVars := BackendVariable.daeGlobalKnownVars(shared); | |
| 545 | ✗ | (_,(false,_,_,_,_)) := Expression.traverseExpTopDown(e1, traversingTimeEqnsFinder, (false,vars,globalKnownVars,true,false)); | |
| 546 | ✗ | (_,(false,_,_,_,_)) := Expression.traverseExpTopDown(e2, traversingTimeEqnsFinder, (false,vars,globalKnownVars,true,false)); | |
| 547 | ✗ | cr := BackendVariable.varCref(var); | |
| 548 | ✗ | cre := Expression.crefExp(cr); | |
| 549 | ✗ | (_,{}) := ExpressionSolve.solve(e1,e2,cre, NONE()); | |
| 550 | then (); | ||
| 551 | // a = const | ||
| 552 | case ({i}, _) | ||
| 553 | algorithm | ||
| 554 | ✗ | vars := BackendVariable.daeVars(syst); | |
| 555 | ✗ | var := BackendVariable.getVarAt(vars,intAbs(i)); | |
| 556 | // no State | ||
| 557 | ✗ | false := BackendVariable.isStateorStateDerVar(var); | |
| 558 | // try to solve the equation | ||
| 559 | ✗ | eqns := BackendEquation.getEqnsFromEqSystem(syst); | |
| 560 | ✗ | eqn := BackendEquation.get(eqns,pos); | |
| 561 | ✗ | BackendDAE.EQUATION(exp=e1,scalar=e2) := eqn; | |
| 562 | // variable time not there | ||
| 563 | ✗ | globalKnownVars := BackendVariable.daeGlobalKnownVars(shared); | |
| 564 | ✗ | (_,(false,_,_,_,_)) := Expression.traverseExpTopDown(e1, traversingTimeEqnsFinder, (false,vars,globalKnownVars,false,false)); | |
| 565 | ✗ | (_,(false,_,_,_,_)) := Expression.traverseExpTopDown(e2, traversingTimeEqnsFinder, (false,vars,globalKnownVars,false,false)); | |
| 566 | ✗ | cr := BackendVariable.varCref(var); | |
| 567 | ✗ | cre := Expression.crefExp(cr); | |
| 568 | ✗ | (_,{}) := ExpressionSolve.solve(e1,e2,cre, NONE()); | |
| 569 | then (); | ||
| 570 | // a = der(b) | ||
| 571 | case ({_,_}, _) | ||
| 572 | algorithm | ||
| 573 | ✗ | eqns := BackendEquation.getEqnsFromEqSystem(syst); | |
| 574 | ✗ | eqn := BackendEquation.get(eqns,pos); | |
| 575 | ✗ | (cr,_,_,_,_) := BackendEquation.derivativeEquation(eqn); | |
| 576 | // select candidate | ||
| 577 | ✗ | vars := BackendVariable.daeVars(syst); | |
| 578 | ✗ | ((_::_),(_::_)) := BackendVariable.getVar(cr,vars); | |
| 579 | then (); | ||
| 580 | // a = b | ||
| 581 | case ({_,_}, _) | ||
| 582 | algorithm | ||
| 583 | ✗ | eqns := BackendEquation.getEqnsFromEqSystem(syst); | |
| 584 | ✗ | eqn as BackendDAE.EQUATION() := BackendEquation.get(eqns,pos); | |
| 585 | ✗ | BackendEquation.aliasEquation(eqn); | |
| 586 | then (); | ||
| 587 | end matchcontinue; | ||
| 588 | end countsimpleEquation; | ||
| 589 | |||
| 590 | // ============================================================================= | ||
| 591 | // remove parameters stuff | ||
| 592 | // | ||
| 593 | // ============================================================================= | ||
| 594 | public function removeParameters | ||
| 595 | "author wbraun" | ||
| 596 | input BackendDAE.BackendDAE inDAE; | ||
| 597 | output BackendDAE.BackendDAE outDAE; | ||
| 598 | algorithm | ||
| 599 | outDAE := match inDAE | ||
| 600 | local | ||
| 601 | BackendDAE.Variables globalKnownVars; | ||
| 602 | BackendVarTransform.VariableReplacements repl; | ||
| 603 | BackendDAE.EqSystems systs; | ||
| 604 | BackendDAE.Shared shared; | ||
| 605 | case BackendDAE.DAE(systs, shared as BackendDAE.SHARED(globalKnownVars=globalKnownVars)) | ||
| 606 | algorithm | ||
| 607 | ✗ | repl := BackendVarTransform.emptyReplacements(); | |
| 608 | ✗ | (repl, _) := BackendVariable.traverseBackendDAEVars(globalKnownVars, removeParametersFinder, (repl, globalKnownVars)); | |
| 609 | ✗ | (globalKnownVars, repl) := replaceFinalVars(1, globalKnownVars, repl); | |
| 610 | ✗ | (globalKnownVars, repl) := replaceFinalVars(1, globalKnownVars, repl); | |
| 611 | ✗ | if Flags.isSet(Flags.DUMP_PARAM_REPL) then | |
| 612 | ✗ | BackendVarTransform.dumpReplacements(repl); | |
| 613 | end if; | ||
| 614 | ✗ | systs := List.map1(systs,removeParameterswork, repl); | |
| 615 | ✗ | shared.globalKnownVars := globalKnownVars; | |
| 616 | ✗ | then | |
| 617 | BackendDAE.DAE(systs, shared); | ||
| 618 | end match; | ||
| 619 | end removeParameters; | ||
| 620 | |||
| 621 | protected function removeParameterswork | ||
| 622 | "author wbraun" | ||
| 623 | input BackendDAE.EqSystem isyst; | ||
| 624 | input BackendVarTransform.VariableReplacements repl; | ||
| 625 | output BackendDAE.EqSystem osyst; | ||
| 626 | algorithm | ||
| 627 | osyst := match isyst | ||
| 628 | local | ||
| 629 | Option<BackendDAE.AdjacencyMatrix> m,mT; | ||
| 630 | BackendDAE.Variables vars; | ||
| 631 | BackendDAE.EquationArray eqns; | ||
| 632 | list<BackendDAE.Equation> lsteqns; | ||
| 633 | BackendDAE.EqSystem syst; | ||
| 634 | |||
| 635 | case syst as BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns) | ||
| 636 | algorithm | ||
| 637 | ✗ | (vars, _) := replaceFinalVars(1, vars, repl); // replacing variable attributes (e.g start) in unknown vars | |
| 638 | ✗ | (lsteqns, _) := BackendVarTransform.replaceEquations(BackendEquation.equationList(eqns), repl, NONE()); | |
| 639 | ✗ | syst.orderedVars := vars; | |
| 640 | ✗ | syst.orderedEqs := BackendEquation.listEquation(lsteqns); | |
| 641 | ✗ | syst.m := NONE(); syst.mT := NONE(); | |
| 642 | then | ||
| 643 | syst; | ||
| 644 | end match; | ||
| 645 | end removeParameterswork; | ||
| 646 | |||
| 647 | protected function removeParametersFinder | ||
| 648 | input BackendDAE.Var inVar; | ||
| 649 | input tuple<BackendVarTransform.VariableReplacements,BackendDAE.Variables> inTpl; | ||
| 650 | output BackendDAE.Var outVar; | ||
| 651 | output tuple<BackendVarTransform.VariableReplacements,BackendDAE.Variables> outTpl; | ||
| 652 | algorithm | ||
| 653 | (outVar,outTpl) := matchcontinue (inVar,inTpl) | ||
| 654 | local | ||
| 655 | BackendDAE.Variables vars; | ||
| 656 | BackendDAE.Var v; | ||
| 657 | BackendVarTransform.VariableReplacements repl,repl_1; | ||
| 658 | DAE.ComponentRef varName; | ||
| 659 | DAE.Exp exp,exp1; | ||
| 660 | |||
| 661 | case (v as BackendDAE.VAR(varName=varName,varKind=BackendDAE.PARAM(),bindExp=SOME(exp)),(repl,vars)) | ||
| 662 | algorithm | ||
| 663 | ✗ | (exp1, _) := Expression.traverseExpBottomUp(exp, BackendDAEUtil.replaceCrefsWithValues, (vars, varName)); | |
| 664 | ✗ | repl_1 := BackendVarTransform.addReplacement(repl, varName, exp1,NONE()); | |
| 665 | ✗ | then (v,(repl_1,vars)); | |
| 666 | |||
| 667 | else (inVar,inTpl); | ||
| 668 | end matchcontinue; | ||
| 669 | end removeParametersFinder; | ||
| 670 | |||
| 671 | protected function replaceFinalVars | ||
| 672 | " author: Frenkel TUD 2011-04" | ||
| 673 | input Integer inNumRepl; | ||
| 674 | input BackendDAE.Variables inVars; | ||
| 675 | input BackendVarTransform.VariableReplacements inRepl; | ||
| 676 | output BackendDAE.Variables outVars; | ||
| 677 | output BackendVarTransform.VariableReplacements outRepl; | ||
| 678 | protected | ||
| 679 | Integer numrepl; | ||
| 680 | BackendDAE.Variables globalKnownVars1; | ||
| 681 | BackendVarTransform.VariableReplacements repl1; | ||
| 682 | algorithm | ||
| 683 | ✗ | if intEq(0,inNumRepl) then | |
| 684 | ✗ | (outVars,outRepl) := (inVars,inRepl); | |
| 685 | else | ||
| 686 | ✗ | (globalKnownVars1, (repl1,numrepl)) := BackendVariable.traverseBackendDAEVarsWithUpdate(inVars,replaceFinalVarTraverser,(inRepl,0)); | |
| 687 | ✗ | (outVars,outRepl) := replaceFinalVars(numrepl,globalKnownVars1,repl1); | |
| 688 | end if; | ||
| 689 | end replaceFinalVars; | ||
| 690 | |||
| 691 | |||
| 692 | protected function replaceFinalVarTraverser | ||
| 693 | input BackendDAE.Var inVar; | ||
| 694 | input tuple<BackendVarTransform.VariableReplacements,Integer> inTpl; | ||
| 695 | output BackendDAE.Var outVar; | ||
| 696 | output tuple<BackendVarTransform.VariableReplacements,Integer> outTpl; | ||
| 697 | algorithm | ||
| 698 | (outVar,outTpl) := matchcontinue (inVar,inTpl) | ||
| 699 | local | ||
| 700 | BackendDAE.Var v,v1; | ||
| 701 | BackendVarTransform.VariableReplacements repl,repl_1; | ||
| 702 | Integer numrepl; | ||
| 703 | DAE.Exp e,e1; | ||
| 704 | DAE.ComponentRef cr; | ||
| 705 | Option<DAE.VariableAttributes> attr,new_attr; | ||
| 706 | |||
| 707 | // Don't replace with function calls | ||
| 708 | case (BackendDAE.VAR(bindExp=SOME(DAE.CALL())),_) | ||
| 709 | then(inVar,inTpl); | ||
| 710 | |||
| 711 | case (v as BackendDAE.VAR(varName=cr,bindExp=SOME(e),values=attr),(repl,numrepl)) | ||
| 712 | algorithm | ||
| 713 |
1/2✓ Branch 1 taken 191199 times.
✗ Branch 2 not taken.
|
191199 | (e1,true) := BackendVarTransform.replaceExp(e, repl, NONE()); |
| 714 | ✗ | (e1,_) := ExpressionSimplify.simplify(e1); | |
| 715 | ✗ | v1 := BackendVariable.setBindExp(v, SOME(e1)); | |
| 716 | ✗ | repl_1 := addConstExpReplacement(e1,cr,repl); | |
| 717 | ✗ | (attr,repl_1) := BackendDAEUtil.traverseBackendDAEVarAttr(attr,traverseExpVisitorWrapper,repl_1); | |
| 718 | ✗ | v1 := BackendVariable.setVarAttributes(v1,attr); | |
| 719 | ✗ | then (v1,(repl_1,numrepl+1)); | |
| 720 | |||
| 721 | case (v as BackendDAE.VAR(values=attr),(repl,numrepl)) | ||
| 722 | algorithm | ||
| 723 | 302669 | (new_attr,repl) := BackendDAEUtil.traverseBackendDAEVarAttr(attr,traverseExpVisitorWrapper,repl); | |
| 724 | 302669 | v1 := BackendVariable.setVarAttributes(v,new_attr); | |
| 725 | 302669 | then (v1,(repl,numrepl)); | |
| 726 | end matchcontinue; | ||
| 727 | end replaceFinalVarTraverser; | ||
| 728 | |||
| 729 | protected function addConstExpReplacement | ||
| 730 | input DAE.Exp inExp; | ||
| 731 | input DAE.ComponentRef cr; | ||
| 732 | input BackendVarTransform.VariableReplacements inRepl; | ||
| 733 | output BackendVarTransform.VariableReplacements outRepl; | ||
| 734 | algorithm | ||
| 735 | outRepl := matchcontinue inRepl | ||
| 736 | case _ | ||
| 737 | algorithm | ||
| 738 | ✗ | true := Expression.isConst(inExp); | |
| 739 | ✗ | then | |
| 740 | BackendVarTransform.addReplacement(inRepl, cr, inExp,NONE()); | ||
| 741 | else | ||
| 742 | inRepl; | ||
| 743 | end matchcontinue; | ||
| 744 | end addConstExpReplacement; | ||
| 745 | |||
| 746 | protected function traverseExpVisitorWrapper "help function to replaceFinalVarTraverser" | ||
| 747 | input DAE.Exp inExp; | ||
| 748 | input BackendVarTransform.VariableReplacements inRepl; | ||
| 749 | output DAE.Exp exp; | ||
| 750 | output BackendVarTransform.VariableReplacements repl; | ||
| 751 | algorithm | ||
| 752 | (exp,repl) := match(inExp,inRepl) | ||
| 753 | local | ||
| 754 | |||
| 755 | case (exp as DAE.CREF(_,_),repl) algorithm | ||
| 756 | 13410 | (exp,_) := BackendVarTransform.replaceExp(exp,repl,NONE()); | |
| 757 | then (exp,repl); | ||
| 758 | |||
| 759 | else (inExp,inRepl); | ||
| 760 | end match; | ||
| 761 | end traverseExpVisitorWrapper; | ||
| 762 | |||
| 763 | |||
| 764 | // ============================================================================= | ||
| 765 | // remove protected parameters stuff | ||
| 766 | // | ||
| 767 | // ============================================================================= | ||
| 768 | public function removeProtectedParameters | ||
| 769 | "author Frenkel TUD" | ||
| 770 | input BackendDAE.BackendDAE inDAE; | ||
| 771 | output BackendDAE.BackendDAE outDAE; | ||
| 772 | algorithm | ||
| 773 | outDAE := match inDAE | ||
| 774 | local | ||
| 775 | BackendDAE.Variables globalKnownVars; | ||
| 776 | BackendVarTransform.VariableReplacements repl; | ||
| 777 | BackendDAE.EqSystems systs; | ||
| 778 | BackendDAE.Shared shared; | ||
| 779 | case BackendDAE.DAE(systs, shared as BackendDAE.SHARED(globalKnownVars=globalKnownVars)) | ||
| 780 | algorithm | ||
| 781 | ✗ | repl := BackendVarTransform.emptyReplacements(); | |
| 782 | ✗ | repl := BackendVariable.traverseBackendDAEVars(globalKnownVars, protectedParametersFinder, repl); | |
| 783 | ✗ | if Flags.isSet(Flags.DUMP_PP_REPL) then | |
| 784 | ✗ | BackendVarTransform.dumpReplacements(repl); | |
| 785 | end if; | ||
| 786 | ✗ | systs := List.map1(systs, removeProtectedParameterswork, repl); | |
| 787 | ✗ | shared.globalKnownVars := globalKnownVars; | |
| 788 | ✗ | then | |
| 789 | (BackendDAE.DAE(systs, shared)); | ||
| 790 | end match; | ||
| 791 | end removeProtectedParameters; | ||
| 792 | |||
| 793 | protected function removeProtectedParameterswork | ||
| 794 | "author Frenkel TUD" | ||
| 795 | input BackendDAE.EqSystem isyst; | ||
| 796 | input BackendVarTransform.VariableReplacements repl; | ||
| 797 | output BackendDAE.EqSystem osyst; | ||
| 798 | algorithm | ||
| 799 | osyst := match isyst | ||
| 800 | local | ||
| 801 | BackendDAE.EqSystem syst; | ||
| 802 | BackendDAE.EquationArray eqns; | ||
| 803 | list<BackendDAE.Equation> lsteqns; | ||
| 804 | Boolean b; | ||
| 805 | |||
| 806 | case syst as BackendDAE.EQSYSTEM(orderedEqs=eqns) | ||
| 807 | algorithm | ||
| 808 | ✗ | lsteqns := BackendEquation.equationList(eqns); | |
| 809 | ✗ | (lsteqns, b) := BackendVarTransform.replaceEquations(lsteqns, repl, NONE()); | |
| 810 | ✗ | if b then | |
| 811 | ✗ | syst.orderedEqs := BackendEquation.listEquation(lsteqns); | |
| 812 | ✗ | syst := BackendDAEUtil.clearEqSyst(syst); | |
| 813 | end if; | ||
| 814 | then | ||
| 815 | syst; | ||
| 816 | end match; | ||
| 817 | end removeProtectedParameterswork; | ||
| 818 | |||
| 819 | protected function protectedParametersFinder | ||
| 820 | input BackendDAE.Var inVar; | ||
| 821 | input BackendVarTransform.VariableReplacements inRepl; | ||
| 822 | output BackendDAE.Var outVar; | ||
| 823 | output BackendVarTransform.VariableReplacements outRepl; | ||
| 824 | algorithm | ||
| 825 | (outVar,outRepl) := matchcontinue (inVar,inRepl) | ||
| 826 | local | ||
| 827 | BackendDAE.Var v; | ||
| 828 | BackendVarTransform.VariableReplacements repl,repl_1; | ||
| 829 | DAE.ComponentRef varName; | ||
| 830 | Option< .DAE.VariableAttributes> values; | ||
| 831 | DAE.Exp exp; | ||
| 832 | case (v as BackendDAE.VAR(varName=varName,varKind=BackendDAE.PARAM(),bindExp=SOME(exp),values=values),repl) | ||
| 833 | algorithm | ||
| 834 | ✗ | true := DAEUtil.getProtectedAttr(values); | |
| 835 | ✗ | repl_1 := BackendVarTransform.addReplacement(repl, varName, exp,NONE()); | |
| 836 | then (v,repl_1); | ||
| 837 | |||
| 838 | else (inVar,inRepl); | ||
| 839 | end matchcontinue; | ||
| 840 | end protectedParametersFinder; | ||
| 841 | |||
| 842 | |||
| 843 | // ============================================================================= | ||
| 844 | // remove equal function calls equations stuff | ||
| 845 | // | ||
| 846 | // ============================================================================= | ||
| 847 | protected type IntArray = array<Integer>; | ||
| 848 | |||
| 849 | public function removeEqualRHS "author: Frenkel TUD 2011-04 | ||
| 850 | Detects equal expressions of the form a=<exp> and b=<exp> and substitutes | ||
| 851 | them to get speed up." | ||
| 852 | input BackendDAE.BackendDAE dae; | ||
| 853 | output BackendDAE.BackendDAE odae; | ||
| 854 | algorithm | ||
| 855 | 2841 | odae := BackendDAEUtil.mapEqSystem(dae,removeEqualFunctionCallsWork); | |
| 856 | end removeEqualRHS; | ||
| 857 | |||
| 858 | protected function removeEqualFunctionCallsWork "author: Frenkel TUD 2011-04 | ||
| 859 | This function detects equal function calls of the form a=f(b) and c=f(b) in | ||
| 860 | BackendDAE.BackendDAE to get speed up." | ||
| 861 | input BackendDAE.EqSystem isyst; | ||
| 862 | input BackendDAE.Shared ishared; | ||
| 863 | output BackendDAE.EqSystem osyst; | ||
| 864 | output BackendDAE.Shared oshared; | ||
| 865 | algorithm | ||
| 866 | (osyst,oshared) := match isyst | ||
| 867 | local | ||
| 868 | BackendDAE.AdjacencyMatrix m; | ||
| 869 | BackendDAE.AdjacencyMatrixT mT; | ||
| 870 | BackendDAE.Variables vars; | ||
| 871 | BackendDAE.EquationArray eqns; | ||
| 872 | list<Integer> changed; | ||
| 873 | array<Boolean> isChanged; | ||
| 874 | array<Integer> degree, varMark; | ||
| 875 | UnorderedMap<Integer, IntArray> ranks; | ||
| 876 | Boolean isInitial; | ||
| 877 | BackendDAE.EqSystem syst; | ||
| 878 | AvlTreePathFunction.Tree funcs; | ||
| 879 | |||
| 880 | case syst as BackendDAE.EQSYSTEM(orderedVars=vars,orderedEqs=eqns) | ||
| 881 | algorithm | ||
| 882 | 20148 | isInitial := BackendDAEUtil.isInitializationDAE(ishared); | |
| 883 | 20148 | funcs := BackendDAEUtil.getFunctions(ishared); | |
| 884 | 20148 | (syst, m, mT) := BackendDAEUtil.getAdjacencyMatrixfromOption(syst, BackendDAE.NORMAL(), SOME(funcs), isInitial); | |
| 885 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20148 times.
|
40296 | degree := arrayCreate(arrayLength(mT), 0); |
| 886 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 20148 times.
✓ Branch 2 taken 20124 times.
✓ Branch 3 taken 24 times.
|
263582 | for v in 1:arrayLength(mT) loop |
| 887 | 223286 | arrayUpdate(degree, v, listLength(mT[v])); | |
| 888 | end for; | ||
| 889 | 20148 | ranks := UnorderedMap.new<IntArray>(Util.id, intEq); | |
| 890 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20148 times.
|
40296 | varMark := arrayCreate(arrayLength(mT), 0); |
| 891 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20148 times.
|
40296 | isChanged := arrayCreate(arrayLength(m), false); |
| 892 | 20148 | changed := {}; | |
| 893 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 20148 times.
✓ Branch 2 taken 20124 times.
✓ Branch 3 taken 24 times.
|
253759 | for pos in 1:arrayLength(m) loop |
| 894 | 213463 | (eqns, changed) := removeEqualFunctionCallFinder(pos, m, mT, degree, ranks, varMark, vars, eqns, changed, isChanged, isInitial); | |
| 895 | end for; | ||
| 896 | // update arrayeqns and algorithms, collect info for wrappers | ||
| 897 | 60444 | syst.m := SOME(m); syst.mT := SOME(mT); syst.matching := BackendDAE.NO_MATCHING(); | |
| 898 | 20148 | syst := BackendDAEUtil.updateAdjacencyMatrix(syst, BackendDAE.NORMAL(), NONE(), changed, isInitial); | |
| 899 | then (syst, ishared); | ||
| 900 | end match; | ||
| 901 | end removeEqualFunctionCallsWork; | ||
| 902 | |||
| 903 | protected function removeEqualFunctionCallFinder "author: Frenkel TUD 2010-12" | ||
| 904 | input Integer pos; | ||
| 905 | input BackendDAE.AdjacencyMatrix m; | ||
| 906 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 907 | input array<Integer> degree "of the variables"; | ||
| 908 | input UnorderedMap<Integer, IntArray> ranks; | ||
| 909 | input array<Integer> varMark; | ||
| 910 | input BackendDAE.Variables vars; | ||
| 911 | input output BackendDAE.EquationArray eqns; | ||
| 912 | input output list<Integer> changed; | ||
| 913 | input array<Boolean> isChanged; | ||
| 914 | input Boolean isInitial; | ||
| 915 | protected | ||
| 916 | DAE.Exp exp,e1,e2,ecr; | ||
| 917 | list<Integer> expvars, controleqns; | ||
| 918 | algorithm | ||
| 919 | try | ||
| 920 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 213463 times.
|
213463 | _::_ := m[pos]; |
| 921 |
2/2✓ Branch 1 taken 3010 times.
✓ Branch 2 taken 210453 times.
|
213463 | BackendDAE.EQUATION(exp=e1,scalar=e2) := BackendEquation.get(eqns,pos); |
| 922 | 210453 | (ecr,exp) := functionCallEqn(e1,e2,vars); | |
| 923 | // TODO: Handle this with alias-equations instead?; at least they don't replace back to the original expression... | ||
| 924 | 89400 | expvars := BackendDAEUtil.uniqueRow(BackendDAEUtil.adjacencyRowExp(exp,vars,{},NONE(),BackendDAE.NORMAL(),isInitial)); | |
| 925 |
2/2✓ Branch 0 taken 41637 times.
✓ Branch 1 taken 47763 times.
|
89400 | _::_ := expvars; |
| 926 | 47763 | controleqns := controlEqns(expvars, pos, m, mT, degree, ranks, varMark); | |
| 927 | 47763 | (eqns,changed) := removeEqualFunctionCall(controleqns,ecr,exp,eqns,changed,isChanged); | |
| 928 | else | ||
| 929 | end try; | ||
| 930 | end removeEqualFunctionCallFinder; | ||
| 931 | |||
| 932 | protected function controlEqns | ||
| 933 | "The other equations containing every variable of the expression, in the | ||
| 934 | order of the first variable's row, collected from the least used one's row." | ||
| 935 | input list<Integer> expvars; | ||
| 936 | input Integer pos; | ||
| 937 | input BackendDAE.AdjacencyMatrix m; | ||
| 938 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 939 | input array<Integer> degree; | ||
| 940 | input UnorderedMap<Integer, IntArray> ranks; | ||
| 941 | input array<Integer> varMark "pos for the variables of the expression"; | ||
| 942 | output list<Integer> eqns = {}; | ||
| 943 | protected | ||
| 944 | Integer first, least, eq, nvars = 0; | ||
| 945 | array<Integer> rank; | ||
| 946 | algorithm | ||
| 947 | 47763 | first := intAbs(listHead(expvars)); | |
| 948 | least := first; | ||
| 949 |
2/2✓ Branch 0 taken 120353 times.
✓ Branch 1 taken 47763 times.
|
168116 | for v in expvars loop |
| 950 |
2/2✓ Branch 2 taken 11550 times.
✓ Branch 3 taken 108803 times.
|
120353 | if degree[intAbs(v)] < degree[least] then |
| 951 | least := intAbs(v); | ||
| 952 | end if; | ||
| 953 |
2/2✓ Branch 1 taken 120248 times.
✓ Branch 2 taken 105 times.
|
120353 | if varMark[intAbs(v)] <> pos then |
| 954 | 120248 | arrayUpdate(varMark, intAbs(v), pos); | |
| 955 | 120248 | nvars := nvars + 1; | |
| 956 | end if; | ||
| 957 | end for; | ||
| 958 |
2/2✓ Branch 1 taken 182907 times.
✓ Branch 2 taken 47763 times.
|
230670 | for i in mT[least] loop |
| 959 | 182907 | eq := intAbs(i); | |
| 960 |
4/4✓ Branch 0 taken 135599 times.
✓ Branch 1 taken 47308 times.
✓ Branch 4 taken 79253 times.
✓ Branch 5 taken 56346 times.
|
182907 | if eq <> pos and rowContainsAll(m[eq], nvars, pos, varMark) then |
| 961 | eqns := eq :: eqns; | ||
| 962 | end if; | ||
| 963 | end for; | ||
| 964 | 47763 | eqns := listReverse(eqns); | |
| 965 |
4/4✓ Branch 0 taken 37450 times.
✓ Branch 1 taken 10313 times.
✓ Branch 2 taken 7454 times.
✓ Branch 3 taken 2859 times.
|
47763 | if least <> first and not listEmpty(eqns) then |
| 966 |
2/2✓ Branch 1 taken 2830 times.
✓ Branch 2 taken 29 times.
|
2859 | if degree[first] <= 64 then |
| 967 |
6/6✓ Branch 2 taken 19658 times.
✓ Branch 3 taken 5635 times.
✓ Branch 4 taken 25293 times.
✓ Branch 5 taken 2830 times.
✓ Branch 6 taken 5635 times.
✓ Branch 7 taken 2830 times.
|
28123 | eqns := list(intAbs(i) for i guard List.isMemberOnTrue(intAbs(i), eqns, intEq) in mT[first]); |
| 968 | else | ||
| 969 | 29 | rank := rowRanks(first, mT, arrayLength(m), ranks); | |
| 970 | 29 | eqns := List.sort(eqns, function rankGt(rank = rank)); | |
| 971 | end if; | ||
| 972 | end if; | ||
| 973 | end controlEqns; | ||
| 974 | |||
| 975 | protected function rowContainsAll | ||
| 976 | "Whether row holds all nvars variables marked pos; a hit is marked -pos until | ||
| 977 | the row has been counted, so a variable in it twice counts once." | ||
| 978 | input list<Integer> row; | ||
| 979 | input Integer nvars; | ||
| 980 | input Integer pos; | ||
| 981 | input array<Integer> varMark; | ||
| 982 | output Boolean all; | ||
| 983 | protected | ||
| 984 | Integer hits = 0; | ||
| 985 | algorithm | ||
| 986 |
2/2✓ Branch 0 taken 567459 times.
✓ Branch 1 taken 135599 times.
|
703058 | for v in row loop |
| 987 |
2/2✓ Branch 1 taken 235665 times.
✓ Branch 2 taken 331794 times.
|
567459 | if varMark[intAbs(v)] == pos then |
| 988 | 235665 | arrayUpdate(varMark, intAbs(v), -pos); | |
| 989 | 235665 | hits := hits + 1; | |
| 990 | end if; | ||
| 991 | end for; | ||
| 992 |
2/2✓ Branch 0 taken 567459 times.
✓ Branch 1 taken 135599 times.
|
703058 | for v in row loop |
| 993 |
2/2✓ Branch 1 taken 235665 times.
✓ Branch 2 taken 331794 times.
|
567459 | if varMark[intAbs(v)] == -pos then |
| 994 | 235665 | arrayUpdate(varMark, intAbs(v), pos); | |
| 995 | end if; | ||
| 996 | end for; | ||
| 997 | 135599 | all := hits == nvars; | |
| 998 | end rowContainsAll; | ||
| 999 | |||
| 1000 | protected function rowRanks "the position of each equation in the row of var, built once per variable" | ||
| 1001 | input Integer var; | ||
| 1002 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 1003 | input Integer numEqns; | ||
| 1004 | input UnorderedMap<Integer, IntArray> ranks; | ||
| 1005 | output array<Integer> rank; | ||
| 1006 | protected | ||
| 1007 | Integer i = 1; | ||
| 1008 | algorithm | ||
| 1009 | rank := match UnorderedMap.get(var, ranks) | ||
| 1010 | case SOME(rank) then rank; | ||
| 1011 | else | ||
| 1012 | algorithm | ||
| 1013 | 1 | rank := arrayCreate(numEqns, 0); | |
| 1014 |
2/2✓ Branch 2 taken 71 times.
✓ Branch 3 taken 1 time.
|
72 | for eq in mT[var] loop |
| 1015 | 71 | arrayUpdate(rank, intAbs(eq), i); | |
| 1016 | 71 | i := i + 1; | |
| 1017 | end for; | ||
| 1018 | 1 | UnorderedMap.add(var, rank, ranks); | |
| 1019 | then rank; | ||
| 1020 | end match; | ||
| 1021 | end rowRanks; | ||
| 1022 | |||
| 1023 | protected function rankGt | ||
| 1024 | input Integer a, b; | ||
| 1025 | input array<Integer> rank; | ||
| 1026 | output Boolean gt = rank[a] > rank[b]; | ||
| 1027 | end rankGt; | ||
| 1028 | |||
| 1029 | protected function functionCallEqn | ||
| 1030 | "author Frenkel TUD 2011-04" | ||
| 1031 | input DAE.Exp ie1; | ||
| 1032 | input DAE.Exp ie2; | ||
| 1033 | input BackendDAE.Variables inVars; | ||
| 1034 | output DAE.Exp outECr; | ||
| 1035 | output DAE.Exp outExp; | ||
| 1036 | algorithm | ||
| 1037 | (outECr,outExp) := match (ie1, ie2) | ||
| 1038 | local | ||
| 1039 | DAE.ComponentRef cr; | ||
| 1040 | DAE.Exp e1,e2; | ||
| 1041 | DAE.Operator op; | ||
| 1042 | |||
| 1043 | case (DAE.CREF(), DAE.UNARY(operator=DAE.UMINUS(),exp=DAE.CREF())) | ||
| 1044 | 2081 | then fail(); | |
| 1045 | case (DAE.CREF(), DAE.CREF()) | ||
| 1046 | 87171 | then fail(); | |
| 1047 | case (DAE.UNARY(operator=DAE.UMINUS(),exp=DAE.CREF()), DAE.CREF()) | ||
| 1048 | 35 | then fail(); | |
| 1049 | // a = -<exp> | ||
| 1050 | case (e1 as DAE.CREF(componentRef = cr), DAE.UNARY(operator=op as DAE.UMINUS(),exp=e2)) | ||
| 1051 | algorithm | ||
| 1052 |
2/4✗ Branch 1 not taken.
✓ Branch 2 taken 111 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 111 times.
|
111 | ((_::_),(_::_)) := BackendVariable.getVar(cr,inVars); |
| 1053 | 111 | then (DAE.UNARY(op,e1),e2); | |
| 1054 | // a = <exp>; | ||
| 1055 | case (e1 as DAE.CREF(componentRef = cr), e2) | ||
| 1056 | algorithm | ||
| 1057 |
2/4✗ Branch 1 not taken.
✓ Branch 2 taken 87572 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 87572 times.
|
88009 | ((_::_),(_::_)) := BackendVariable.getVar(cr,inVars); |
| 1058 | then (e1,e2); | ||
| 1059 | // -<exp> = a | ||
| 1060 | case (DAE.UNARY(operator=op as DAE.UMINUS(),exp=e1), e2 as DAE.CREF(componentRef = cr)) | ||
| 1061 | algorithm | ||
| 1062 | ✗ | ((_::_),(_::_)) := BackendVariable.getVar(cr,inVars); | |
| 1063 | ✗ | then (DAE.UNARY(op,e2),e1); | |
| 1064 | // <exp> = a | ||
| 1065 | case (e1, e2 as DAE.CREF(componentRef = cr)) | ||
| 1066 | algorithm | ||
| 1067 |
2/4✗ Branch 1 not taken.
✓ Branch 2 taken 1717 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1717 times.
|
1956 | ((_::_),(_::_)) := BackendVariable.getVar(cr,inVars); |
| 1068 | then (e2,e1); | ||
| 1069 | end match; | ||
| 1070 | end functionCallEqn; | ||
| 1071 | |||
| 1072 | protected function removeEqualFunctionCall | ||
| 1073 | "author: Frenkel TUD 2011-04" | ||
| 1074 | input list<Integer> inEqsLst; | ||
| 1075 | input DAE.Exp inExp; | ||
| 1076 | input DAE.Exp inECr; | ||
| 1077 | input output BackendDAE.EquationArray eqns; | ||
| 1078 | input output list<Integer> changed; | ||
| 1079 | input array<Boolean> isChanged; | ||
| 1080 | protected | ||
| 1081 | BackendDAE.Equation eqn; | ||
| 1082 | Integer i; | ||
| 1083 | algorithm | ||
| 1084 |
2/2✓ Branch 0 taken 79265 times.
✓ Branch 1 taken 47763 times.
|
127028 | for pos in inEqsLst loop |
| 1085 | try | ||
| 1086 | 79265 | eqn := BackendEquation.get(eqns,pos); | |
| 1087 | 79265 | (eqn,(_,_,i)) := BackendDAETransform.traverseBackendDAEExpsEqnWithSymbolicOperation(eqn, replaceExp, (inECr,inExp,0)); | |
| 1088 |
2/2✓ Branch 0 taken 2338 times.
✓ Branch 1 taken 76927 times.
|
79265 | if i > 0 then |
| 1089 | 2338 | eqns := BackendEquation.setAtIndex(eqns,pos,eqn); | |
| 1090 |
2/2✓ Branch 1 taken 2304 times.
✓ Branch 2 taken 34 times.
|
2338 | if not isChanged[pos] then |
| 1091 | 2304 | arrayUpdate(isChanged, pos, true); | |
| 1092 | changed := pos::changed; | ||
| 1093 | end if; | ||
| 1094 | end if; | ||
| 1095 | else | ||
| 1096 | end try; | ||
| 1097 | end for; | ||
| 1098 | end removeEqualFunctionCall; | ||
| 1099 | |||
| 1100 | protected function replaceExp | ||
| 1101 | input DAE.Exp inExp; | ||
| 1102 | input tuple<list<DAE.SymbolicOperation>, tuple<DAE.Exp, DAE.Exp, Integer>> inTpl; | ||
| 1103 | output DAE.Exp e1; | ||
| 1104 | output tuple<list<DAE.SymbolicOperation>, tuple<DAE.Exp, DAE.Exp, Integer>> outTpl; | ||
| 1105 | protected | ||
| 1106 | DAE.Exp e, se, te; | ||
| 1107 | Integer i, j; | ||
| 1108 | list<DAE.SymbolicOperation> ops; | ||
| 1109 | algorithm | ||
| 1110 | e := inExp; | ||
| 1111 | 159513 | (ops, (se, te, i)) := inTpl; | |
| 1112 | // BackendDump.debugStrExpStrExpStr(("Repalce ", se, " with ", te, "\n")); | ||
| 1113 | // use the noEvent-aware variant: a relation inside noEvent()/smooth() is | ||
| 1114 | // continuous and must not be substituted by an event-based variable | ||
| 1115 | 159513 | (e1, j) := Expression.replaceExpNoEvent(e, se, te); | |
| 1116 |
2/2✓ Branch 0 taken 2339 times.
✓ Branch 1 taken 157174 times.
|
161852 | ops := if j>0 then DAE.SUBSTITUTION({e1}, e)::ops else ops; |
| 1117 | // BackendDump.debugStrExpStrExpStr(("Old ", e, " new ", e1, "\n")); | ||
| 1118 | 159513 | outTpl := (ops, (se, te, i+j)); | |
| 1119 | end replaceExp; | ||
| 1120 | |||
| 1121 | // ============================================================================= | ||
| 1122 | // remove unused parameter | ||
| 1123 | // | ||
| 1124 | // ============================================================================= | ||
| 1125 | public function removeUnusedParameter | ||
| 1126 | "author: Frenkel TUD 2011-04 | ||
| 1127 | This function remove unused parameters | ||
| 1128 | in BackendDAE.BackendDAE to get speed up for compilation of | ||
| 1129 | target code" | ||
| 1130 | input BackendDAE.BackendDAE inDlow; | ||
| 1131 | output BackendDAE.BackendDAE outDlow; | ||
| 1132 | algorithm | ||
| 1133 | outDlow := match inDlow | ||
| 1134 | local | ||
| 1135 | BackendDAE.Variables globalKnownVars, globalKnownVars1; | ||
| 1136 | BackendDAE.EqSystems eqs; | ||
| 1137 | BackendDAE.Shared shared; | ||
| 1138 | |||
| 1139 | case BackendDAE.DAE(eqs, shared) | ||
| 1140 | algorithm | ||
| 1141 | ✗ | globalKnownVars1 := BackendVariable.emptyVars(); | |
| 1142 | ✗ | globalKnownVars := shared.globalKnownVars; | |
| 1143 | ✗ | globalKnownVars1 := BackendVariable.traverseBackendDAEVars(globalKnownVars, copyNonParamVariables, globalKnownVars1); | |
| 1144 | ✗ | (_, globalKnownVars1) := List.fold1(eqs,BackendDAEUtil.traverseBackendDAEExpsEqSystem, checkUnusedVariables, (globalKnownVars,globalKnownVars1)); | |
| 1145 | ✗ | (_, globalKnownVars1) := BackendDAEUtil.traverseBackendDAEExpsVars(globalKnownVars, checkUnusedParameter, (globalKnownVars,globalKnownVars1)); | |
| 1146 | ✗ | (_, globalKnownVars1) := BackendDAEUtil.traverseBackendDAEExpsVars(shared.aliasVars, checkUnusedParameter, (globalKnownVars,globalKnownVars1)); | |
| 1147 | ✗ | (_, globalKnownVars1) := BackendDAEUtil.traverseBackendDAEExpsEqns(shared.removedEqs, checkUnusedParameter, (globalKnownVars,globalKnownVars1)); | |
| 1148 | ✗ | (_, globalKnownVars1) := BackendDAEUtil.traverseBackendDAEExpsEqns(shared.initialEqs, checkUnusedParameter, (globalKnownVars,globalKnownVars1)); | |
| 1149 | ✗ | shared.globalKnownVars := globalKnownVars1; | |
| 1150 | ✗ | then | |
| 1151 | BackendDAE.DAE(eqs, shared); | ||
| 1152 | end match; | ||
| 1153 | end removeUnusedParameter; | ||
| 1154 | |||
| 1155 | protected function copyNonParamVariables | ||
| 1156 | input BackendDAE.Var inVar; | ||
| 1157 | input BackendDAE.Variables inVars; | ||
| 1158 | output BackendDAE.Var outVar; | ||
| 1159 | output BackendDAE.Variables outVars; | ||
| 1160 | algorithm | ||
| 1161 | (outVar,outVars) := match inVar | ||
| 1162 | local | ||
| 1163 | BackendDAE.Var v; | ||
| 1164 | BackendDAE.Variables vars1; | ||
| 1165 | case v as BackendDAE.VAR(varKind = BackendDAE.PARAM()) | ||
| 1166 | then (v,inVars); | ||
| 1167 | else | ||
| 1168 | algorithm | ||
| 1169 | ✗ | vars1 := BackendVariable.addVar(inVar,inVars); | |
| 1170 | then (inVar,vars1); | ||
| 1171 | end match; | ||
| 1172 | end copyNonParamVariables; | ||
| 1173 | |||
| 1174 | protected function checkUnusedParameter | ||
| 1175 | input DAE.Exp inExp; | ||
| 1176 | input tuple<BackendDAE.Variables,BackendDAE.Variables> inTpl; | ||
| 1177 | output DAE.Exp outExp; | ||
| 1178 | output tuple<BackendDAE.Variables,BackendDAE.Variables> outTpl; | ||
| 1179 | algorithm | ||
| 1180 | (outExp,outTpl) := matchcontinue (inExp,inTpl) | ||
| 1181 | local | ||
| 1182 | DAE.Exp exp; | ||
| 1183 | BackendDAE.Variables vars,vars1; | ||
| 1184 | case (exp,(vars,_)) | ||
| 1185 | algorithm | ||
| 1186 | ✗ | (_,(_,vars1)) := Expression.traverseExpBottomUp(exp,checkUnusedParameterExp,inTpl); | |
| 1187 | ✗ | then (exp,(vars,vars1)); | |
| 1188 | else (inExp,inTpl); | ||
| 1189 | end matchcontinue; | ||
| 1190 | end checkUnusedParameter; | ||
| 1191 | |||
| 1192 | protected function checkUnusedParameterExp | ||
| 1193 | input DAE.Exp inExp; | ||
| 1194 | input tuple<BackendDAE.Variables,BackendDAE.Variables> inTuple; | ||
| 1195 | output DAE.Exp outExp; | ||
| 1196 | output tuple<BackendDAE.Variables,BackendDAE.Variables> outTuple; | ||
| 1197 | algorithm | ||
| 1198 | (outExp,outTuple) := matchcontinue (inExp,inTuple) | ||
| 1199 | local | ||
| 1200 | DAE.Exp e,e1; | ||
| 1201 | BackendDAE.Variables vars,vars1; | ||
| 1202 | DAE.ComponentRef cr; | ||
| 1203 | list<DAE.Exp> expl; | ||
| 1204 | list<DAE.Var> varLst; | ||
| 1205 | BackendDAE.Var var; | ||
| 1206 | tuple<BackendDAE.Variables,BackendDAE.Variables> tp; | ||
| 1207 | |||
| 1208 | // special case for time, it is never part of the equation system | ||
| 1209 | case (e as DAE.CREF(componentRef = DAE.CREF_IDENT(ident="time")),_) | ||
| 1210 | then (e, inTuple); | ||
| 1211 | |||
| 1212 | // Special Case for Records | ||
| 1213 | case (e as DAE.CREF(componentRef = cr,ty= DAE.T_COMPLEX(varLst=varLst,complexClassType=ClassInf.RECORD(_))),tp) | ||
| 1214 | algorithm | ||
| 1215 | ✗ | expl := List.map1(varLst,Expression.generateCrefsExpFromExpVar,cr); | |
| 1216 | ✗ | (_,tp) := Expression.traverseExpList(expl,checkUnusedParameterExp,tp); | |
| 1217 | ✗ | then (e, tp); | |
| 1218 | |||
| 1219 | // Special Case for Arrays | ||
| 1220 | case (e as DAE.CREF(ty = DAE.T_ARRAY()),tp) | ||
| 1221 | algorithm | ||
| 1222 | ✗ | (e1,true) := Expression.extendArrExp(e,false); | |
| 1223 | ✗ | (_,tp) := Expression.traverseExpBottomUp(e1,checkUnusedParameterExp,tp); | |
| 1224 | ✗ | then (e, tp); | |
| 1225 | |||
| 1226 | // case for functionpointers | ||
| 1227 | case (e as DAE.CREF(ty=DAE.T_FUNCTION_REFERENCE_FUNC()),_) | ||
| 1228 | then (e, inTuple); | ||
| 1229 | |||
| 1230 | // already there | ||
| 1231 | case (e as DAE.CREF(componentRef = cr),(_,vars1)) | ||
| 1232 | algorithm | ||
| 1233 | ✗ | BackendVariable.getVar(cr, vars1); | |
| 1234 | then (e, inTuple); | ||
| 1235 | |||
| 1236 | // add it | ||
| 1237 | case (e as DAE.CREF(componentRef = cr),(vars,vars1)) | ||
| 1238 | algorithm | ||
| 1239 | ✗ | (var::_,_) := BackendVariable.getVar(cr, vars); | |
| 1240 | ✗ | vars1 := BackendVariable.addVar(var,vars1); | |
| 1241 | ✗ | then (e, (vars,vars1)); | |
| 1242 | |||
| 1243 | else (inExp,inTuple); | ||
| 1244 | end matchcontinue; | ||
| 1245 | end checkUnusedParameterExp; | ||
| 1246 | |||
| 1247 | // ============================================================================= | ||
| 1248 | // remove unused variables | ||
| 1249 | // | ||
| 1250 | // ============================================================================= | ||
| 1251 | public function removeUnusedVariables | ||
| 1252 | "author: Frenkel TUD 2011-04 | ||
| 1253 | This function removes unused variables | ||
| 1254 | from BackendDAE.BackendDAE to get speed up for compilation of | ||
| 1255 | target code" | ||
| 1256 | input BackendDAE.BackendDAE inDlow; | ||
| 1257 | output BackendDAE.BackendDAE outDlow; | ||
| 1258 | algorithm | ||
| 1259 | outDlow := match inDlow | ||
| 1260 | local | ||
| 1261 | BackendDAE.Variables globalKnownVars, globalKnownVars1; | ||
| 1262 | BackendDAE.EqSystems eqs; | ||
| 1263 | BackendDAE.Shared shared; | ||
| 1264 | tuple<BackendDAE.Variables,BackendDAE.Variables> tpl; | ||
| 1265 | |||
| 1266 | case BackendDAE.DAE(eqs, shared) | ||
| 1267 | algorithm | ||
| 1268 | 14 | globalKnownVars1 := BackendVariable.emptyVars(); | |
| 1269 | 14 | globalKnownVars := shared.globalKnownVars; | |
| 1270 | 14 | tpl := List.fold1(eqs,BackendDAEUtil.traverseBackendDAEExpsEqSystem, checkUnusedVariables, (globalKnownVars, globalKnownVars1)); | |
| 1271 | 14 | tpl := BackendDAEUtil.traverseBackendDAEExpsVars(globalKnownVars, checkUnusedVariables, tpl); | |
| 1272 | 14 | tpl := BackendDAEUtil.traverseBackendDAEExpsVars(shared.aliasVars, checkUnusedVariables, tpl); | |
| 1273 | 14 | tpl := BackendDAEUtil.traverseBackendDAEExpsEqns(shared.removedEqs, checkUnusedVariables, tpl); | |
| 1274 | 14 | (_, globalKnownVars1) := BackendDAEUtil.traverseBackendDAEExpsEqns(shared.initialEqs, checkUnusedVariables, tpl); | |
| 1275 | 14 | shared.globalKnownVars := globalKnownVars1; | |
| 1276 | 14 | then | |
| 1277 | BackendDAE.DAE(eqs, shared); | ||
| 1278 | end match; | ||
| 1279 | end removeUnusedVariables; | ||
| 1280 | |||
| 1281 | protected function checkUnusedVariables | ||
| 1282 | input DAE.Exp inExp; | ||
| 1283 | input tuple<BackendDAE.Variables,BackendDAE.Variables> inTpl; | ||
| 1284 | output DAE.Exp outExp; | ||
| 1285 | output tuple<BackendDAE.Variables,BackendDAE.Variables> outTpl; | ||
| 1286 | algorithm | ||
| 1287 | (outExp,outTpl) := matchcontinue inExp | ||
| 1288 | local | ||
| 1289 | DAE.Exp exp; | ||
| 1290 | tuple<BackendDAE.Variables,BackendDAE.Variables> tpl; | ||
| 1291 | case exp | ||
| 1292 | algorithm | ||
| 1293 | 7343 | (_,tpl) := Expression.traverseExpBottomUp(exp,checkUnusedVariablesExp,inTpl); | |
| 1294 | 7343 | then (exp,tpl); | |
| 1295 | else (inExp,inTpl); | ||
| 1296 | end matchcontinue; | ||
| 1297 | end checkUnusedVariables; | ||
| 1298 | |||
| 1299 | protected function checkUnusedVariablesExp | ||
| 1300 | input DAE.Exp inExp; | ||
| 1301 | input tuple<BackendDAE.Variables,BackendDAE.Variables> inTuple; | ||
| 1302 | output DAE.Exp outExp; | ||
| 1303 | output tuple<BackendDAE.Variables,BackendDAE.Variables> outTuple; | ||
| 1304 | algorithm | ||
| 1305 | (outExp,outTuple) := matchcontinue (inExp,inTuple) | ||
| 1306 | local | ||
| 1307 | DAE.Exp e,e1; | ||
| 1308 | BackendDAE.Variables vars,vars1; | ||
| 1309 | DAE.ComponentRef cr; | ||
| 1310 | list<DAE.Exp> expl; | ||
| 1311 | list<DAE.Var> varLst; | ||
| 1312 | BackendDAE.Var var; | ||
| 1313 | tuple<BackendDAE.Variables,BackendDAE.Variables> tp; | ||
| 1314 | |||
| 1315 | // special case for time, it is never part of the equation system | ||
| 1316 | case (e as DAE.CREF(componentRef = DAE.CREF_IDENT(ident="time")),tp) | ||
| 1317 | then (e, tp); | ||
| 1318 | |||
| 1319 | // Special Case for Records | ||
| 1320 | case (e as DAE.CREF(componentRef = cr,ty= DAE.T_COMPLEX(varLst=varLst,complexClassType=ClassInf.RECORD(_))),tp) | ||
| 1321 | algorithm | ||
| 1322 | 18 | expl := List.map1(varLst,Expression.generateCrefsExpFromExpVar,cr); | |
| 1323 | 18 | (_,tp) := Expression.traverseExpList(expl,checkUnusedVariablesExp,tp); | |
| 1324 | 18 | then (e, tp); | |
| 1325 | |||
| 1326 | // Special Case for Arrays | ||
| 1327 | case (e as DAE.CREF(ty = DAE.T_ARRAY()),tp) | ||
| 1328 | algorithm | ||
| 1329 | ✗ | (e1,true) := Expression.extendArrExp(e,false); | |
| 1330 | ✗ | (_,tp) := Expression.traverseExpBottomUp(e1,checkUnusedVariablesExp,tp); | |
| 1331 | ✗ | then (e, tp); | |
| 1332 | |||
| 1333 | // case for functionpointers | ||
| 1334 | case (DAE.CREF(ty=DAE.T_FUNCTION_REFERENCE_FUNC()),_) | ||
| 1335 | then (inExp, inTuple); | ||
| 1336 | |||
| 1337 | // already there | ||
| 1338 | case (DAE.CREF(componentRef = cr),(_,vars1)) | ||
| 1339 | algorithm | ||
| 1340 | 2400 | BackendVariable.getVar(cr, vars1); | |
| 1341 | then (inExp, inTuple); | ||
| 1342 | |||
| 1343 | // add it | ||
| 1344 | case (DAE.CREF(componentRef = cr),(vars,vars1)) | ||
| 1345 | algorithm | ||
| 1346 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 316 times.
|
2077 | (var::_,_) := BackendVariable.getVar(cr, vars); |
| 1347 | 316 | vars1 := BackendVariable.addVar(var,vars1); | |
| 1348 | 316 | then (inExp, (vars,vars1)); | |
| 1349 | |||
| 1350 | else (inExp,inTuple); | ||
| 1351 | end matchcontinue; | ||
| 1352 | end checkUnusedVariablesExp; | ||
| 1353 | |||
| 1354 | // ============================================================================= | ||
| 1355 | // remove unused functions | ||
| 1356 | // | ||
| 1357 | // ============================================================================= | ||
| 1358 | public function removeUnusedFunctions "author: Frenkel TUD 2012-03 | ||
| 1359 | This function remove unused functions from AvlTreePathFunction.Tree to get speed up | ||
| 1360 | for compilation of target code." | ||
| 1361 | input BackendDAE.EqSystems inEqs; | ||
| 1362 | input BackendDAE.Shared inShared; | ||
| 1363 | input list<BackendDAE.Equation> inEquationLst; | ||
| 1364 | input AvlTreePathFunction.Tree inFunctionTree; | ||
| 1365 | input AvlTreePathFunction.Tree inusedFunctions; | ||
| 1366 | output AvlTreePathFunction.Tree outFunctionTree; | ||
| 1367 | protected | ||
| 1368 | partial function FuncType | ||
| 1369 | input DAE.Exp inExp; | ||
| 1370 | input AvlTreePathFunction.Tree inUnsedFunctions; | ||
| 1371 | output DAE.Exp outExp; | ||
| 1372 | output AvlTreePathFunction.Tree outUsedFunctions; | ||
| 1373 | end FuncType; | ||
| 1374 | |||
| 1375 | FuncType func; | ||
| 1376 | AvlTreePathFunction.Tree funcs, usedfuncs; | ||
| 1377 | algorithm | ||
| 1378 | funcs := inFunctionTree; | ||
| 1379 | usedfuncs := inusedFunctions; | ||
| 1380 | 2493 | func := function checkUnusedFunctions(inFunctions = funcs); | |
| 1381 | |||
| 1382 | // equation system | ||
| 1383 | 2493 | usedfuncs := List.fold1(inEqs, BackendDAEUtil.traverseBackendDAEExpsEqSystem, func, usedfuncs); | |
| 1384 | 2493 | usedfuncs := List.fold1(inEqs, BackendDAEUtil.traverseBackendDAEExpsEqSystemJacobians, func, usedfuncs); | |
| 1385 | |||
| 1386 | // equation list | ||
| 1387 | 2493 | usedfuncs := List.fold1(inEquationLst, BackendEquation.traverseExpsOfEquationList_WithoutChange, func, usedfuncs); | |
| 1388 | |||
| 1389 | // shared object | ||
| 1390 | 2493 | usedfuncs := BackendDAEUtil.traverseBackendDAEExpsVars(inShared.globalKnownVars, func, usedfuncs); | |
| 1391 | 2493 | usedfuncs := BackendDAEUtil.traverseBackendDAEExpsVars(inShared.externalObjects, func, usedfuncs); | |
| 1392 | 2493 | usedfuncs := BackendDAEUtil.traverseBackendDAEExpsVars(inShared.aliasVars, func, usedfuncs); | |
| 1393 | 2493 | usedfuncs := BackendDAEUtil.traverseBackendDAEExpsEqns(inShared.removedEqs, func, usedfuncs); | |
| 1394 | 2493 | usedfuncs := BackendDAEUtil.traverseBackendDAEExpsEqns(inShared.initialEqs, func, usedfuncs); | |
| 1395 | 2493 | usedfuncs := removeUnusedFunctionsSymJacs(inShared, funcs, usedfuncs); | |
| 1396 | |||
| 1397 | outFunctionTree := usedfuncs; | ||
| 1398 | end removeUnusedFunctions; | ||
| 1399 | |||
| 1400 | public function copyRecordConstructorAndExternalObjConstructorDestructor | ||
| 1401 | input AvlTreePathFunction.Tree inAllFunctionTree; | ||
| 1402 | output AvlTreePathFunction.Tree outUsedFunctionTree; | ||
| 1403 | protected | ||
| 1404 | list<DAE.Function> allfuncs_list; | ||
| 1405 | algorithm | ||
| 1406 | 1076 | outUsedFunctionTree := AvlTreePathFunction.Tree.EMPTY(); | |
| 1407 | 1076 | allfuncs_list := DAEUtil.getFunctionList(inAllFunctionTree); | |
| 1408 | |||
| 1409 |
2/2✓ Branch 0 taken 17719 times.
✓ Branch 1 taken 1076 times.
|
18795 | for func in allfuncs_list loop |
| 1410 | () := match func | ||
| 1411 | local | ||
| 1412 | Absyn.Path path; | ||
| 1413 | list<DAE.Var> var_list; | ||
| 1414 | Option<DAE.Exp> obind; | ||
| 1415 | DAE.Exp bind_exp; | ||
| 1416 | |||
| 1417 | case DAE.RECORD_CONSTRUCTOR(path=path) algorithm | ||
| 1418 | // Add the constructor function. | ||
| 1419 | 4259 | outUsedFunctionTree := AvlTreePathFunction.add(outUsedFunctionTree, path, SOME(func)); | |
| 1420 | |||
| 1421 | // Now we traverse the bindings of the record members and look for function calls. | ||
| 1422 | try | ||
| 1423 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 4259 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4259 times.
|
4259 | DAE.T_FUNCTION(funcResultType = DAE.T_COMPLEX(varLst=var_list)) := func.type_; |
| 1424 | else | ||
| 1425 | ✗ | Error.addSourceMessage(Error.INTERNAL_ERROR, | |
| 1426 | {getInstanceName() + " got unxpected record constructor structure for " + AbsynUtil.pathString(path)}, | ||
| 1427 | sourceInfo()); | ||
| 1428 | ✗ | fail(); | |
| 1429 | end try; | ||
| 1430 | |||
| 1431 |
2/2✓ Branch 0 taken 44396 times.
✓ Branch 1 taken 4259 times.
|
48655 | for var in var_list loop |
| 1432 | 44396 | obind := Types.getBindingExpOptional(var); | |
| 1433 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 44396 times.
✓ Branch 2 taken 8194 times.
✓ Branch 3 taken 36202 times.
|
44396 | if isSome(obind) then |
| 1434 | 8194 | SOME(bind_exp) := obind; | |
| 1435 | 8194 | (_, outUsedFunctionTree) := checkUnusedFunctions(bind_exp,inAllFunctionTree,outUsedFunctionTree); | |
| 1436 | end if; | ||
| 1437 | end for; | ||
| 1438 | |||
| 1439 | then | ||
| 1440 | (); | ||
| 1441 | |||
| 1442 | // copy external objects constructors/destructors | ||
| 1443 | case DAE.FUNCTION(path = path) algorithm | ||
| 1444 |
8/8✓ Branch 1 taken 419 times.
✓ Branch 2 taken 13041 times.
✓ Branch 5 taken 378 times.
✓ Branch 6 taken 41 times.
✓ Branch 8 taken 948 times.
✓ Branch 9 taken 12471 times.
✓ Branch 12 taken 41 times.
✓ Branch 13 taken 907 times.
|
13460 | if stringEq(AbsynUtil.pathLastIdent(path), "constructor") or |
| 1445 | stringEq(AbsynUtil.pathLastIdent(path), "destructor") then | ||
| 1446 | 82 | outUsedFunctionTree := AvlTreePathFunction.add(outUsedFunctionTree, path, SOME(func)); | |
| 1447 | end if; | ||
| 1448 | then | ||
| 1449 | (); | ||
| 1450 | |||
| 1451 | end match; | ||
| 1452 | |||
| 1453 | end for; | ||
| 1454 | |||
| 1455 | end copyRecordConstructorAndExternalObjConstructorDestructor; | ||
| 1456 | |||
| 1457 | protected function removeUnusedFunctionsSymJacs | ||
| 1458 | input BackendDAE.Shared inShared; | ||
| 1459 | input AvlTreePathFunction.Tree inFunctions; | ||
| 1460 | input AvlTreePathFunction.Tree inUsedFunctions; | ||
| 1461 | output AvlTreePathFunction.Tree outUsedFunctions = inUsedFunctions; | ||
| 1462 | protected | ||
| 1463 | BackendDAE.BackendDAE bdae; | ||
| 1464 | AvlTreePathFunction.Tree usedfuncs; | ||
| 1465 | BackendDAE.Shared shared; | ||
| 1466 | algorithm | ||
| 1467 |
2/2✓ Branch 0 taken 4436 times.
✓ Branch 1 taken 2493 times.
|
6929 | for sjac in inShared.symjacs loop |
| 1468 | () := match sjac | ||
| 1469 | case (SOME((bdae, _, _, _, _, _)), _, _, _) | ||
| 1470 | algorithm | ||
| 1471 | 214 | bdae := BackendDAEUtil.setFunctionTree(bdae, inFunctions); | |
| 1472 | 214 | shared := bdae.shared; | |
| 1473 | 214 | usedfuncs := removeUnusedFunctions(bdae.eqs, shared, {}, shared.functionTree, inUsedFunctions); | |
| 1474 | 214 | outUsedFunctions := AvlTreePathFunction.join(outUsedFunctions, usedfuncs); | |
| 1475 | then | ||
| 1476 | (); | ||
| 1477 | |||
| 1478 | else (); | ||
| 1479 | end match; | ||
| 1480 | end for; | ||
| 1481 | |||
| 1482 | // Collect function if there is a data recon structure. | ||
| 1483 | () := match inShared.dataReconciliationData | ||
| 1484 | case NONE() then (); | ||
| 1485 | |||
| 1486 | case SOME(BackendDAE.DATA_RECON(symbolicJacobian = | ||
| 1487 | BackendDAE.GENERIC_JACOBIAN(jacobian=SOME((bdae, _, _, _, _, _))))) | ||
| 1488 | algorithm | ||
| 1489 | 25 | bdae := BackendDAEUtil.setFunctionTree(bdae, inFunctions); | |
| 1490 | 25 | shared := bdae.shared; | |
| 1491 | 25 | usedfuncs := removeUnusedFunctions(bdae.eqs, shared, {}, shared.functionTree, inUsedFunctions); | |
| 1492 | 25 | outUsedFunctions := AvlTreePathFunction.join(outUsedFunctions, usedfuncs); | |
| 1493 | then (); | ||
| 1494 | |||
| 1495 | // If data isSome and we have non generic jacobian what do we do? | ||
| 1496 | else algorithm | ||
| 1497 | 1 | Error.addInternalError(getInstanceName() | |
| 1498 | + ": Unexpected data reconciliation jacobian structure. ", sourceInfo()); | ||
| 1499 | 1 | then fail(); | |
| 1500 | end match; | ||
| 1501 | end removeUnusedFunctionsSymJacs; | ||
| 1502 | |||
| 1503 | protected function checkUnusedFunctions | ||
| 1504 | input DAE.Exp inExp; | ||
| 1505 | input AvlTreePathFunction.Tree inFunctions; | ||
| 1506 | input AvlTreePathFunction.Tree inUsedFunctions; | ||
| 1507 | output DAE.Exp outExp; | ||
| 1508 | output AvlTreePathFunction.Tree outUsedFunctions; | ||
| 1509 | algorithm | ||
| 1510 | 2094018 | (outExp, outUsedFunctions) := Expression.traverseExpBottomUp(inExp, | |
| 1511 | function checkUnusedFunctionsExp(inFunctions = inFunctions), inUsedFunctions); | ||
| 1512 | end checkUnusedFunctions; | ||
| 1513 | |||
| 1514 | protected function checkUnusedFunctionsExp | ||
| 1515 | input DAE.Exp inExp; | ||
| 1516 | input AvlTreePathFunction.Tree inFunctions; | ||
| 1517 | input AvlTreePathFunction.Tree inUsedFunctions; | ||
| 1518 | output DAE.Exp outExp = inExp; | ||
| 1519 | output AvlTreePathFunction.Tree outUsedFunctions; | ||
| 1520 | algorithm | ||
| 1521 | outUsedFunctions := match inExp | ||
| 1522 | local | ||
| 1523 | Absyn.Path path; | ||
| 1524 | DAE.ComponentRef cr; | ||
| 1525 | AvlTreePathFunction.Tree usedfuncs; | ||
| 1526 | |||
| 1527 | // If the expression is some kind of function call, add it to the used functions. | ||
| 1528 | case DAE.CALL(path = path) | ||
| 1529 | 87170 | then addUnusedFunction(path, inFunctions, inUsedFunctions); | |
| 1530 | |||
| 1531 | case DAE.PARTEVALFUNCTION(path = path) | ||
| 1532 | 250 | then addUnusedFunction(path, inFunctions, inUsedFunctions); | |
| 1533 | |||
| 1534 | case DAE.CREF(ty = DAE.T_FUNCTION_REFERENCE_FUNC(functionType = | ||
| 1535 | DAE.T_FUNCTION(path=path))) | ||
| 1536 | 22 | then addUnusedFunction(path, inFunctions, inUsedFunctions); | |
| 1537 | |||
| 1538 | // If it's a cref, check the cref's dimensions for function calls. | ||
| 1539 | case DAE.CREF(componentRef = cr) | ||
| 1540 | algorithm | ||
| 1541 | 1385203 | (_, usedfuncs) := Expression.traverseExpCrefDims(cr, | |
| 1542 | function checkUnusedFunctions(inFunctions = inFunctions), inUsedFunctions); | ||
| 1543 | 1385203 | then | |
| 1544 | usedfuncs; | ||
| 1545 | |||
| 1546 | // Otherwise, do nothing. | ||
| 1547 | else inUsedFunctions; | ||
| 1548 | end match; | ||
| 1549 | end checkUnusedFunctionsExp; | ||
| 1550 | |||
| 1551 | protected function addUnusedFunction | ||
| 1552 | input Absyn.Path inPath; | ||
| 1553 | input AvlTreePathFunction.Tree inFunctions; | ||
| 1554 | input AvlTreePathFunction.Tree inUsedFunctions; | ||
| 1555 | output AvlTreePathFunction.Tree outUsedFunctions = inUsedFunctions; | ||
| 1556 | protected | ||
| 1557 | Option<DAE.Function> f; | ||
| 1558 | list<DAE.Element> body; | ||
| 1559 | algorithm | ||
| 1560 | try // Check if the function has already been added. | ||
| 1561 | 87442 | AvlTreePathFunction.get(inUsedFunctions, inPath); | |
| 1562 | else // Otherwise, try to add it. | ||
| 1563 | 52318 | (f, body) := getFunctionAndBody(inPath, inFunctions); | |
| 1564 | |||
| 1565 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 52318 times.
✓ Branch 2 taken 7199 times.
✓ Branch 3 taken 45119 times.
|
52318 | if isSome(f) then |
| 1566 | 7199 | outUsedFunctions := AvlTreePathFunction.add(outUsedFunctions, inPath, f); | |
| 1567 | 7199 | (_, outUsedFunctions) := DAEUtil.traverseDAEElementList(body, | |
| 1568 | function checkUnusedFunctions(inFunctions = inFunctions), outUsedFunctions); | ||
| 1569 | end if; | ||
| 1570 | end try; | ||
| 1571 | end addUnusedFunction; | ||
| 1572 | |||
| 1573 | protected function getFunctionAndBody | ||
| 1574 | "returns the body of a function" | ||
| 1575 | input Absyn.Path inPath; | ||
| 1576 | input AvlTreePathFunction.Tree fns; | ||
| 1577 | output Option<DAE.Function> outFn; | ||
| 1578 | output list<DAE.Element> outFnBody; | ||
| 1579 | protected | ||
| 1580 | DAE.Function fn; | ||
| 1581 | algorithm | ||
| 1582 | try | ||
| 1583 |
2/4✗ Branch 1 not taken.
✓ Branch 2 taken 7199 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7199 times.
|
52318 | outFn as SOME(fn) := AvlTreePathFunction.get(fns, inPath); |
| 1584 | 7199 | outFnBody := DAEUtil.getFunctionElements(fn); | |
| 1585 | else | ||
| 1586 | outFn := NONE(); | ||
| 1587 | outFnBody := {}; | ||
| 1588 | end try; | ||
| 1589 | end getFunctionAndBody; | ||
| 1590 | |||
| 1591 | |||
| 1592 | // ============================================================================= | ||
| 1593 | // parallel back end stuff (TLM) | ||
| 1594 | // | ||
| 1595 | // ============================================================================= | ||
| 1596 | |||
| 1597 | public function collapseIndependentBlocks | ||
| 1598 | input BackendDAE.BackendDAE inDAE; | ||
| 1599 | output BackendDAE.BackendDAE outDAE; | ||
| 1600 | protected | ||
| 1601 | BackendDAE.EqSystem syst; | ||
| 1602 | list<BackendDAE.EqSystem> systs; | ||
| 1603 | BackendDAE.Shared shared; | ||
| 1604 | BackendDAE.Variables vars; | ||
| 1605 | algorithm | ||
| 1606 | 1477 | BackendDAE.DAE(systs, shared) := inDAE; | |
| 1607 |
4/4✓ Branch 0 taken 7892 times.
✓ Branch 1 taken 1477 times.
✓ Branch 2 taken 7892 times.
✓ Branch 3 taken 1477 times.
|
9369 | vars := BackendVariable.emptyVarsSized(integer(sum(BackendVariable.varsSize(s.orderedVars) for s in systs)*1.4)); |
| 1608 | // We can use listReduce as if there is no eq-system something went terribly wrong | ||
| 1609 | 1477 | syst := List.fold(listReverse(systs), mergeIndependentBlocks, BackendDAEUtil.createEqSystem(vars)); | |
| 1610 | 1477 | outDAE := BackendDAE.DAE({syst}, shared); | |
| 1611 | end collapseIndependentBlocks; | ||
| 1612 | |||
| 1613 | public function collapseIndependentContinuousBlocks | ||
| 1614 | "Like collapseIndependentBlocks, but leaves out the clocked partitions. | ||
| 1615 | The Jacobian of the ODE is taken with respect to the continuous states only, | ||
| 1616 | a clocked partition does not change between clock ticks and contributes | ||
| 1617 | nothing to it. Merged with the continuous partitions, a loop that is closed | ||
| 1618 | over a sample/hold pair looks like an algebraic loop and cannot be sorted." | ||
| 1619 | input BackendDAE.BackendDAE inDAE; | ||
| 1620 | output BackendDAE.BackendDAE outDAE; | ||
| 1621 | algorithm | ||
| 1622 | 1061 | outDAE := collapseIndependentBlocks(BackendDAE.DAE( | |
| 1623 | List.filterOnFalse(inDAE.eqs, BackendDAEUtil.isClockedSyst), inDAE.shared)); | ||
| 1624 | end collapseIndependentContinuousBlocks; | ||
| 1625 | |||
| 1626 | protected function mergeIndependentBlocks | ||
| 1627 | input BackendDAE.EqSystem syst1; | ||
| 1628 | input BackendDAE.EqSystem syst2; | ||
| 1629 | output BackendDAE.EqSystem syst; | ||
| 1630 | protected | ||
| 1631 | BackendDAE.Variables vars; | ||
| 1632 | BackendDAE.EquationArray eqs, removedEqs; | ||
| 1633 | BackendDAE.StateSets stateSets; | ||
| 1634 | algorithm | ||
| 1635 | 7892 | vars := BackendVariable.addVariables(syst1.orderedVars, syst2.orderedVars); | |
| 1636 | 7892 | eqs := BackendEquation.addList(BackendEquation.equationList(syst1.orderedEqs), syst2.orderedEqs); | |
| 1637 | 7892 | removedEqs := BackendEquation.addList(BackendEquation.equationList(syst1.removedEqs), syst2.removedEqs); | |
| 1638 | 7892 | stateSets := listAppend(syst1.stateSets, syst2.stateSets); | |
| 1639 | 7892 | syst := BackendDAEUtil.createEqSystem(vars, eqs, stateSets, BackendDAE.UNKNOWN_PARTITION(), removedEqs); | |
| 1640 | end mergeIndependentBlocks; | ||
| 1641 | |||
| 1642 | public function partitionIndependentBlocks | ||
| 1643 | "Finds independent partitions of the equation system by " | ||
| 1644 | input BackendDAE.BackendDAE dlow; | ||
| 1645 | output BackendDAE.BackendDAE outDlow; | ||
| 1646 | algorithm | ||
| 1647 | outDlow := match dlow | ||
| 1648 | local | ||
| 1649 | BackendDAE.EqSystem syst; | ||
| 1650 | list<BackendDAE.EqSystem> systs; | ||
| 1651 | BackendDAE.Shared shared; | ||
| 1652 | |||
| 1653 | case BackendDAE.DAE({syst},shared) | ||
| 1654 | algorithm | ||
| 1655 | ✗ | (systs,shared) := partitionIndependentBlocksHelper(syst,shared,Error.getNumErrorMessages(),false); | |
| 1656 | ✗ | then BackendDAE.DAE(systs,shared); | |
| 1657 | else // TODO: Improve support for partitioned systems of equations | ||
| 1658 | algorithm | ||
| 1659 | ✗ | BackendDAE.DAE({syst},shared) := collapseIndependentBlocks(dlow); | |
| 1660 | ✗ | (systs,shared) := partitionIndependentBlocksHelper(syst,shared,Error.getNumErrorMessages(),false); | |
| 1661 | ✗ | then BackendDAE.DAE(systs,shared); | |
| 1662 | end match; | ||
| 1663 | end partitionIndependentBlocks; | ||
| 1664 | |||
| 1665 | public function partitionIndependentBlocksHelper | ||
| 1666 | "Finds independent partitions of the equation system by " | ||
| 1667 | input BackendDAE.EqSystem isyst; | ||
| 1668 | input BackendDAE.Shared ishared; | ||
| 1669 | input Integer numErrorMessages; | ||
| 1670 | input Boolean throwNoError; | ||
| 1671 | output list<BackendDAE.EqSystem> systs; | ||
| 1672 | output BackendDAE.Shared oshared; | ||
| 1673 | algorithm | ||
| 1674 | (systs,oshared) := matchcontinue (isyst, ishared) | ||
| 1675 | local | ||
| 1676 | BackendDAE.AdjacencyMatrix m, mT, rm, rmT; | ||
| 1677 | array<Integer> eqPartMap, varPartMap, rixs; | ||
| 1678 | array<Boolean> vars, rvars; | ||
| 1679 | Boolean b, isInitial; | ||
| 1680 | Integer i; | ||
| 1681 | BackendDAE.Shared shared; | ||
| 1682 | BackendDAE.EqSystem syst; | ||
| 1683 | AvlTreePathFunction.Tree funcs; | ||
| 1684 | case (syst, shared) | ||
| 1685 | algorithm | ||
| 1686 | 1120 | isInitial := BackendDAEUtil.isInitializationDAE(ishared); | |
| 1687 | 1120 | funcs := BackendDAEUtil.getFunctions(ishared); | |
| 1688 | 1120 | (syst, m, mT) := BackendDAEUtil.getAdjacencyMatrixfromOption(syst, BackendDAE.NORMAL(), SOME(funcs), isInitial); | |
| 1689 | 1120 | (rm, rmT) := BackendDAEUtil.removedAdjacencyMatrix(syst, BackendDAE.NORMAL(), SOME(funcs), isInitial); | |
| 1690 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1120 times.
|
2240 | eqPartMap := arrayCreate(arrayLength(m), 0); |
| 1691 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1120 times.
|
2240 | varPartMap := arrayCreate(arrayLength(mT), 0); |
| 1692 | 1120 | rixs := arrayCreate(arrayLength(rm), 0); | |
| 1693 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1120 times.
|
2240 | vars := arrayCreate(arrayLength(mT), false); |
| 1694 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1120 times.
|
2240 | rvars := arrayCreate(arrayLength(rmT), false); |
| 1695 | // ixsT = arrayCreate(arrayLength(mT),0); | ||
| 1696 | 1120 | i := SynchronousFeatures.partitionIndependentBlocks0(m, mT, rm, rmT, eqPartMap, varPartMap, rixs, vars, rvars); | |
| 1697 | // i2 = SynchronousFeatures.partitionIndependentBlocks0(mT,m,ixsT); | ||
| 1698 | b := i > 1; | ||
| 1699 | // bcall2(b,BackendDump.dumpBackendDAE,BackendDAE.DAE({syst},shared), "partitionIndependentBlocksHelper"); | ||
| 1700 | // printPartition(b,ixs); | ||
| 1701 |
2/2✓ Branch 0 taken 762 times.
✓ Branch 1 taken 358 times.
|
1120 | systs := if b then SynchronousFeatures.partitionIndependentBlocksSplitBlocks(i, syst, eqPartMap, rixs, mT, rmT, throwNoError, funcs, isInitial) else {syst}; |
| 1702 | // print("Number of partitioned systems: " + intString(listLength(systs)) + "\n"); | ||
| 1703 | // List.map1_0(systs, BackendDump.dumpEqSystem, "System"); | ||
| 1704 | 1120 | GCExt.free(eqPartMap); | |
| 1705 | 1120 | GCExt.free(varPartMap); | |
| 1706 | 1120 | GCExt.free(rixs); | |
| 1707 | then (systs,shared); | ||
| 1708 | else | ||
| 1709 | algorithm | ||
| 1710 | ✗ | Error.assertion(not (numErrorMessages==Error.getNumErrorMessages()),"BackendDAEOptimize.partitionIndependentBlocks failed without good error message",Absyn.dummyInfo); | |
| 1711 | ✗ | then fail(); | |
| 1712 | end matchcontinue; | ||
| 1713 | end partitionIndependentBlocksHelper; | ||
| 1714 | |||
| 1715 | |||
| 1716 | // ============================================================================= | ||
| 1717 | // residual stuff ... for whatever reason | ||
| 1718 | // | ||
| 1719 | // ============================================================================= | ||
| 1720 | |||
| 1721 | public function residualForm | ||
| 1722 | "Puts equations like x=y in the form of 0=x-y" | ||
| 1723 | input BackendDAE.BackendDAE dlow; | ||
| 1724 | output BackendDAE.BackendDAE odlow; | ||
| 1725 | algorithm | ||
| 1726 | ✗ | odlow := BackendDAEUtil.mapEqSystem1(dlow,residualForm1,1); | |
| 1727 | end residualForm; | ||
| 1728 | |||
| 1729 | protected function residualForm1 | ||
| 1730 | "Puts equations like x=y in the form of 0=x-y" | ||
| 1731 | input BackendDAE.EqSystem syst; | ||
| 1732 | input Integer i; | ||
| 1733 | input BackendDAE.Shared shared; | ||
| 1734 | output BackendDAE.EqSystem osyst = syst; | ||
| 1735 | output BackendDAE.Shared oshared = shared; | ||
| 1736 | protected | ||
| 1737 | BackendDAE.EquationArray eqs; | ||
| 1738 | algorithm | ||
| 1739 | ✗ | BackendDAE.EQSYSTEM(orderedEqs=eqs) := syst; | |
| 1740 | ✗ | BackendEquation.traverseEquationArray_WithUpdate(eqs, residualForm2, 1); | |
| 1741 | end residualForm1; | ||
| 1742 | |||
| 1743 | protected function residualForm2 | ||
| 1744 | input BackendDAE.Equation inEq; | ||
| 1745 | input Integer ii; | ||
| 1746 | output BackendDAE.Equation outEq; | ||
| 1747 | output Integer oi; | ||
| 1748 | algorithm | ||
| 1749 | (outEq,oi) := matchcontinue (inEq,ii) | ||
| 1750 | local | ||
| 1751 | DAE.Exp e1,e2,e; | ||
| 1752 | DAE.ElementSource source; | ||
| 1753 | Integer i; | ||
| 1754 | BackendDAE.EquationAttributes eqAttr; | ||
| 1755 | |||
| 1756 | case (BackendDAE.EQUATION(e1,e2,source,eqAttr),i) | ||
| 1757 | algorithm | ||
| 1758 | // This is ok, because EQUATION is not an array equation :D | ||
| 1759 | ✗ | DAE.T_REAL() := Expression.typeof(e1); | |
| 1760 | ✗ | false := Expression.isZero(e1) or Expression.isZero(e2); | |
| 1761 | ✗ | e := DAE.BINARY(e1,DAE.SUB(DAE.T_REAL_DEFAULT),e2); | |
| 1762 | ✗ | (e,_) := ExpressionSimplify.simplify(e); | |
| 1763 | ✗ | source := ElementSource.addSymbolicTransformation(source, DAE.OP_RESIDUAL(e1,e2,e)); | |
| 1764 | ✗ | then (BackendDAE.EQUATION(DAE.RCONST(0.0),e,source,eqAttr),i); | |
| 1765 | else (inEq,ii); | ||
| 1766 | end matchcontinue; | ||
| 1767 | end residualForm2; | ||
| 1768 | |||
| 1769 | // ============================================================================= | ||
| 1770 | // countOperations | ||
| 1771 | // | ||
| 1772 | // ============================================================================= | ||
| 1773 | |||
| 1774 | public function countOperations "author: Frenkel TUD 2011-05" | ||
| 1775 | input BackendDAE.BackendDAE inDAE; | ||
| 1776 | output BackendDAE.BackendDAE outDAE; | ||
| 1777 | algorithm | ||
| 1778 | ✗ | if Flags.isSet(Flags.COUNT_OPERATIONS) then | |
| 1779 | ✗ | (outDAE, _) := BackendDAEUtil.mapEqSystemAndFold(inDAE, countOperations0, false); | |
| 1780 | else | ||
| 1781 | outDAE := inDAE; | ||
| 1782 | end if; | ||
| 1783 | end countOperations; | ||
| 1784 | |||
| 1785 | protected function countOperations0 "author: Frenkel TUD 2011-05" | ||
| 1786 | input BackendDAE.EqSystem isyst; | ||
| 1787 | input BackendDAE.Shared inShared; | ||
| 1788 | input Boolean inChanged; | ||
| 1789 | output BackendDAE.EqSystem osyst = isyst; | ||
| 1790 | output BackendDAE.Shared outShared = inShared; | ||
| 1791 | output Boolean outChanged = inChanged; | ||
| 1792 | protected | ||
| 1793 | list<BackendDAE.CompInfo> compInfos; | ||
| 1794 | BackendDAE.StrongComponents comps; | ||
| 1795 | algorithm | ||
| 1796 | ✗ | BackendDAE.EQSYSTEM(matching=BackendDAE.MATCHING(comps=comps)) := isyst; | |
| 1797 | ✗ | compInfos := countOperationstraverseComps(comps, isyst, inShared,{}); | |
| 1798 | end countOperations0; | ||
| 1799 | |||
| 1800 | public function countOperationstraverseComps "author: Frenkel TUD 2012-05" | ||
| 1801 | input BackendDAE.StrongComponents inComps; | ||
| 1802 | input BackendDAE.EqSystem isyst; | ||
| 1803 | input BackendDAE.Shared ishared; | ||
| 1804 | input list<BackendDAE.CompInfo> compInfosIn; | ||
| 1805 | output list<BackendDAE.CompInfo> compInfosOut; | ||
| 1806 | algorithm | ||
| 1807 | compInfosOut := matchcontinue (inComps, ishared) | ||
| 1808 | local | ||
| 1809 | Integer eqIdx, numAdd,numMul,numDiv,numTrig,numRel,numOth, numFuncs, numLog, size, jacEntries; | ||
| 1810 | Real density; | ||
| 1811 | list<Integer> eqs, tornEqs,otherEqs; | ||
| 1812 | BackendDAE.StrongComponent comp; | ||
| 1813 | BackendDAE.StrongComponents rest; | ||
| 1814 | BackendDAE.EquationArray eqns; | ||
| 1815 | BackendDAE.Variables vars; | ||
| 1816 | BackendDAE.Equation eqn; | ||
| 1817 | BackendDAE.CompInfo compInfo, allOps, torn,other; | ||
| 1818 | list<BackendDAE.Equation> eqnlst; | ||
| 1819 | BackendDAE.Jacobian jac; | ||
| 1820 | AvlTreePathFunction.Tree funcs; | ||
| 1821 | list<BackendDAE.Var> varlst; | ||
| 1822 | list<DAE.Exp> explst; | ||
| 1823 | BackendDAE.InnerEquations innerEquations; | ||
| 1824 | list<Integer> vlst; | ||
| 1825 | list<list<Integer>> vLstLst; | ||
| 1826 | case ({}, _) then compInfosIn; | ||
| 1827 | case (BackendDAE.SINGLEEQUATION(eqn=eqIdx)::rest, _) | ||
| 1828 | algorithm | ||
| 1829 | 1428 | eqns := BackendEquation.getEqnsFromEqSystem(isyst); | |
| 1830 | 1428 | eqn := BackendEquation.get(eqns, eqIdx); | |
| 1831 | //BackendDump.dumpBackendDAEEqnList({eqn},"AN EQUATION",true); | ||
| 1832 | //BackendDump.dumpEquationList({eqn},""); | ||
| 1833 | 1428 | (_,(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs)) := BackendEquation.traverseExpsOfEquation(eqn,function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0)); | |
| 1834 | 1428 | compInfo := BackendDAE.COUNTER(listHead(inComps),numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs); | |
| 1835 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1428 times.
|
1428 | if Flags.isSet(Flags.COUNT_OPERATIONS) then BackendDump.dumpCompInfo(compInfo); end if; |
| 1836 | 1428 | then countOperationstraverseComps(rest,isyst,ishared,compInfo::compInfosIn); | |
| 1837 | |||
| 1838 | case (BackendDAE.SINGLEWHENEQUATION(eqn=eqIdx)::rest, _) | ||
| 1839 | algorithm | ||
| 1840 | 27 | eqn := BackendEquation.get(BackendEquation.getEqnsFromEqSystem(isyst), eqIdx); | |
| 1841 | //BackendDump.printEquation(eqn); | ||
| 1842 | 27 | (_,(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs)) := BackendEquation.traverseExpsOfEquation(eqn,function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0)); | |
| 1843 | 27 | compInfo := BackendDAE.COUNTER(listHead(inComps),numAdd,numMul,numDiv,numTrig,numRel,numLog+1,numOth,numFuncs); | |
| 1844 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 27 times.
|
27 | if Flags.isSet(Flags.COUNT_OPERATIONS) then BackendDump.dumpCompInfo(compInfo); end if; |
| 1845 | 27 | then countOperationstraverseComps(rest,isyst,ishared,compInfo::compInfosIn); | |
| 1846 | |||
| 1847 | case ((comp as BackendDAE.EQUATIONSYSTEM(eqns=eqs,jac=jac,jacType=BackendDAE.JAC_LINEAR()))::rest, _) | ||
| 1848 | algorithm | ||
| 1849 | ✗ | BackendDAETransform.getEquationAndSolvedVar(comp, BackendEquation.getEqnsFromEqSystem(isyst), BackendVariable.daeVars(isyst)); | |
| 1850 | ✗ | size := listLength(eqs); | |
| 1851 | ✗ | density := realDiv(intReal(getNumJacEntries(jac)),intReal(size*size )); | |
| 1852 | ✗ | allOps := BackendDAE.COUNTER(comp,0,0,0,0,0,0,0,0); | |
| 1853 | ✗ | allOps := countOperationsJac(jac,ishared,allOps); | |
| 1854 | ✗ | compInfo := BackendDAE.SYSTEM(comp,allOps,size,density); | |
| 1855 | ✗ | then countOperationstraverseComps(rest,isyst,ishared,compInfo::compInfosIn); | |
| 1856 | |||
| 1857 | case ((comp as BackendDAE.EQUATIONSYSTEM(jac=jac))::rest, _) | ||
| 1858 | algorithm | ||
| 1859 | 22 | (eqnlst,_,_) := BackendDAETransform.getEquationAndSolvedVar(comp, BackendEquation.getEqnsFromEqSystem(isyst), BackendVariable.daeVars(isyst)); | |
| 1860 | 22 | size := listLength(eqnlst); | |
| 1861 | 22 | (numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs) := BackendDAEUtil.traverseBackendDAEExpsEqns(BackendEquation.listEquation(eqnlst),function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0)); | |
| 1862 | 22 | allOps := BackendDAE.COUNTER(comp,numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs); | |
| 1863 | 22 | jacEntries := getNumJacEntries(jac); | |
| 1864 |
1/2✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
|
22 | if intEq(jacEntries,-1) then jacEntries := size*size; end if; // a non linear system that is too small and too dense (usually 2x2) to be torn |
| 1865 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
|
22 | density := realDiv(intReal(jacEntries),intReal(size*size)); |
| 1866 | 22 | compInfo := BackendDAE.SYSTEM(comp,allOps,size,density); | |
| 1867 | 22 | then | |
| 1868 | countOperationstraverseComps(rest,isyst,ishared,compInfo::compInfosIn); | ||
| 1869 | |||
| 1870 | case ((comp as BackendDAE.SINGLEARRAY(eqn=eqIdx))::rest, _) | ||
| 1871 | algorithm | ||
| 1872 | ✗ | eqn := BackendEquation.get(BackendEquation.getEqnsFromEqSystem(isyst), eqIdx); | |
| 1873 | ✗ | (_,(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs)) := BackendEquation.traverseExpsOfEquation(eqn,function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0)); | |
| 1874 | ✗ | compInfo := BackendDAE.COUNTER(comp,numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs); | |
| 1875 | ✗ | then | |
| 1876 | countOperationstraverseComps(rest,isyst,ishared,compInfo::compInfosIn); | ||
| 1877 | |||
| 1878 | case ((comp as BackendDAE.SINGLEIFEQUATION(eqn=eqIdx))::rest, _) | ||
| 1879 | algorithm | ||
| 1880 | ✗ | eqn := BackendEquation.get(BackendEquation.getEqnsFromEqSystem(isyst), eqIdx); | |
| 1881 | ✗ | (_,(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs)) := BackendEquation.traverseExpsOfEquation(eqn,function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0)); | |
| 1882 | ✗ | compInfo := BackendDAE.COUNTER(comp,numAdd,numMul,numDiv,numTrig,numRel,numLog+1,numOth,numFuncs); | |
| 1883 | ✗ | then | |
| 1884 | countOperationstraverseComps(rest,isyst,ishared,compInfo::compInfosIn); | ||
| 1885 | |||
| 1886 | case ((comp as BackendDAE.SINGLEALGORITHM(eqn=eqIdx))::rest, _) | ||
| 1887 | algorithm | ||
| 1888 | 1 | eqn := BackendEquation.get(BackendEquation.getEqnsFromEqSystem(isyst), eqIdx); | |
| 1889 | 1 | (_,(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs)) := BackendEquation.traverseExpsOfEquation(eqn,function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0)); | |
| 1890 | 1 | compInfo := BackendDAE.COUNTER(comp,numAdd,numMul,numDiv,numTrig,numRel,numLog+1,numOth,numFuncs); | |
| 1891 | 1 | then | |
| 1892 | countOperationstraverseComps(rest,isyst,ishared,compInfo::compInfosIn); | ||
| 1893 | |||
| 1894 | case ((comp as BackendDAE.SINGLECOMPLEXEQUATION(eqn=eqIdx))::rest, _) | ||
| 1895 | algorithm | ||
| 1896 | ✗ | eqn := BackendEquation.get(BackendEquation.getEqnsFromEqSystem(isyst), eqIdx); | |
| 1897 | ✗ | (_,(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs)) := BackendEquation.traverseExpsOfEquation(eqn,function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0)); | |
| 1898 | ✗ | compInfo := BackendDAE.COUNTER(comp,numAdd,numMul,numDiv,numTrig,numRel,numLog+1,numOth,numFuncs); | |
| 1899 | ✗ | then | |
| 1900 | countOperationstraverseComps(rest,isyst,ishared,compInfo::compInfosIn); | ||
| 1901 | |||
| 1902 | case (BackendDAE.TORNSYSTEM(strictTearingSet=BackendDAE.TEARINGSET(tearingvars=vlst, residualequations=tornEqs, innerEquations= innerEquations), linear = true)::rest, BackendDAE.SHARED(functionTree=funcs)) | ||
| 1903 | algorithm | ||
| 1904 | 30 | comp := listHead(inComps); | |
| 1905 | 30 | eqns := BackendEquation.getEqnsFromEqSystem(isyst); | |
| 1906 | 30 | vars := BackendVariable.daeVars(isyst); | |
| 1907 | // the torn equations | ||
| 1908 | 30 | eqnlst := BackendEquation.getList(tornEqs,eqns); | |
| 1909 | 30 | varlst := List.map1(vlst,BackendVariable.getVarAtIndexFirst, vars); | |
| 1910 | 30 | (explst,_) := BackendDAEUtil.getEqnSysRhs(BackendEquation.listEquation(eqnlst),BackendVariable.listVar1(varlst),SOME(funcs)); | |
| 1911 | 30 | (_,(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs)) := Expression.traverseExpList(explst,function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0)); | |
| 1912 | 30 | torn := BackendDAE.COUNTER(comp,numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs); | |
| 1913 | // the other eqs | ||
| 1914 | 30 | (otherEqs,vLstLst,_) := List.map_3(innerEquations, BackendDAEUtil.getEqnAndVarsFromInnerEquation); | |
| 1915 | 30 | vlst := List.flatten(vLstLst); | |
| 1916 | 30 | eqnlst := BackendEquation.getList(otherEqs,eqns); | |
| 1917 | 30 | varlst := List.map1(vlst,BackendVariable.getVarAtIndexFirst, vars); | |
| 1918 | 30 | (explst,_) := BackendDAEUtil.getEqnSysRhs(BackendEquation.listEquation(eqnlst),BackendVariable.listVar1(varlst),SOME(funcs)); | |
| 1919 | 30 | (_,(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs)) := Expression.traverseExpList(explst,function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0)); | |
| 1920 | 30 | other := BackendDAE.COUNTER(comp,numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs); | |
| 1921 | 30 | compInfo := BackendDAE.TORN_ANALYSE(comp,torn,other,listLength(tornEqs)); | |
| 1922 | 30 | then | |
| 1923 | countOperationstraverseComps(rest,isyst,ishared,compInfo::compInfosIn); | ||
| 1924 | case (BackendDAE.TORNSYSTEM(strictTearingSet=BackendDAE.TEARINGSET(residualequations=tornEqs, innerEquations = innerEquations), linear = false)::rest, BackendDAE.SHARED()) | ||
| 1925 | algorithm | ||
| 1926 | 23 | comp := listHead(inComps); | |
| 1927 | 23 | eqns := BackendEquation.getEqnsFromEqSystem(isyst); | |
| 1928 | // the torn equations | ||
| 1929 | 23 | eqnlst := BackendEquation.getList(tornEqs,eqns); | |
| 1930 | 23 | explst := List.map(eqnlst,BackendEquation.getEquationRHS); | |
| 1931 | 23 | (_,(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs)) := Expression.traverseExpList(explst,function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0)); | |
| 1932 | 23 | torn := BackendDAE.COUNTER(comp,numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs); | |
| 1933 | // the other eqs | ||
| 1934 | 23 | (otherEqs,_,_) := List.map_3(innerEquations, BackendDAEUtil.getEqnAndVarsFromInnerEquation); | |
| 1935 | 23 | eqnlst := BackendEquation.getList(otherEqs,eqns); | |
| 1936 | 23 | explst := List.map(eqnlst,BackendEquation.getEquationRHS); | |
| 1937 | 23 | (_,(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs)) := Expression.traverseExpList(explst,function countOperationsExp(shared=ishared),(0,0,0,0,0,0,0,0)); | |
| 1938 | 23 | other := BackendDAE.COUNTER(comp,numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs); | |
| 1939 | 23 | compInfo := BackendDAE.TORN_ANALYSE(comp,torn,other,listLength(tornEqs)); | |
| 1940 | 23 | then | |
| 1941 | countOperationstraverseComps(rest,isyst,ishared,compInfo::compInfosIn); | ||
| 1942 | case (comp::rest, _) | ||
| 1943 | algorithm | ||
| 1944 | ✗ | print("not supported component: "+BackendDump.strongComponentString(comp)+"\n"); | |
| 1945 | ✗ | then | |
| 1946 | countOperationstraverseComps(rest,isyst,ishared,compInfosIn); | ||
| 1947 | end matchcontinue; | ||
| 1948 | end countOperationstraverseComps; | ||
| 1949 | |||
| 1950 | protected function getNumJacEntries | ||
| 1951 | input BackendDAE.Jacobian inJac; | ||
| 1952 | output Integer numEntries; | ||
| 1953 | algorithm | ||
| 1954 | numEntries := match inJac | ||
| 1955 | local | ||
| 1956 | list<tuple<Integer, Integer, BackendDAE.Equation>> jac; | ||
| 1957 | list<BackendDAE.Var> vars1, vars2; | ||
| 1958 | case BackendDAE.FULL_JACOBIAN(NONE()) | ||
| 1959 | then -1; | ||
| 1960 | case BackendDAE.FULL_JACOBIAN(SOME(jac)) | ||
| 1961 | ✗ | then listLength(jac); | |
| 1962 | case BackendDAE.EMPTY_JACOBIAN() | ||
| 1963 | then -1; | ||
| 1964 | /* TODO: implement/check for GENERIC_JACOBIAN */ | ||
| 1965 | case BackendDAE.GENERIC_JACOBIAN(jacobian=NONE()) | ||
| 1966 | then -1; | ||
| 1967 | case BackendDAE.GENERIC_JACOBIAN(jacobian=SOME((_,_,vars1,vars2,_,_))) | ||
| 1968 | guard | ||
| 1969 | listLength(vars1) == listLength(vars2) | ||
| 1970 | ✗ | then listLength(vars1); | |
| 1971 | else | ||
| 1972 | algorithm | ||
| 1973 | //print(BackendDump.jacobianString(inJac)); | ||
| 1974 | ✗ | print("another JAC\n"); | |
| 1975 | then -1; | ||
| 1976 | end match; | ||
| 1977 | end getNumJacEntries; | ||
| 1978 | |||
| 1979 | |||
| 1980 | protected function countOperationsJac | ||
| 1981 | input BackendDAE.Jacobian inJac; | ||
| 1982 | input BackendDAE.Shared shared; | ||
| 1983 | input BackendDAE.CompInfo compInfoIn; | ||
| 1984 | output BackendDAE.CompInfo compInfoOut; | ||
| 1985 | algorithm | ||
| 1986 | compInfoOut := match(inJac, compInfoIn) | ||
| 1987 | local | ||
| 1988 | Integer numAdd,numMul,numDiv,numOth,numTrig,numRel,numLog, numFuncs; | ||
| 1989 | list<tuple<Integer, Integer, BackendDAE.Equation>> jac; | ||
| 1990 | BackendDAE.StrongComponent comp; | ||
| 1991 | case (BackendDAE.FULL_JACOBIAN(NONE()), _) then compInfoIn; | ||
| 1992 | case (BackendDAE.FULL_JACOBIAN(SOME(jac)), BackendDAE.COUNTER(comp=comp,numAdds=numAdd,numMul=numMul,numDiv=numDiv,numTrig=numTrig,numRelations=numRel,numLog=numLog,numOth=numOth,funcCalls=numFuncs)) | ||
| 1993 | algorithm | ||
| 1994 | ✗ | (numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs) := List.fold(jac,function countOperationsJac1(shared=shared),((numAdd,numMul,numDiv,numOth,numTrig,numRel,numLog,numFuncs))); | |
| 1995 | ✗ | then BackendDAE.COUNTER(comp,numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs); | |
| 1996 | /* TODO: implement for GENERIC_JACOBIAN */ | ||
| 1997 | case (_, _) then compInfoIn; | ||
| 1998 | end match; | ||
| 1999 | end countOperationsJac; | ||
| 2000 | |||
| 2001 | protected function countOperationsJac1 | ||
| 2002 | input tuple<Integer, Integer, BackendDAE.Equation> inJac; | ||
| 2003 | input BackendDAE.Shared shared; | ||
| 2004 | input tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> inTpl; | ||
| 2005 | output tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> outTpl; | ||
| 2006 | algorithm | ||
| 2007 | ✗ | (_,outTpl) := BackendEquation.traverseExpsOfEquation(Util.tuple33(inJac),function countOperationsExp(shared=shared),inTpl); | |
| 2008 | end countOperationsJac1; | ||
| 2009 | |||
| 2010 | public function countOperationsExp | ||
| 2011 | input DAE.Exp inExp; | ||
| 2012 | input BackendDAE.Shared shared; | ||
| 2013 | input tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> inTpl; | ||
| 2014 | output DAE.Exp outExp; | ||
| 2015 | output tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> outTpl; | ||
| 2016 | algorithm | ||
| 2017 | 13923 | (outExp,outTpl) := Expression.traverseExpBottomUp(inExp,function traversecountOperationsExp(shared=shared),inTpl); | |
| 2018 | end countOperationsExp; | ||
| 2019 | |||
| 2020 | protected function traversecountOperationsExp | ||
| 2021 | input DAE.Exp inExp; | ||
| 2022 | input BackendDAE.Shared shared; | ||
| 2023 | input tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> inTuple; | ||
| 2024 | output DAE.Exp outExp; | ||
| 2025 | output tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> outTuple; | ||
| 2026 | algorithm | ||
| 2027 | (outExp,outTuple) := matchcontinue (inExp, inTuple) | ||
| 2028 | local | ||
| 2029 | Absyn.Path path; | ||
| 2030 | DAE.Exp e,cond,exp1,exp2; | ||
| 2031 | DAE.Function func; | ||
| 2032 | Integer i1,i2,i3,i4,i5,i6,i7,i8; | ||
| 2033 | tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> tpl; | ||
| 2034 | DAE.Operator op; | ||
| 2035 | String opName; | ||
| 2036 | Absyn.Path path; | ||
| 2037 | list<DAE.Exp> expLst; | ||
| 2038 | list<DAE.Element> elemLst; | ||
| 2039 | //case (e as DAE.BINARY(operator=DAE.POW(),exp2=DAE.RCONST(rexp2)),_,(i1,i2,i3,i4,i5,i6)) equation | ||
| 2040 | // iexp2 = realInt(rexp2); | ||
| 2041 | // true = realEq(rexp2, intReal(iexp2)); | ||
| 2042 | // i2_1 = i2+intAbs(iexp2)-1; | ||
| 2043 | // then (e, (i1,i2_1,i3,i4,i5,i6)); | ||
| 2044 | |||
| 2045 | case (e as DAE.BINARY(operator=op), _) algorithm | ||
| 2046 | 11407 | tpl := countOperator(op,inTuple); | |
| 2047 | then (e, tpl); | ||
| 2048 | |||
| 2049 | case (e as DAE.UNARY(operator=op), _) algorithm | ||
| 2050 | 771 | tpl := countOperator(op,inTuple); | |
| 2051 | then (e, tpl); | ||
| 2052 | |||
| 2053 | case (e as DAE.LBINARY(operator=op), _) algorithm | ||
| 2054 | 331 | tpl := countOperator(op,inTuple); | |
| 2055 | then (e, tpl); | ||
| 2056 | |||
| 2057 | case (e as DAE.LUNARY(operator=op), _) algorithm | ||
| 2058 | 433 | tpl := countOperator(op,inTuple); | |
| 2059 | then (e, tpl); | ||
| 2060 | |||
| 2061 | case (e as DAE.RELATION(operator=op), _) algorithm | ||
| 2062 | 1935 | tpl := countOperator(op,inTuple); | |
| 2063 | then (e, tpl); | ||
| 2064 | |||
| 2065 | case (e as DAE.IFEXP(expCond=cond,expThen=exp1,expElse=exp2), _) algorithm | ||
| 2066 | //count all branches, use the complete count for the condition and one additional logical count | ||
| 2067 | 938 | (_,tpl) := traversecountOperationsExp(exp1,shared,inTuple); | |
| 2068 | 938 | (_,tpl) := traversecountOperationsExp(exp2,shared,tpl); | |
| 2069 | 938 | (_,(i1,i2,i3,i4,i5,i6,i7,i8)) := traversecountOperationsExp(cond,shared,tpl); | |
| 2070 | 938 | then (e, (i1,i2,i3,i4,i5,i6+1,i7,i8)); | |
| 2071 | |||
| 2072 | case (e as DAE.RECORD(exps=expLst), _) algorithm | ||
| 2073 | 120 | (_,tpl) := Expression.traverseExpList(expLst,function countOperationsExp(shared=shared),inTuple); | |
| 2074 | 120 | then (e, tpl); | |
| 2075 | |||
| 2076 | case (e as DAE.ARRAY(array=expLst), _) algorithm | ||
| 2077 | 352 | (_,tpl) := Expression.traverseExpList(expLst,function countOperationsExp(shared=shared),inTuple); | |
| 2078 | 352 | then (e, tpl); | |
| 2079 | |||
| 2080 | case (e as DAE.TUPLE(PR=expLst), _) algorithm | ||
| 2081 | 154 | (_,tpl) := Expression.traverseExpList(expLst,function countOperationsExp(shared=shared),inTuple); | |
| 2082 | 154 | then (e, tpl); | |
| 2083 | |||
| 2084 | case (e as DAE.CALL(path=Absyn.IDENT(name=opName)), (i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2085 | guard stringEq(opName,"sin") or stringEq(opName,"cos") or stringEq(opName,"tan") | ||
| 2086 | 151 | then (e, (i1,i2,i3,i4+1,i5,i6,i7,i8)); | |
| 2087 | |||
| 2088 | case (e as DAE.CALL(path=Absyn.IDENT(name="der")), (i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2089 | 1159 | then (e, (i1,i2,i3,i4,i5,i6,i7,i8)); | |
| 2090 | |||
| 2091 | case (e as DAE.CALL(path=Absyn.IDENT(name="exp")), (i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2092 | 59 | then (e, (i1,i2,i3,i4,i5,i6,i7+1,i8)); | |
| 2093 | |||
| 2094 | case (e as DAE.CALL(path=Absyn.IDENT(name="pre")), (i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2095 | 245 | then (e, (i1,i2,i3,i4,i5,i6,i7,i8+1)); | |
| 2096 | |||
| 2097 | case (e as DAE.CALL(path=Absyn.IDENT(name="previous")), (i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2098 | ✗ | then (e, (i1,i2,i3,i4,i5,i6,i7,i8+1)); | |
| 2099 | |||
| 2100 | case (e as DAE.CALL(path=path), _) algorithm | ||
| 2101 | 2024 | func := DAEUtil.getNamedFunction(path,BackendDAEUtil.getFunctions(shared)); | |
| 2102 | 1135 | elemLst := DAEUtil.getFunctionElements(func); | |
| 2103 | //print(ExpressionDump.dumpExpStr(e,0)+"\n"); | ||
| 2104 | //print("THE FUNCTION CALL\n "+DAEDump.dumpElementsStr(elemLst)+"\n"); | ||
| 2105 | 1135 | (i1,i2,i3,i4,i5,i6,i7,i8) := countOperationsInFunction(elemLst,shared,inTuple); | |
| 2106 | 1135 | then (e, (i1,i2,i3,i4,i5,i6,i7,i8+1)); | |
| 2107 | else | ||
| 2108 | algorithm | ||
| 2109 | //print(ExpressionDump.dumpExpStr(inExp,0)+"\n"); | ||
| 2110 | then (inExp,inTuple); | ||
| 2111 | end matchcontinue; | ||
| 2112 | end traversecountOperationsExp; | ||
| 2113 | |||
| 2114 | protected function countOperationsInFunction | ||
| 2115 | input list<DAE.Element> elemLst; | ||
| 2116 | input BackendDAE.Shared shared; | ||
| 2117 | input tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> inTpl; | ||
| 2118 | output tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> outTpl; | ||
| 2119 | algorithm | ||
| 2120 | outTpl := matchcontinue elemLst | ||
| 2121 | local | ||
| 2122 | tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> tpl; | ||
| 2123 | DAE.Exp exp1, exp2; | ||
| 2124 | list<DAE.Statement> stmts; | ||
| 2125 | list<DAE.Element> rest; | ||
| 2126 | case {} | ||
| 2127 | algorithm | ||
| 2128 | then inTpl; | ||
| 2129 | case DAE.ALGORITHM(algorithm_=DAE.ALGORITHM_STMTS(statementLst=stmts))::rest | ||
| 2130 | algorithm | ||
| 2131 | 878 | (_,tpl) := DAEUtil.traverseDAEEquationsStmts(stmts,function traversecountOperationsExp(shared=shared),inTpl); | |
| 2132 | 878 | then countOperationsInFunction(rest,shared,tpl); | |
| 2133 | case DAE.EQUATION(exp=exp1, scalar=exp2)::rest | ||
| 2134 | algorithm | ||
| 2135 | ✗ | (_,tpl) := traversecountOperationsExp(exp1,shared,inTpl); | |
| 2136 | ✗ | (_,tpl) := traversecountOperationsExp(exp2,shared,tpl); | |
| 2137 | ✗ | then countOperationsInFunction(rest,shared,tpl); | |
| 2138 | case DAE.COMPLEX_EQUATION(lhs=exp1, rhs=exp2)::rest | ||
| 2139 | algorithm | ||
| 2140 | ✗ | (_,tpl) := traversecountOperationsExp(exp1,shared,inTpl); | |
| 2141 | ✗ | (_,tpl) := traversecountOperationsExp(exp2,shared,tpl); | |
| 2142 | ✗ | then countOperationsInFunction(rest,shared,tpl); | |
| 2143 | case _::rest | ||
| 2144 | algorithm | ||
| 2145 | 8942 | then countOperationsInFunction(rest,shared,inTpl); | |
| 2146 | end matchcontinue; | ||
| 2147 | end countOperationsInFunction; | ||
| 2148 | |||
| 2149 | protected function countOperator | ||
| 2150 | input DAE.Operator op; | ||
| 2151 | input tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> inTpl; // add,mul,div,trig,relations,logical,other,funcCalls | ||
| 2152 | output tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> outTpl; | ||
| 2153 | algorithm | ||
| 2154 | outTpl := match(op, inTpl) | ||
| 2155 | local | ||
| 2156 | DAE.Type tp; | ||
| 2157 | Integer i,i1,i2,i3,i4,i5,i6,i7,i8; | ||
| 2158 | case (DAE.ADD(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2159 | 2225 | then (i1+1,i2,i3,i4,i5,i6,i7,i8); | |
| 2160 | case (DAE.SUB(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2161 | 2645 | then (i1+1,i2,i3,i4,i5,i6,i7,i8); | |
| 2162 | case (DAE.MUL(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2163 | 4629 | then (i1,i2+1,i3,i4,i5,i6,i7,i8); | |
| 2164 | case (DAE.DIV(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2165 | 1376 | then (i1,i2,i3+1,i4,i5,i6,i7,i8); | |
| 2166 | case (DAE.POW(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2167 | 532 | then (i1,i2,i3,i4,i5,i6,i7+1,i8); | |
| 2168 | case (DAE.UMINUS(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2169 | 771 | then (i1+1,i2,i3,i4,i5,i6,i7,i8); | |
| 2170 | case (DAE.UMINUS_ARR(ty=tp),(i1,i2,i3,i4,i5,i6,i7,i8)) algorithm | ||
| 2171 | ✗ | i := Expression.sizeOf(tp); | |
| 2172 | ✗ | then (i1+i,i2,i3,i4,i5,i6,i7,i8); | |
| 2173 | case (DAE.ADD_ARR(ty=tp),(i1,i2,i3,i4,i5,i6,i7,i8)) algorithm | ||
| 2174 | ✗ | i := Expression.sizeOf(tp); | |
| 2175 | ✗ | then (i1+i,i2,i3,i4,i5,i6,i7,i8); | |
| 2176 | case (DAE.SUB_ARR(ty=tp),(i1,i2,i3,i4,i5,i6,i7,i8)) algorithm | ||
| 2177 | ✗ | i := Expression.sizeOf(tp); | |
| 2178 | ✗ | then (i1+i,i2,i3,i4,i5,i6,i7,i8); | |
| 2179 | case (DAE.MUL_ARR(ty=tp),(i1,i2,i3,i4,i5,i6,i7,i8)) algorithm | ||
| 2180 | ✗ | i := Expression.sizeOf(tp); | |
| 2181 | ✗ | then (i1,i2+i,i3,i4,i5,i6,i7,i8); | |
| 2182 | case (DAE.DIV_ARR(ty=tp),(i1,i2,i3,i4,i5,i6,i7,i8)) algorithm | ||
| 2183 | ✗ | i := Expression.sizeOf(tp); | |
| 2184 | ✗ | then (i1,i2,i3+i,i4,i5,i6,i7,i8); | |
| 2185 | case (DAE.MUL_ARRAY_SCALAR(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2186 | ✗ | then (i1,i2+1,i3,i4,i5,i6,i7,i8); | |
| 2187 | case (DAE.ADD_ARRAY_SCALAR(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2188 | ✗ | then (i1+1,i2,i3,i4,i5,i6,i7,i8); | |
| 2189 | case (DAE.SUB_SCALAR_ARRAY(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2190 | ✗ | then (i1+1,i2,i3,i4,i5,i6,i7,i8); | |
| 2191 | case (DAE.MUL_SCALAR_PRODUCT(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2192 | ✗ | then (i1,i2+1,i3,i4,i5,i6,i7,i8); | |
| 2193 | case (DAE.MUL_MATRIX_PRODUCT(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2194 | ✗ | then (i1,i2+1,i3,i4,i5,i6,i7,i8); | |
| 2195 | case (DAE.DIV_ARRAY_SCALAR(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2196 | ✗ | then (i1,i2,i3+1,i4,i5,i6,i7,i8); | |
| 2197 | case (DAE.DIV_SCALAR_ARRAY(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2198 | ✗ | then (i1,i2,i3+1,i4,i5,i6,i7,i8); | |
| 2199 | case (DAE.POW_ARRAY_SCALAR(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2200 | ✗ | then (i1,i2,i3,i4,i5,i6,i7+1,i8); | |
| 2201 | case (DAE.POW_SCALAR_ARRAY(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2202 | ✗ | then (i1,i2,i3,i4,i5,i6,i7+1,i8); | |
| 2203 | case (DAE.POW_ARR(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2204 | ✗ | then (i1,i2,i3,i4,i5,i6,i7+1,i8); | |
| 2205 | case (DAE.POW_ARR2(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2206 | ✗ | then (i1,i2,i3,i4,i5,i6,i7+1,i8); | |
| 2207 | case (DAE.AND(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2208 | 166 | then (i1,i2,i3,i4,i5,i6+1,i7,i8); | |
| 2209 | case (DAE.OR(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2210 | 165 | then (i1,i2,i3,i4,i5,i6+1,i7,i8); | |
| 2211 | case (DAE.NOT(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2212 | 433 | then (i1,i2,i3,i4,i5,i6+1,i7,i8); | |
| 2213 | case (DAE.LESS(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2214 | 522 | then (i1,i2,i3,i4,i5+1,i6,i7,i8); | |
| 2215 | case (DAE.LESSEQ(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2216 | 229 | then (i1,i2,i3,i4,i5+1,i6,i7,i8); | |
| 2217 | case (DAE.GREATER(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2218 | 524 | then (i1,i2,i3,i4,i5+1,i6,i7,i8); | |
| 2219 | case (DAE.GREATEREQ(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2220 | 289 | then (i1,i2,i3,i4,i5+1,i6,i7,i8); | |
| 2221 | case (DAE.EQUAL(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2222 | 369 | then (i1,i2,i3,i4,i5+1,i6,i7,i8); | |
| 2223 | case (DAE.NEQUAL(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2224 | 2 | then (i1,i2,i3,i4,i5+1,i6,i7,i8); | |
| 2225 | case (DAE.USERDEFINED(),(i1,i2,i3,i4,i5,i6,i7,i8)) | ||
| 2226 | ✗ | then (i1,i2,i3,i4,i5,i6+1,i7,i8); | |
| 2227 | else | ||
| 2228 | algorithm | ||
| 2229 | ✗ | print("not supported operator\n"); | |
| 2230 | then inTpl; | ||
| 2231 | end match; | ||
| 2232 | end countOperator; | ||
| 2233 | |||
| 2234 | |||
| 2235 | // ============================================================================= | ||
| 2236 | // simplify if equations | ||
| 2237 | // | ||
| 2238 | // ============================================================================= | ||
| 2239 | |||
| 2240 | public function simplifyIfEquations "author: Frenkel TUD 2012-07 | ||
| 2241 | This function traveres all if equations and if expressions and tries to | ||
| 2242 | simplify it by using the information from evaluated parameters." | ||
| 2243 | input BackendDAE.BackendDAE dae; | ||
| 2244 | output BackendDAE.BackendDAE odae; | ||
| 2245 | algorithm | ||
| 2246 | 1075 | odae := BackendDAEUtil.mapEqSystem(dae, simplifyIfEquationsWork); | |
| 2247 | end simplifyIfEquations; | ||
| 2248 | |||
| 2249 | protected function simplifyIfEquationsWork "author: Frenkel TUD 2012-07 | ||
| 2250 | This function traveres all if equations and if expressions and tries to | ||
| 2251 | simplify it by using the information from evaluated parameters." | ||
| 2252 | input BackendDAE.EqSystem isyst; | ||
| 2253 | input BackendDAE.Shared ishared; | ||
| 2254 | output BackendDAE.EqSystem osyst; | ||
| 2255 | output BackendDAE.Shared oshared; | ||
| 2256 | algorithm | ||
| 2257 | (osyst,oshared) := matchcontinue (isyst, ishared) | ||
| 2258 | local | ||
| 2259 | BackendDAE.Variables globalKnownVars; | ||
| 2260 | BackendDAE.EquationArray eqns, initialEqs; | ||
| 2261 | list<BackendDAE.Equation> eqnslst, asserts, initial_asserts; | ||
| 2262 | BackendDAE.EqSystem syst; | ||
| 2263 | BackendDAE.Shared shared; | ||
| 2264 | Boolean systChanged; | ||
| 2265 | |||
| 2266 | case ( syst as BackendDAE.EQSYSTEM(orderedEqs=eqns), | ||
| 2267 | shared as BackendDAE.SHARED(globalKnownVars=globalKnownVars, initialEqs=initialEqs) ) | ||
| 2268 | algorithm | ||
| 2269 | // traverse the equations | ||
| 2270 | 1075 | eqnslst := BackendEquation.equationList(eqns); | |
| 2271 | // traverse equations in reverse order, than branch equations of if equaitions need no reverse | ||
| 2272 | 1075 | (eqnslst,asserts,systChanged) := List.fold31(listReverse(eqnslst), simplifyIfEquationsFinder, globalKnownVars, {},{},false); | |
| 2273 | 1075 | syst.orderedEqs := BackendEquation.listEquation(eqnslst); | |
| 2274 | |||
| 2275 | // traverse the initial equations | ||
| 2276 | 1075 | eqnslst := BackendEquation.equationList(initialEqs); | |
| 2277 | // traverse equations in reverse order, than branch equations of if equaitions need no reverse | ||
| 2278 |
4/4✓ Branch 0 taken 1028 times.
✓ Branch 1 taken 47 times.
✓ Branch 4 taken 1025 times.
✓ Branch 5 taken 50 times.
|
2103 | (eqnslst,initial_asserts,true) := List.fold31(listReverse(eqnslst), simplifyIfEquationsFinder, globalKnownVars, {},{},systChanged); |
| 2279 | |||
| 2280 | // ticket #5599 | ||
| 2281 | // leave initial asserts in the initial equation block | ||
| 2282 | // this just removes the surrounding unnecessary if condition | ||
| 2283 | 50 | shared.initialEqs := BackendEquation.listEquation(listAppend(initial_asserts, eqnslst)); | |
| 2284 | |||
| 2285 | 50 | syst := BackendDAEUtil.clearEqSyst(syst); | |
| 2286 | 50 | syst := BackendEquation.requationsAddDAE(asserts, syst); | |
| 2287 | then (syst, shared); | ||
| 2288 | |||
| 2289 | else | ||
| 2290 | then (isyst, ishared); | ||
| 2291 | end matchcontinue; | ||
| 2292 | end simplifyIfEquationsWork; | ||
| 2293 | |||
| 2294 | protected function simplifyIfEquationsFinder | ||
| 2295 | "author: Frenkel TUD 2012-07 | ||
| 2296 | helper for simplifyIfEquations" | ||
| 2297 | input BackendDAE.Equation inElem; | ||
| 2298 | input BackendDAE.Variables inConstArg; | ||
| 2299 | input output list<BackendDAE.Equation> acc; | ||
| 2300 | input output list<BackendDAE.Equation> asserts; | ||
| 2301 | input output Boolean b; | ||
| 2302 | algorithm | ||
| 2303 | (acc, asserts, b) := matchcontinue(inElem,inConstArg) | ||
| 2304 | local | ||
| 2305 | list<DAE.Exp> explst; | ||
| 2306 | list<BackendDAE.Equation> eqnslst,asserts1; | ||
| 2307 | list<list<BackendDAE.Equation>> eqnslstlst; | ||
| 2308 | DAE.ElementSource source; | ||
| 2309 | BackendDAE.Variables globalKnownVars; | ||
| 2310 | BackendDAE.Equation eqn; | ||
| 2311 | BackendDAE.EquationAttributes attr; | ||
| 2312 | |||
| 2313 | case (BackendDAE.IF_EQUATION(conditions=explst, eqnstrue=eqnslstlst, eqnsfalse=eqnslst, source=source, attr=attr), globalKnownVars) | ||
| 2314 | algorithm | ||
| 2315 | // check conditions | ||
| 2316 | 166 | (explst,_) := Expression.traverseExpList(explst, simplifyEvaluatedParamter, (globalKnownVars,false)); | |
| 2317 | 166 | explst := ExpressionSimplify.simplifyList(explst); | |
| 2318 | // simplify if equation | ||
| 2319 | 166 | (acc,asserts1) := simplifyIfEquation(explst,eqnslstlst,eqnslst,{},{},source,globalKnownVars,acc,attr); | |
| 2320 | 166 | asserts1 := listAppend(asserts,asserts1); | |
| 2321 | then | ||
| 2322 | (acc, asserts1, true); | ||
| 2323 | |||
| 2324 | case (eqn,globalKnownVars) | ||
| 2325 | algorithm | ||
| 2326 |
2/2✓ Branch 0 taken 150986 times.
✓ Branch 1 taken 10652 times.
|
312624 | (eqn,(_,b)) := BackendEquation.traverseExpsOfEquation(eqn, simplifyIfExpevaluatedParamter, (globalKnownVars,b)); |
| 2327 | 161638 | then | |
| 2328 | (eqn::acc,asserts,b); | ||
| 2329 | end matchcontinue; | ||
| 2330 | end simplifyIfEquationsFinder; | ||
| 2331 | |||
| 2332 | protected function simplifyIfExpevaluatedParamter | ||
| 2333 | input DAE.Exp inExp; | ||
| 2334 | input tuple<BackendDAE.Variables,Boolean> tpl1; | ||
| 2335 | output DAE.Exp outExp; | ||
| 2336 | output tuple<BackendDAE.Variables,Boolean> tpl2; | ||
| 2337 | algorithm | ||
| 2338 | (outExp,tpl2) := matchcontinue (inExp,tpl1) | ||
| 2339 | local | ||
| 2340 | BackendDAE.Variables globalKnownVars; | ||
| 2341 | DAE.Exp e1,e2,cond,expThen,expElse; | ||
| 2342 | Boolean b,b1; | ||
| 2343 | case (e1 as DAE.IFEXP(expCond=cond, expThen=expThen, expElse=expElse),(globalKnownVars,b)) | ||
| 2344 | algorithm | ||
| 2345 | 1688 | (cond,(_,b1)) := Expression.traverseExpBottomUp(cond, simplifyEvaluatedParamter, (globalKnownVars,false)); | |
| 2346 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1688 times.
|
1688 | e2 := if b1 then DAE.IFEXP(cond,expThen,expElse) else e1; |
| 2347 | 1688 | (e2,_) := ExpressionSimplify.condsimplify(b1,e2); | |
| 2348 |
2/2✓ Branch 0 taken 1524 times.
✓ Branch 1 taken 164 times.
|
3212 | then (e2,(globalKnownVars,b or b1)); |
| 2349 | else (inExp,tpl1); | ||
| 2350 | end matchcontinue; | ||
| 2351 | end simplifyIfExpevaluatedParamter; | ||
| 2352 | |||
| 2353 | protected function simplifyEvaluatedParamter | ||
| 2354 | input DAE.Exp inExp; | ||
| 2355 | input tuple<BackendDAE.Variables,Boolean> tpl1; | ||
| 2356 | output DAE.Exp outExp; | ||
| 2357 | output tuple<BackendDAE.Variables,Boolean> tpl2; | ||
| 2358 | algorithm | ||
| 2359 | (outExp,tpl2) := matchcontinue (inExp,tpl1) | ||
| 2360 | local | ||
| 2361 | BackendDAE.Variables globalKnownVars; | ||
| 2362 | DAE.ComponentRef cr; | ||
| 2363 | BackendDAE.Var v; | ||
| 2364 | DAE.Exp e; | ||
| 2365 | case (DAE.CREF(componentRef = cr),(globalKnownVars,_)) | ||
| 2366 | algorithm | ||
| 2367 | 4057 | (v,_) := BackendVariable.getVarSingle(cr,globalKnownVars); | |
| 2368 |
3/10✓ Branch 1 taken 466 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 466 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 466 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
|
466 | true := BackendVariable.hasVarEvaluateAnnotationTrue(v) |
| 2369 | or (Flags.getConfigBool(Flags.EVALUATE_FINAL_PARAMS) and BackendVariable.isFinalVar(v)) | ||
| 2370 | or (Flags.getConfigBool(Flags.EVALUATE_PROTECTED_PARAMS) and BackendVariable.isProtectedVar(v)); | ||
| 2371 | ✗ | e := BackendVariable.varBindExpStartValue(v); | |
| 2372 | ✗ | then (e,(globalKnownVars,true)); | |
| 2373 | else (inExp,tpl1); | ||
| 2374 | end matchcontinue; | ||
| 2375 | end simplifyEvaluatedParamter; | ||
| 2376 | |||
| 2377 | protected function simplifyIfEquation | ||
| 2378 | "author: Frenkel TUD 2012-07 | ||
| 2379 | helper for simplifyIfEquations" | ||
| 2380 | input list<DAE.Exp> conditions; | ||
| 2381 | input list<list<BackendDAE.Equation>> theneqns; | ||
| 2382 | input list<BackendDAE.Equation> elseenqs; | ||
| 2383 | input list<DAE.Exp> conditions1; | ||
| 2384 | input list<list<BackendDAE.Equation>> theneqns1; | ||
| 2385 | input DAE.ElementSource source; | ||
| 2386 | input BackendDAE.Variables globalKnownVars; | ||
| 2387 | input list<BackendDAE.Equation> inEqns; | ||
| 2388 | input BackendDAE.EquationAttributes inEqAttr; | ||
| 2389 | output list<BackendDAE.Equation> outEqns; | ||
| 2390 | output list<BackendDAE.Equation> outAsserts; | ||
| 2391 | algorithm | ||
| 2392 | (outEqns,outAsserts) := match(conditions, theneqns, conditions1, theneqns1) | ||
| 2393 | local | ||
| 2394 | DAE.Exp e; | ||
| 2395 | list<DAE.Exp> explst; | ||
| 2396 | list<list<BackendDAE.Equation>> eqnslst; | ||
| 2397 | list<BackendDAE.Equation> eqns,elseenqs1,asserts; | ||
| 2398 | |||
| 2399 | // no true case left with condition<>false | ||
| 2400 | case ({}, {}, {}, {}) | ||
| 2401 | algorithm | ||
| 2402 | // simplify nested if equations | ||
| 2403 | ✗ | (eqns,asserts,_) := List.fold31(listReverse(elseenqs), simplifyIfEquationsFinder, globalKnownVars, {},{},false); | |
| 2404 | ✗ | then | |
| 2405 | (listAppend(eqns,inEqns),asserts); | ||
| 2406 | // true case left with condition<>false | ||
| 2407 | case ({}, {}, _, _) | ||
| 2408 | algorithm | ||
| 2409 | 166 | explst := listReverse(conditions1); | |
| 2410 | 166 | eqnslst := listReverse(theneqns1); | |
| 2411 | // simplify nested if equations | ||
| 2412 | 166 | (elseenqs1,asserts,_) := List.fold31(listReverse(elseenqs), simplifyIfEquationsFinder, globalKnownVars, {},{},false); | |
| 2413 | 166 | elseenqs1 := listAppend(elseenqs1,asserts) annotation(__OpenModelica_DisableListAppendWarning=true); | |
| 2414 | 166 | (eqnslst,elseenqs1,asserts) := simplifyIfEquationAsserts(explst,eqnslst,elseenqs1,{},{},{}); | |
| 2415 | 166 | eqns := simplifyIfEquation1(explst,eqnslst,elseenqs1,source,globalKnownVars,inEqns,inEqAttr); | |
| 2416 | 166 | then | |
| 2417 | (eqns,asserts); | ||
| 2418 | // if true and first use it | ||
| 2419 | case(DAE.BCONST(true)::_, eqns::_, {}, _) | ||
| 2420 | algorithm | ||
| 2421 | // simplify nested if equations | ||
| 2422 | ✗ | (eqns,asserts,_) := List.fold31(listReverse(eqns), simplifyIfEquationsFinder, globalKnownVars, {},{},false); | |
| 2423 | ✗ | then | |
| 2424 | (listAppend(eqns,inEqns),asserts); | ||
| 2425 | // if true and not first use it as new else | ||
| 2426 | case(DAE.BCONST(true)::_, eqns::_, _, _) | ||
| 2427 | algorithm | ||
| 2428 | ✗ | explst := listReverse(conditions1); | |
| 2429 | ✗ | eqnslst := listReverse(theneqns1); | |
| 2430 | // simplify nested if equations | ||
| 2431 | ✗ | (elseenqs1,asserts,_) := List.fold31(listReverse(eqns), simplifyIfEquationsFinder, globalKnownVars, {},{},false); | |
| 2432 | ✗ | elseenqs1 := listAppend(elseenqs1,asserts) annotation(__OpenModelica_DisableListAppendWarning=true); | |
| 2433 | ✗ | (eqnslst,elseenqs1,asserts) := simplifyIfEquationAsserts(explst,eqnslst,elseenqs1,{},{},{}); | |
| 2434 | ✗ | eqns := simplifyIfEquation1(explst,eqnslst,elseenqs1,source,globalKnownVars,inEqns,inEqAttr); | |
| 2435 | ✗ | then | |
| 2436 | (eqns,asserts); | ||
| 2437 | // if false skip it | ||
| 2438 | case(DAE.BCONST(false)::explst, _::eqnslst, _, _) | ||
| 2439 | algorithm | ||
| 2440 | 441 | (eqns,asserts) := simplifyIfEquation(explst,eqnslst,elseenqs,conditions1,theneqns1,source,globalKnownVars,inEqns,inEqAttr); | |
| 2441 | then | ||
| 2442 | (eqns,asserts); | ||
| 2443 | // all other cases | ||
| 2444 | case(e::explst, eqns::eqnslst, _, _) | ||
| 2445 | algorithm | ||
| 2446 | // simplify nested if equations | ||
| 2447 | 441 | (eqns,asserts,_) := List.fold31(listReverse(eqns), simplifyIfEquationsFinder, globalKnownVars, {},{},false); | |
| 2448 | 441 | eqns := listAppend(eqns,asserts) annotation(__OpenModelica_DisableListAppendWarning=true); | |
| 2449 | 441 | (eqns,asserts) := simplifyIfEquation(explst,eqnslst,elseenqs,e::conditions1,eqns::theneqns1,source,globalKnownVars,inEqns,inEqAttr); | |
| 2450 | then | ||
| 2451 | (eqns,asserts); | ||
| 2452 | end match; | ||
| 2453 | end simplifyIfEquation; | ||
| 2454 | |||
| 2455 | protected function simplifyIfEquation1 | ||
| 2456 | "author: Frenkel TUD 2012-07 | ||
| 2457 | helper for simplifyIfEquations" | ||
| 2458 | input list<DAE.Exp> conditions; | ||
| 2459 | input list<list<BackendDAE.Equation>> theneqns; | ||
| 2460 | input list<BackendDAE.Equation> elseenqs; | ||
| 2461 | input DAE.ElementSource source; | ||
| 2462 | input BackendDAE.Variables globalKnownVars; | ||
| 2463 | input list<BackendDAE.Equation> inEqns; | ||
| 2464 | input BackendDAE.EquationAttributes inEqAttr; | ||
| 2465 | output list<BackendDAE.Equation> outEqns; | ||
| 2466 | algorithm | ||
| 2467 | outEqns := matchcontinue inEqAttr | ||
| 2468 | local | ||
| 2469 | list<DAE.Exp> fbsExp; | ||
| 2470 | list<list<DAE.Exp>> tbsExp; | ||
| 2471 | list<BackendDAE.Equation> eqns; | ||
| 2472 | HashTable2.HashTable ht; | ||
| 2473 | list<tuple<DAE.ComponentRef,DAE.Exp>> crexplst; | ||
| 2474 | |||
| 2475 | // true case left with condition<>false | ||
| 2476 | case _ | ||
| 2477 | algorithm | ||
| 2478 | 166 | countEquationsInBranches(theneqns,elseenqs,source); | |
| 2479 | // simplify if eqution | ||
| 2480 | // if .. then a=.. elseif .. then a=... else a=.. end if; | ||
| 2481 | // to | ||
| 2482 | // a=if .. then .. else if .. then else ..; | ||
| 2483 | 166 | ht := HashTable2.emptyHashTable(); | |
| 2484 | 166 | ht := simplifySolvedIfEqnsElse(elseenqs,ht); | |
| 2485 | 157 | ht := simplifySolvedIfEqns(listReverse(conditions),listReverse(theneqns),ht); | |
| 2486 | 127 | crexplst := BaseHashTable.hashTableList(ht); | |
| 2487 | 127 | eqns := simplifySolvedIfEqns2(crexplst, inEqns, inEqAttr); | |
| 2488 | // ToDo: check if the same cref is not used more than once on the lhs, merge sources | ||
| 2489 | then | ||
| 2490 | eqns; | ||
| 2491 | case _ | ||
| 2492 | algorithm | ||
| 2493 | 39 | countEquationsInBranches(theneqns,elseenqs,source); | |
| 2494 | 39 | fbsExp := makeEquationLstToResidualExpLst(elseenqs); | |
| 2495 | 39 | tbsExp := List.map(theneqns, makeEquationLstToResidualExpLst); | |
| 2496 | 39 | eqns := makeEquationsFromResiduals(conditions, tbsExp, fbsExp, source, inEqAttr); | |
| 2497 | 39 | then | |
| 2498 | listAppend(eqns,inEqns); | ||
| 2499 | |||
| 2500 | ✗ | else BackendDAE.IF_EQUATION(conditions,theneqns,elseenqs,source,inEqAttr)::inEqns; | |
| 2501 | end matchcontinue; | ||
| 2502 | end simplifyIfEquation1; | ||
| 2503 | |||
| 2504 | protected function simplifySolvedIfEqns2 | ||
| 2505 | input list<tuple<DAE.ComponentRef,DAE.Exp>> crexplst; | ||
| 2506 | input list<BackendDAE.Equation> inEqns; | ||
| 2507 | input BackendDAE.EquationAttributes inEqAttr; | ||
| 2508 | output list<BackendDAE.Equation> outEqns; | ||
| 2509 | algorithm | ||
| 2510 | outEqns := match crexplst | ||
| 2511 | local | ||
| 2512 | DAE.ComponentRef cr; | ||
| 2513 | DAE.Exp e,crexp; | ||
| 2514 | list<tuple<DAE.ComponentRef,DAE.Exp>> rest; | ||
| 2515 | |||
| 2516 | case {} | ||
| 2517 | then inEqns; | ||
| 2518 | |||
| 2519 | case (cr,e)::rest | ||
| 2520 | algorithm | ||
| 2521 | 379 | crexp := Expression.crefExp(cr); | |
| 2522 | 758 | then | |
| 2523 | simplifySolvedIfEqns2(rest, BackendDAE.EQUATION(crexp, e, DAE.emptyElementSource, inEqAttr)::inEqns, inEqAttr); | ||
| 2524 | end match; | ||
| 2525 | end simplifySolvedIfEqns2; | ||
| 2526 | |||
| 2527 | protected function simplifySolvedIfEqns | ||
| 2528 | "author: Frenkel TUD 2012-10 | ||
| 2529 | helper for simplifyIfEquations" | ||
| 2530 | input list<DAE.Exp> conditions; | ||
| 2531 | input list<list<BackendDAE.Equation>> theneqns; | ||
| 2532 | input HashTable2.HashTable iHt; | ||
| 2533 | output HashTable2.HashTable oHt; | ||
| 2534 | algorithm | ||
| 2535 | oHt := match(conditions, theneqns) | ||
| 2536 | local | ||
| 2537 | HashTable2.HashTable ht; | ||
| 2538 | DAE.Exp c; | ||
| 2539 | list<DAE.Exp> explst; | ||
| 2540 | list<BackendDAE.Equation> eqns; | ||
| 2541 | list<list<BackendDAE.Equation>> rest; | ||
| 2542 | case ({}, {}) | ||
| 2543 | then | ||
| 2544 | iHt; | ||
| 2545 | case (c::explst, eqns::rest) | ||
| 2546 | algorithm | ||
| 2547 | 416 | ht := simplifySolvedIfEqns1(c,eqns,iHt, HashSet.emptyHashSet()); | |
| 2548 | 386 | then | |
| 2549 | simplifySolvedIfEqns(explst,rest,ht); | ||
| 2550 | end match; | ||
| 2551 | end simplifySolvedIfEqns; | ||
| 2552 | |||
| 2553 | protected function simplifySolvedIfEqns1 | ||
| 2554 | "author: Frenkel TUD 2012-10 | ||
| 2555 | helper for simplifyIfEquations" | ||
| 2556 | input DAE.Exp condition; | ||
| 2557 | input list<BackendDAE.Equation> brancheqns; | ||
| 2558 | input HashTable2.HashTable iHt; | ||
| 2559 | input HashSet.HashSet iHs; | ||
| 2560 | output HashTable2.HashTable oHt; | ||
| 2561 | algorithm | ||
| 2562 | // ticket #13927 | ||
| 2563 | // Only proceed if `cr` was not already assigned within current branch. | ||
| 2564 | // This is checked by collecting all `cr` in `hs`. | ||
| 2565 | // Prevents errors like: | ||
| 2566 | // if b then a = r1; a = r2; else a = r3; c = r4; end if; | ||
| 2567 | // to | ||
| 2568 | // a = if b then r2 else if b then r1 else r3; c = r4; | ||
| 2569 | |||
| 2570 | oHt := match brancheqns | ||
| 2571 | local | ||
| 2572 | DAE.ComponentRef cr; | ||
| 2573 | DAE.Exp e,exp; | ||
| 2574 | HashTable2.HashTable ht; | ||
| 2575 | HashSet.HashSet hs; | ||
| 2576 | list<BackendDAE.Equation> rest; | ||
| 2577 | case {} | ||
| 2578 | then | ||
| 2579 | iHt; | ||
| 2580 | case BackendDAE.EQUATION(exp=DAE.CREF(componentRef=cr), scalar=e)::rest | ||
| 2581 | algorithm | ||
| 2582 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1285 times.
|
1285 | false := Expression.expHasCref(e, cr); |
| 2583 | 1285 | hs := BaseHashSet.addUnique(cr, iHs); | |
| 2584 | 1285 | exp := BaseHashTable.get(cr, iHt); | |
| 2585 | 1259 | exp := DAE.IFEXP(condition, e, exp); | |
| 2586 | 1259 | ht := BaseHashTable.add((cr,exp), iHt); | |
| 2587 | 1259 | then | |
| 2588 | simplifySolvedIfEqns1(condition,rest,ht, hs); | ||
| 2589 | case BackendDAE.EQUATION(exp=DAE.UNARY(operator=DAE.UMINUS(), exp=DAE.CREF(componentRef=cr)), scalar=e)::rest | ||
| 2590 | algorithm | ||
| 2591 | ✗ | false := Expression.expHasCref(e, cr); | |
| 2592 | ✗ | hs := BaseHashSet.addUnique(cr, iHs); | |
| 2593 | ✗ | exp := BaseHashTable.get(cr, iHt); | |
| 2594 | ✗ | e := Expression.negate(e); | |
| 2595 | ✗ | exp := DAE.IFEXP(condition, e, exp); | |
| 2596 | ✗ | ht := BaseHashTable.add((cr,exp), iHt); | |
| 2597 | ✗ | then | |
| 2598 | simplifySolvedIfEqns1(condition,rest,ht, hs); | ||
| 2599 | end match; | ||
| 2600 | end simplifySolvedIfEqns1; | ||
| 2601 | |||
| 2602 | protected function simplifySolvedIfEqnsElse | ||
| 2603 | "author: Frenkel TUD 2012-10 | ||
| 2604 | helper for simplifyIfEquations" | ||
| 2605 | input list<BackendDAE.Equation> elseenqs; | ||
| 2606 | input HashTable2.HashTable iHt; | ||
| 2607 | output HashTable2.HashTable oHt; | ||
| 2608 | algorithm | ||
| 2609 | oHt := match elseenqs | ||
| 2610 | local | ||
| 2611 | DAE.ComponentRef cr; | ||
| 2612 | DAE.Exp e; | ||
| 2613 | HashTable2.HashTable ht; | ||
| 2614 | list<BackendDAE.Equation> rest; | ||
| 2615 | case {} | ||
| 2616 | then | ||
| 2617 | iHt; | ||
| 2618 | case BackendDAE.EQUATION(exp=DAE.CREF(componentRef=cr), scalar=e)::rest guard not BaseHashTable.hasKey(cr, iHt) | ||
| 2619 | algorithm | ||
| 2620 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 426 times.
|
426 | false := Expression.expHasCref(e, cr); |
| 2621 | 426 | ht := BaseHashTable.add((cr,e), iHt); | |
| 2622 | 426 | then | |
| 2623 | simplifySolvedIfEqnsElse(rest,ht); | ||
| 2624 | case BackendDAE.EQUATION(exp=DAE.UNARY(operator=DAE.UMINUS(), exp=DAE.CREF(componentRef=cr)), scalar=e)::rest guard not BaseHashTable.hasKey(cr, iHt) | ||
| 2625 | algorithm | ||
| 2626 | ✗ | false := Expression.expHasCref(e, cr); | |
| 2627 | ✗ | e := Expression.negate(e); | |
| 2628 | ✗ | ht := BaseHashTable.add((cr,e), iHt); | |
| 2629 | ✗ | then | |
| 2630 | simplifySolvedIfEqnsElse(rest,ht); | ||
| 2631 | end match; | ||
| 2632 | end simplifySolvedIfEqnsElse; | ||
| 2633 | |||
| 2634 | protected function simplifyIfEquationAsserts | ||
| 2635 | "author: Frenkel TUD 2012-07 | ||
| 2636 | helper for simplifyIfEquations" | ||
| 2637 | input list<DAE.Exp> conditions; | ||
| 2638 | input list<list<BackendDAE.Equation>> theneqns; | ||
| 2639 | input list<BackendDAE.Equation> elseenqs; | ||
| 2640 | input list<DAE.Exp> conditions1; | ||
| 2641 | input list<list<BackendDAE.Equation>> theneqns1; | ||
| 2642 | input list<BackendDAE.Equation> inEqns; | ||
| 2643 | output list<list<BackendDAE.Equation>> otheneqns; | ||
| 2644 | output list<BackendDAE.Equation> oelseenqs; | ||
| 2645 | output list<BackendDAE.Equation> outEqns; | ||
| 2646 | algorithm | ||
| 2647 | (otheneqns,oelseenqs,outEqns) := match(conditions, theneqns) | ||
| 2648 | local | ||
| 2649 | DAE.Exp e; | ||
| 2650 | list<DAE.Exp> explst; | ||
| 2651 | list<BackendDAE.Equation> eqns,eqns1,beqns; | ||
| 2652 | list<list<BackendDAE.Equation>> eqnslst,eqnslst1; | ||
| 2653 | |||
| 2654 | case (_, {}) | ||
| 2655 | algorithm | ||
| 2656 | 166 | (beqns,eqns) := simplifyIfEquationAsserts1(elseenqs,NONE(),conditions1,{},inEqns); | |
| 2657 |
1/2✓ Branch 1 taken 166 times.
✗ Branch 2 not taken.
|
166 | then |
| 2658 | (listReverse(theneqns1),beqns,eqns); | ||
| 2659 | case (e::explst, eqns::eqnslst) | ||
| 2660 | algorithm | ||
| 2661 | 441 | (beqns,eqns) := simplifyIfEquationAsserts1(eqns,SOME(e),conditions1,{},inEqns); | |
| 2662 | 441 | (eqnslst1,eqns1,eqns) := simplifyIfEquationAsserts(explst,eqnslst,elseenqs,e::conditions1,beqns::theneqns1,eqns); | |
| 2663 | then | ||
| 2664 | (eqnslst1,eqns1,eqns); | ||
| 2665 | end match; | ||
| 2666 | end simplifyIfEquationAsserts; | ||
| 2667 | |||
| 2668 | protected function simplifyIfEquationAsserts1 | ||
| 2669 | "author: Frenkel TUD 2012-07 | ||
| 2670 | helper for simplifyIfEquationAsserts" | ||
| 2671 | input list<BackendDAE.Equation> brancheqns; | ||
| 2672 | input Option<DAE.Exp> condition; | ||
| 2673 | input list<DAE.Exp> conditions "reversed"; | ||
| 2674 | input list<BackendDAE.Equation> brancheqns1; | ||
| 2675 | input list<BackendDAE.Equation> inEqns; | ||
| 2676 | output list<BackendDAE.Equation> obrancheqns; | ||
| 2677 | output list<BackendDAE.Equation> outEqns; | ||
| 2678 | algorithm | ||
| 2679 | (obrancheqns,outEqns) := match(brancheqns, condition) | ||
| 2680 | local | ||
| 2681 | DAE.Exp e,cond,msg,level; | ||
| 2682 | BackendDAE.Equation eqn; | ||
| 2683 | list<BackendDAE.Equation> eqns,beqns; | ||
| 2684 | Integer size; | ||
| 2685 | DAE.ElementSource source,source1; | ||
| 2686 | DAE.Expand crefExpand; | ||
| 2687 | BackendDAE.EquationAttributes eqAttr; | ||
| 2688 | |||
| 2689 | case ({}, _) | ||
| 2690 | 607 | then | |
| 2691 | (listReverse(brancheqns1),inEqns); | ||
| 2692 | |||
| 2693 | case (BackendDAE.ALGORITHM(size=size,alg=DAE.ALGORITHM_STMTS({DAE.STMT_ASSERT(cond=cond,msg=msg,level=level,source=source1)}),source=source,expand=crefExpand,attr=eqAttr)::eqns, NONE()) | ||
| 2694 | algorithm | ||
| 2695 | ✗ | e := List.fold(conditions,makeIfExp,cond); | |
| 2696 | ✗ | (beqns,eqns) := simplifyIfEquationAsserts1(eqns,condition,conditions,brancheqns1,BackendDAE.ALGORITHM(size,DAE.ALGORITHM_STMTS({DAE.STMT_ASSERT(e,msg,level,source1)}),source,crefExpand,eqAttr)::inEqns); | |
| 2697 | then | ||
| 2698 | (beqns,eqns); | ||
| 2699 | |||
| 2700 | case (BackendDAE.ALGORITHM(size=size,alg=DAE.ALGORITHM_STMTS({DAE.STMT_ASSERT(cond=cond,msg=msg,level=level,source=source1)}),source=source,expand=crefExpand,attr=eqAttr)::eqns, SOME(e)) | ||
| 2701 | algorithm | ||
| 2702 | 2 | e := DAE.IFEXP(e,cond,DAE.BCONST(true)); | |
| 2703 | 2 | e := List.fold(conditions,makeIfExp,e); | |
| 2704 | 6 | (beqns,eqns) := simplifyIfEquationAsserts1(eqns,condition,conditions,brancheqns1,BackendDAE.ALGORITHM(size,DAE.ALGORITHM_STMTS({DAE.STMT_ASSERT(e,msg,level,source1)}),source,crefExpand,eqAttr)::inEqns); | |
| 2705 | then | ||
| 2706 | (beqns,eqns); | ||
| 2707 | |||
| 2708 | case (BackendDAE.ALGORITHM(size=size,alg=DAE.ALGORITHM_STMTS({DAE.STMT_TERMINATE(msg=msg,source=source1)}),source=source,expand=crefExpand,attr=eqAttr)::eqns, NONE()) | ||
| 2709 | algorithm | ||
| 2710 | ✗ | e := List.fold(conditions,makeIfExp,DAE.BCONST(true)); | |
| 2711 | ✗ | (beqns,eqns) := simplifyIfEquationAsserts1(eqns,condition,conditions,brancheqns1,BackendDAE.ALGORITHM(size,DAE.ALGORITHM_STMTS({DAE.STMT_IF(e,{DAE.STMT_TERMINATE(msg,source1)},DAE.NOELSE(),source1)}),source,crefExpand,eqAttr)::inEqns); | |
| 2712 | then | ||
| 2713 | (beqns,eqns); | ||
| 2714 | |||
| 2715 | case (BackendDAE.ALGORITHM(size=size,alg=DAE.ALGORITHM_STMTS({DAE.STMT_TERMINATE(msg=msg,source=source1)}),source=source,expand=crefExpand,attr=eqAttr)::eqns, SOME(e)) | ||
| 2716 | algorithm | ||
| 2717 | 1 | e := List.fold(conditions,makeIfExp,e); | |
| 2718 | 4 | (beqns,eqns) := simplifyIfEquationAsserts1(eqns,condition,conditions,brancheqns1,BackendDAE.ALGORITHM(size,DAE.ALGORITHM_STMTS({DAE.STMT_IF(e,{DAE.STMT_TERMINATE(msg,source1)},DAE.NOELSE(),source1)}),source,crefExpand,eqAttr)::inEqns); | |
| 2719 | then | ||
| 2720 | (beqns,eqns); | ||
| 2721 | |||
| 2722 | case (eqn::eqns, _) | ||
| 2723 | algorithm | ||
| 2724 | 1770 | (beqns,eqns) := simplifyIfEquationAsserts1(eqns,condition,conditions,eqn::brancheqns1,inEqns); | |
| 2725 | then | ||
| 2726 | (beqns,eqns); | ||
| 2727 | end match; | ||
| 2728 | end simplifyIfEquationAsserts1; | ||
| 2729 | |||
| 2730 | protected function makeIfExp | ||
| 2731 | input DAE.Exp cond; | ||
| 2732 | input DAE.Exp else_; | ||
| 2733 | output DAE.Exp oExp; | ||
| 2734 | algorithm | ||
| 2735 | ✗ | oExp := DAE.IFEXP(cond,DAE.BCONST(true),else_); | |
| 2736 | end makeIfExp; | ||
| 2737 | |||
| 2738 | protected function countEquationsInBranches " | ||
| 2739 | Checks that the number of equations is the same in all branches | ||
| 2740 | of an if-equation" | ||
| 2741 | input list<list<BackendDAE.Equation>> trueBranches; | ||
| 2742 | input list<BackendDAE.Equation> falseBranch; | ||
| 2743 | input DAE.ElementSource source; | ||
| 2744 | output Integer nrOfEquations; | ||
| 2745 | algorithm | ||
| 2746 | nrOfEquations := matchcontinue falseBranch | ||
| 2747 | local | ||
| 2748 | list<Boolean> b; | ||
| 2749 | list<String> strs; | ||
| 2750 | String str,eqstr; | ||
| 2751 | list<Integer> nrOfEquationsBranches; | ||
| 2752 | |||
| 2753 | case _ | ||
| 2754 | algorithm | ||
| 2755 | 205 | nrOfEquations := BackendEquation.equationLstSize(falseBranch); | |
| 2756 | 205 | nrOfEquationsBranches := List.map(trueBranches, BackendEquation.equationLstSize); | |
| 2757 | 205 | b := List.map1(nrOfEquationsBranches, intEq, nrOfEquations); | |
| 2758 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 205 times.
|
205 | true := List.reduce(b,boolAnd); |
| 2759 | then | ||
| 2760 | nrOfEquations; | ||
| 2761 | |||
| 2762 | // An if-equation with non-parameter conditions must have an else-clause. | ||
| 2763 | case {} | ||
| 2764 | algorithm | ||
| 2765 | ✗ | Error.addSourceMessage(Error.IF_EQUATION_MISSING_ELSE, {}, | |
| 2766 | ElementSource.getElementSourceFileInfo(source)); | ||
| 2767 | ✗ | then | |
| 2768 | fail(); | ||
| 2769 | |||
| 2770 | // If if-equation with non-parameter conditions must have the same number of | ||
| 2771 | // equations in each branch. | ||
| 2772 | case _ :: _ | ||
| 2773 | algorithm | ||
| 2774 | ✗ | nrOfEquations := BackendEquation.equationLstSize(falseBranch); | |
| 2775 | ✗ | nrOfEquationsBranches := List.map(trueBranches, BackendEquation.equationLstSize); | |
| 2776 | ✗ | eqstr := stringDelimitList(List.map(listAppend(trueBranches,{falseBranch}),BackendDump.dumpEqnsStr),"\n"); | |
| 2777 | ✗ | strs := List.map(nrOfEquationsBranches, intString); | |
| 2778 | ✗ | str := stringDelimitList(strs,","); | |
| 2779 | ✗ | str := "{" + str + "," + intString(nrOfEquations) + "}"; | |
| 2780 | ✗ | Error.addSourceMessage(Error.IF_EQUATION_UNBALANCED_2,{str,eqstr},ElementSource.getElementSourceFileInfo(source)); | |
| 2781 | ✗ | then | |
| 2782 | fail(); | ||
| 2783 | |||
| 2784 | end matchcontinue; | ||
| 2785 | end countEquationsInBranches; | ||
| 2786 | |||
| 2787 | protected function makeEquationLstToResidualExpLst | ||
| 2788 | input list<BackendDAE.Equation> eqLst; | ||
| 2789 | output list<DAE.Exp> oExpLst; | ||
| 2790 | algorithm | ||
| 2791 | oExpLst := matchcontinue eqLst | ||
| 2792 | local | ||
| 2793 | list<BackendDAE.Equation> rest; | ||
| 2794 | list<DAE.Exp> exps1,exps2,exps; | ||
| 2795 | BackendDAE.Equation eq; | ||
| 2796 | DAE.ElementSource source; | ||
| 2797 | String str; | ||
| 2798 | case {} then {}; | ||
| 2799 | case (eq as BackendDAE.ALGORITHM(source = source))::rest | ||
| 2800 | algorithm | ||
| 2801 | ✗ | str := BackendDump.equationString(eq); | |
| 2802 | ✗ | str := Util.stringReplaceChar(str,"\n",""); | |
| 2803 | ✗ | Error.addSourceMessage(Error.IF_EQUATION_WARNING,{str},ElementSource.getElementSourceFileInfo(source)); | |
| 2804 | ✗ | exps := makeEquationLstToResidualExpLst(rest); | |
| 2805 | then exps; | ||
| 2806 | case eq::rest | ||
| 2807 | algorithm | ||
| 2808 | 148 | exps1 := makeEquationToResidualExpLst(eq); | |
| 2809 | 148 | exps2 := makeEquationLstToResidualExpLst(rest); | |
| 2810 | 148 | exps := listAppend(exps1,exps2); | |
| 2811 | then | ||
| 2812 | exps; | ||
| 2813 | end matchcontinue; | ||
| 2814 | end makeEquationLstToResidualExpLst; | ||
| 2815 | |||
| 2816 | protected function makeEquationToResidualExpLst " | ||
| 2817 | If-equations with more than 1 equation in each branch cannot be transformed | ||
| 2818 | to a single equation with residual if-expression. This function translates such | ||
| 2819 | equations to a list of residual if-expressions. Normal equations are translated | ||
| 2820 | to a list with a single residual expression." | ||
| 2821 | input BackendDAE.Equation eq; | ||
| 2822 | output list<DAE.Exp> oExpLst; | ||
| 2823 | algorithm | ||
| 2824 | oExpLst := matchcontinue eq | ||
| 2825 | local | ||
| 2826 | list<list<BackendDAE.Equation>> tbs; | ||
| 2827 | list<BackendDAE.Equation> fbs; | ||
| 2828 | list<DAE.Exp> conds, fbsExp,exps; | ||
| 2829 | list<list<DAE.Exp>> tbsExp; | ||
| 2830 | BackendDAE.Equation elt; | ||
| 2831 | DAE.Exp exp; | ||
| 2832 | |||
| 2833 | case BackendDAE.IF_EQUATION(conditions=conds,eqnstrue=tbs,eqnsfalse=fbs) | ||
| 2834 | algorithm | ||
| 2835 | ✗ | fbsExp := makeEquationLstToResidualExpLst(fbs); | |
| 2836 | ✗ | tbsExp := List.map(tbs, makeEquationLstToResidualExpLst); | |
| 2837 | ✗ | exps := makeResidualIfExpLst(conds,tbsExp,fbsExp); | |
| 2838 | then | ||
| 2839 | exps; | ||
| 2840 | case elt | ||
| 2841 | algorithm | ||
| 2842 | 148 | exp:=makeEquationToResidualExp(elt); | |
| 2843 | then | ||
| 2844 | {exp}; | ||
| 2845 | end matchcontinue; | ||
| 2846 | end makeEquationToResidualExpLst; | ||
| 2847 | |||
| 2848 | protected function makeResidualIfExpLst | ||
| 2849 | input list<DAE.Exp> inExp1; | ||
| 2850 | input list<list<DAE.Exp>> inExpLst2; | ||
| 2851 | input list<DAE.Exp> inExpLst3; | ||
| 2852 | output list<DAE.Exp> outExpLst; | ||
| 2853 | algorithm | ||
| 2854 | outExpLst := match (inExp1,inExpLst2,inExpLst3) | ||
| 2855 | local | ||
| 2856 | list<list<DAE.Exp>> tbs,tbsRest; | ||
| 2857 | list<DAE.Exp> tbsFirst,fbs,rest_res; | ||
| 2858 | list<DAE.Exp> conds; | ||
| 2859 | DAE.Exp ifexp,fb; | ||
| 2860 | |||
| 2861 | case (_,tbs,{}) | ||
| 2862 | algorithm | ||
| 2863 | ✗ | true := List.all(tbs, listEmpty); | |
| 2864 | then {}; | ||
| 2865 | |||
| 2866 | case (conds,tbs,fb::fbs) | ||
| 2867 | algorithm | ||
| 2868 | ✗ | tbsRest := List.map(tbs, listRest); | |
| 2869 | ✗ | rest_res := makeResidualIfExpLst(conds, tbsRest, fbs); | |
| 2870 | |||
| 2871 | ✗ | tbsFirst := List.map(tbs,listHead); | |
| 2872 | |||
| 2873 | ✗ | ifexp := Expression.makeNestedIf(conds,tbsFirst,fb); | |
| 2874 | then | ||
| 2875 | (ifexp :: rest_res); | ||
| 2876 | end match; | ||
| 2877 | end makeResidualIfExpLst; | ||
| 2878 | |||
| 2879 | public function makeEquationToResidualExp "" | ||
| 2880 | input BackendDAE.Equation eq; | ||
| 2881 | output DAE.Exp oExp; | ||
| 2882 | algorithm | ||
| 2883 | oExp := matchcontinue eq | ||
| 2884 | local | ||
| 2885 | DAE.Exp e1,e2, e; | ||
| 2886 | list<DAE.Exp> expl, expl1; | ||
| 2887 | DAE.ComponentRef cr1; | ||
| 2888 | String str; | ||
| 2889 | DAE.Type ty; | ||
| 2890 | Integer idx; | ||
| 2891 | list<Integer> idxs; | ||
| 2892 | // normal equation | ||
| 2893 | case BackendDAE.EQUATION(exp=e1,scalar=e2) | ||
| 2894 | algorithm | ||
| 2895 | 167 | ty := Expression.typeof(e1); | |
| 2896 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 167 times.
|
167 | true := Types.isIntegerOrRealOrSubTypeOfEither(ty); |
| 2897 | 167 | oExp := Expression.expSub(e1,e2); | |
| 2898 | then | ||
| 2899 | oExp; | ||
| 2900 | // equation from array TODO! check if this works! | ||
| 2901 | case BackendDAE.ARRAY_EQUATION(left=e1,right=e2) | ||
| 2902 | algorithm | ||
| 2903 | ✗ | oExp := Expression.expSub(e1,e2); | |
| 2904 | then | ||
| 2905 | oExp; | ||
| 2906 | // solved equation | ||
| 2907 | case BackendDAE.SOLVED_EQUATION(componentRef=cr1, exp=e2) | ||
| 2908 | algorithm | ||
| 2909 | ✗ | e1 := Expression.crefExp(cr1); | |
| 2910 | ✗ | oExp := Expression.expSub(e1,e2); | |
| 2911 | then | ||
| 2912 | oExp; | ||
| 2913 | // residual equation | ||
| 2914 | case BackendDAE.RESIDUAL_EQUATION(exp = oExp) | ||
| 2915 | then | ||
| 2916 | oExp; | ||
| 2917 | // complex equation | ||
| 2918 | // (x,_) = f(.) | ||
| 2919 | case BackendDAE.COMPLEX_EQUATION(left = DAE.TUPLE(expl), right = e2) | ||
| 2920 | algorithm | ||
| 2921 | expl1 := {}; | ||
| 2922 | idxs := {}; | ||
| 2923 | idx := 1; | ||
| 2924 | ✗ | for elem in expl loop | |
| 2925 | ✗ | if Expression.isNotWild(elem) then | |
| 2926 | idxs := idx :: idxs; | ||
| 2927 | expl1 := elem :: expl1; | ||
| 2928 | end if; | ||
| 2929 | ✗ | idx := idx + 1; | |
| 2930 | end for; | ||
| 2931 | ✗ | {e} := expl1; | |
| 2932 | ✗ | {idx} := idxs; | |
| 2933 | ✗ | oExp := Expression.expSub(e, DAE.TSUB(e2,idx,Expression.typeof(e))); | |
| 2934 | //print("\n" + ExpressionDump.dumpExpStr(oExp,0)); | ||
| 2935 | then oExp; | ||
| 2936 | case BackendDAE.COMPLEX_EQUATION(left = e1, right = e2) | ||
| 2937 | algorithm | ||
| 2938 | ✗ | oExp := Expression.expSub(e1,e2); | |
| 2939 | then | ||
| 2940 | oExp; | ||
| 2941 | // failure | ||
| 2942 | case _ | ||
| 2943 | algorithm | ||
| 2944 | ✗ | str := "- BackendDAEOptimize.makeEquationToResidualExp failed to transform equation: " + BackendDump.equationString(eq) + " to residual form!"; | |
| 2945 | ✗ | Error.addMessage(Error.INTERNAL_ERROR, {str}); | |
| 2946 | ✗ | then fail(); | |
| 2947 | end matchcontinue; | ||
| 2948 | end makeEquationToResidualExp; | ||
| 2949 | |||
| 2950 | protected function makeEquationsFromResiduals | ||
| 2951 | input list<DAE.Exp> inExp1 "conds"; | ||
| 2952 | input list<list<DAE.Exp>> inExpLst2 "tbs"; | ||
| 2953 | input list<DAE.Exp> inExpLst3; | ||
| 2954 | input DAE.ElementSource inSource "the origin of the element"; | ||
| 2955 | input BackendDAE.EquationAttributes inEqAttr; | ||
| 2956 | output list<BackendDAE.Equation> outExpLst; | ||
| 2957 | algorithm | ||
| 2958 | outExpLst := match inExpLst3 | ||
| 2959 | local | ||
| 2960 | list<list<DAE.Exp>> tbsRest; | ||
| 2961 | list<DAE.Exp> tbsFirst, fbs; | ||
| 2962 | DAE.Exp ifexp, fb; | ||
| 2963 | BackendDAE.Equation eq; | ||
| 2964 | list<BackendDAE.Equation> rest_res; | ||
| 2965 | DAE.Exp zeroExp; | ||
| 2966 | Integer size; | ||
| 2967 | |||
| 2968 | case {} | ||
| 2969 | algorithm | ||
| 2970 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
|
39 | true := List.all(inExpLst2, listEmpty); |
| 2971 | then {}; | ||
| 2972 | |||
| 2973 | case fb::fbs | ||
| 2974 | algorithm | ||
| 2975 | 58 | size := Expression.sizeOf(Expression.typeof(fb)); | |
| 2976 | 58 | tbsRest := List.map(inExpLst2, listRest); | |
| 2977 | 58 | rest_res := makeEquationsFromResiduals(inExp1, tbsRest, fbs, inSource, inEqAttr); | |
| 2978 | 58 | tbsFirst := List.map(inExpLst2, listHead); | |
| 2979 | 58 | ifexp := Expression.makeNestedIf(inExp1,tbsFirst,fb); | |
| 2980 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | if size==1 then |
| 2981 | 58 | eq := BackendDAE.EQUATION(DAE.RCONST(0.0), ifexp, inSource, inEqAttr); | |
| 2982 | else | ||
| 2983 | ✗ | zeroExp := Expression.createZeroExpression(Expression.typeof(fb)); | |
| 2984 | ✗ | eq := BackendDAE.COMPLEX_EQUATION(size, zeroExp, ifexp, inSource, inEqAttr); | |
| 2985 | end if; | ||
| 2986 | |||
| 2987 | then (eq::rest_res); | ||
| 2988 | end match; | ||
| 2989 | end makeEquationsFromResiduals; | ||
| 2990 | |||
| 2991 | |||
| 2992 | // ============================================================================= | ||
| 2993 | // simplify semiLinear calls | ||
| 2994 | // | ||
| 2995 | // ============================================================================= | ||
| 2996 | |||
| 2997 | public function simplifysemiLinear "author: Frenkel TUD 2012-08 | ||
| 2998 | This function traveres all equations and tries to simplify calls to semiLinear" | ||
| 2999 | input BackendDAE.BackendDAE dae; | ||
| 3000 | output BackendDAE.BackendDAE odae; | ||
| 3001 | algorithm | ||
| 3002 | 1070 | odae := BackendDAEUtil.mapEqSystem(dae,simplifysemiLinearWork); | |
| 3003 | end simplifysemiLinear; | ||
| 3004 | |||
| 3005 | protected function simplifysemiLinearWork "author: Frenkel TUD 2012-08 | ||
| 3006 | This function traveres all equations and tries to simplify calls to semiLinear" | ||
| 3007 | input BackendDAE.EqSystem isyst; | ||
| 3008 | input BackendDAE.Shared ishared; | ||
| 3009 | output BackendDAE.EqSystem osyst; | ||
| 3010 | output BackendDAE.Shared oshared; | ||
| 3011 | algorithm | ||
| 3012 | (osyst,oshared) := matchcontinue isyst | ||
| 3013 | local | ||
| 3014 | BackendDAE.EquationArray eqns; | ||
| 3015 | list<tuple<BackendDAE.Equation,Integer>> eqnslst; | ||
| 3016 | BackendDAE.EqSystem syst; | ||
| 3017 | array<list<tuple<BackendDAE.Equation,Integer>>> eqnsarray; | ||
| 3018 | BackendDAE.EqSystem syst; | ||
| 3019 | |||
| 3020 | case syst as BackendDAE.EQSYSTEM(orderedEqs=eqns) | ||
| 3021 | algorithm | ||
| 3022 | // traverse the equations and collect all semiLinear calls y=semiLinear(x,sa,sb) | ||
| 3023 |
2/2✓ Branch 1 taken 1543 times.
✓ Branch 2 taken 19 times.
|
1562 | (eqns, (eqnslst,_,true)) := BackendEquation.traverseEquationArray_WithUpdate(eqns,simplifysemiLinearFinder,({},0,false)); |
| 3024 | // sort for (y,x) pairs | ||
| 3025 | 19 | eqnsarray := semiLinearSort(eqnslst, HashTableExpToIndex.emptyHashTable(), 1, arrayCreate(5, {})); | |
| 3026 | 19 | eqnsarray := semiLinearSort1(arrayList(eqnsarray), 1, arrayCreate(5, {})); | |
| 3027 | // optimize | ||
| 3028 | // y = semiLinear(x,sa,s1) | ||
| 3029 | // y = semiLinear(x,s1,s2) | ||
| 3030 | // y = semiLinear(x,s2,s3) | ||
| 3031 | // ... | ||
| 3032 | // y = semiLinear(x,sn,sb) | ||
| 3033 | // -> | ||
| 3034 | // s1 = if (x>=0) then sa else sb | ||
| 3035 | // s2 = s1 | ||
| 3036 | // s3 = s2 | ||
| 3037 | // .. | ||
| 3038 | // sn = sn-1 | ||
| 3039 | // y = semiLinear(x,sa,sb) | ||
| 3040 | 19 | eqnslst := Array.fold(eqnsarray, semiLinearOptimize, {}); | |
| 3041 | // replace the equations in the system | ||
| 3042 | 19 | syst.orderedEqs := List.fold(eqnslst, semiLinearReplaceEqns, eqns); | |
| 3043 | 19 | then (BackendDAEUtil.clearEqSyst(syst), ishared); | |
| 3044 | |||
| 3045 | else | ||
| 3046 | then (isyst,ishared); | ||
| 3047 | end matchcontinue; | ||
| 3048 | end simplifysemiLinearWork; | ||
| 3049 | |||
| 3050 | protected function semiLinearReplaceEqns "author: Frenkel TUD 2012-08 | ||
| 3051 | helper for simplifysemiLinear" | ||
| 3052 | input tuple<BackendDAE.Equation, Integer /*zero-based*/> iTpl; | ||
| 3053 | input BackendDAE.EquationArray iEqns; | ||
| 3054 | output BackendDAE.EquationArray oEqns; | ||
| 3055 | protected | ||
| 3056 | BackendDAE.Equation eqn; | ||
| 3057 | Integer index; | ||
| 3058 | algorithm | ||
| 3059 | 39 | (eqn, index) := iTpl; | |
| 3060 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
|
39 | if Flags.isSet(Flags.SEMILINEAR) then |
| 3061 | ✗ | BackendDump.debugStrEqnStr("Replace with ", eqn, "\n"); | |
| 3062 | end if; | ||
| 3063 | 39 | oEqns := BackendEquation.setAtIndex(iEqns, index+1, eqn); | |
| 3064 | end semiLinearReplaceEqns; | ||
| 3065 | |||
| 3066 | protected function semiLinearOptimize | ||
| 3067 | "author: Frenkel TUD 2012-08 | ||
| 3068 | helper for simplifysemiLinear" | ||
| 3069 | input list<tuple<BackendDAE.Equation,Integer>> eqnslst; | ||
| 3070 | input list<tuple<BackendDAE.Equation,Integer>> iAcc; | ||
| 3071 | output list<tuple<BackendDAE.Equation,Integer>> oAcc; | ||
| 3072 | algorithm | ||
| 3073 | oAcc := matchcontinue eqnslst | ||
| 3074 | local | ||
| 3075 | HashTableExpToIndex.HashTable ht,ht1; | ||
| 3076 | array<tuple<BackendDAE.Equation,Integer>> eqnsarray; | ||
| 3077 | list<DAE.Exp> explst; | ||
| 3078 | case _::{} then iAcc; | ||
| 3079 | case _ | ||
| 3080 | algorithm | ||
| 3081 | // get HashMab sa-> index | ||
| 3082 | 62 | ht := HashTableExpToIndex.emptyHashTable(); | |
| 3083 | 62 | ht1 := HashTableExpToIndex.emptyHashTable(); | |
| 3084 | 62 | (ht,ht1) := semiLinearOptimize1(eqnslst,1,ht,ht1); | |
| 3085 | // get sa | ||
| 3086 | 62 | explst := List.fold1(BaseHashTable.hashTableKeyList(ht),semiLinearGetSA,ht1,{}); | |
| 3087 | 62 | eqnsarray := listArray(eqnslst); | |
| 3088 | // optimize | ||
| 3089 | 62 | then | |
| 3090 | semiLinearOptimize2(explst,ht,eqnsarray,iAcc); | ||
| 3091 | case _ then iAcc; | ||
| 3092 | end matchcontinue; | ||
| 3093 | end semiLinearOptimize; | ||
| 3094 | |||
| 3095 | protected function semiLinearOptimize2 | ||
| 3096 | "author: Frenkel TUD 2012-08 | ||
| 3097 | helper for simplifysemiLinear" | ||
| 3098 | input list<DAE.Exp> saLst; | ||
| 3099 | input HashTableExpToIndex.HashTable iHt; | ||
| 3100 | input array<tuple<BackendDAE.Equation,Integer>> IEqnsarray; | ||
| 3101 | input list<tuple<BackendDAE.Equation,Integer>> iAcc; | ||
| 3102 | output list<tuple<BackendDAE.Equation,Integer>> oAcc; | ||
| 3103 | algorithm | ||
| 3104 | oAcc := matchcontinue saLst | ||
| 3105 | local | ||
| 3106 | DAE.Exp sa,sb,s1,y,x; | ||
| 3107 | list<DAE.Exp> rest; | ||
| 3108 | list<tuple<DAE.Exp,Integer,DAE.ElementSource>> explst; | ||
| 3109 | list<tuple<BackendDAE.Equation,Integer>> acc; | ||
| 3110 | BackendDAE.Equation eqn,eqn1; | ||
| 3111 | Integer i1,index,index1; | ||
| 3112 | Absyn.Path path; | ||
| 3113 | DAE.CallAttributes attr; | ||
| 3114 | DAE.ElementSource source,source1; | ||
| 3115 | BackendDAE.EquationAttributes eqAttr; | ||
| 3116 | case {} then iAcc; | ||
| 3117 | case sa::rest | ||
| 3118 | algorithm | ||
| 3119 | 15 | i1 := BaseHashTable.get(sa,iHt); | |
| 3120 |
6/12✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 15 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 15 times.
|
15 | (BackendDAE.EQUATION(exp=y,scalar=DAE.CALL(path=path,expLst = {x,_,s1},attr=attr),source=source,attr=eqAttr),index) := IEqnsarray[i1]; |
| 3121 | // get Order of s1,s2,s3,..,sn,sb | ||
| 3122 | 15 | (sb,source1,index1,explst) := semiLinearOptimize3(s1,source,index,iHt,IEqnsarray,{}); | |
| 3123 | // generate optimized equations | ||
| 3124 | // s1 = if (x>=0) then sa else sb | ||
| 3125 | // s2 = s1 | ||
| 3126 | // .. | ||
| 3127 | // sn = sn-1 | ||
| 3128 | // y = semiLinear(x,sa,sb) | ||
| 3129 | 30 | eqn := BackendDAE.EQUATION(s1,DAE.IFEXP(DAE.CALL(Absyn.IDENT("noEvent"),{DAE.RELATION(x,DAE.GREATEREQ(DAE.T_REAL_DEFAULT),DAE.RCONST(0.0),-1,NONE())},DAE.callAttrBuiltinBool),sa,sb),source,eqAttr); | |
| 3130 | 15 | eqn1 := BackendDAE.EQUATION(y,DAE.CALL(path,{x,sa,sb},attr),source1,eqAttr); | |
| 3131 | 30 | acc := semiLinearOptimize4(explst,(eqn1,index1)::iAcc, eqAttr); | |
| 3132 | 30 | then | |
| 3133 | semiLinearOptimize2(rest,iHt,IEqnsarray,(eqn,index)::acc); | ||
| 3134 | case _::rest | ||
| 3135 | ✗ | then | |
| 3136 | semiLinearOptimize2(rest,iHt,IEqnsarray,iAcc); | ||
| 3137 | end matchcontinue; | ||
| 3138 | end semiLinearOptimize2; | ||
| 3139 | |||
| 3140 | protected function semiLinearOptimize4 | ||
| 3141 | "author: Frenkel TUD 2012-08 | ||
| 3142 | helper for simplifysemiLinear" | ||
| 3143 | input list<tuple<DAE.Exp,Integer,DAE.ElementSource>> explst; | ||
| 3144 | input list<tuple<BackendDAE.Equation,Integer>> iAcc; | ||
| 3145 | input BackendDAE.EquationAttributes inEqAttr; | ||
| 3146 | output list<tuple<BackendDAE.Equation,Integer>> oAcc; | ||
| 3147 | algorithm | ||
| 3148 | oAcc := match explst | ||
| 3149 | local | ||
| 3150 | DAE.Exp s1,s2; | ||
| 3151 | list<tuple<DAE.Exp,Integer,DAE.ElementSource>> rest; | ||
| 3152 | Integer index; | ||
| 3153 | BackendDAE.Equation eqn; | ||
| 3154 | DAE.ElementSource source; | ||
| 3155 | case {} then iAcc; | ||
| 3156 | case _::{} then iAcc; | ||
| 3157 | case (s2,index,source)::(rest as ((s1,_,_)::_)) | ||
| 3158 | algorithm | ||
| 3159 | 9 | eqn := BackendDAE.EQUATION(s2, s1, source, inEqAttr); | |
| 3160 | 18 | then | |
| 3161 | semiLinearOptimize4(rest, (eqn, index)::iAcc, inEqAttr); | ||
| 3162 | end match; | ||
| 3163 | end semiLinearOptimize4; | ||
| 3164 | |||
| 3165 | protected function semiLinearOptimize3 | ||
| 3166 | "author: Frenkel TUD 2012-08 | ||
| 3167 | helper for simplifysemiLinear" | ||
| 3168 | input DAE.Exp exp; | ||
| 3169 | input DAE.ElementSource isource; | ||
| 3170 | input Integer iIndex; | ||
| 3171 | input HashTableExpToIndex.HashTable iHt; | ||
| 3172 | input array<tuple<BackendDAE.Equation,Integer>> IEqnsarray; | ||
| 3173 | input list<tuple<DAE.Exp,Integer,DAE.ElementSource>> iAcc; | ||
| 3174 | output DAE.Exp slast; | ||
| 3175 | output DAE.ElementSource osource; | ||
| 3176 | output Integer oIndex; | ||
| 3177 | output list<tuple<DAE.Exp,Integer,DAE.ElementSource>> oAcc; | ||
| 3178 | algorithm | ||
| 3179 | (slast,osource,oIndex,oAcc) := matchcontinue iAcc | ||
| 3180 | local | ||
| 3181 | DAE.Exp sb; | ||
| 3182 | Integer i,index; | ||
| 3183 | DAE.ElementSource source; | ||
| 3184 | case _ | ||
| 3185 | algorithm | ||
| 3186 | 39 | i := BaseHashTable.get(exp,iHt); | |
| 3187 |
6/12✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 24 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 24 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 24 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 24 times.
|
24 | (BackendDAE.EQUATION(scalar=DAE.CALL(expLst = {_,_,sb}),source=source),index) := IEqnsarray[i]; |
| 3188 | 48 | (sb,source,index,oAcc) := semiLinearOptimize3(sb,source,index,iHt,IEqnsarray,(exp,iIndex,source)::iAcc); | |
| 3189 | then | ||
| 3190 | (sb,source,index,oAcc); | ||
| 3191 | case _ | ||
| 3192 | 15 | then | |
| 3193 | (exp,isource,iIndex,iAcc); | ||
| 3194 | end matchcontinue; | ||
| 3195 | end semiLinearOptimize3; | ||
| 3196 | |||
| 3197 | protected function semiLinearGetSA | ||
| 3198 | "author: Frenkel TUD 2012-08 | ||
| 3199 | helper for simplifysemiLinear" | ||
| 3200 | input DAE.Exp key; | ||
| 3201 | input HashTableExpToIndex.HashTable iHt1; | ||
| 3202 | input list<DAE.Exp> iAcc; | ||
| 3203 | output list<DAE.Exp> oAcc; | ||
| 3204 | algorithm | ||
| 3205 |
2/2✓ Branch 1 taken 15 times.
✓ Branch 2 taken 24 times.
|
39 | oAcc := if BaseHashTable.hasKey(key, iHt1) then iAcc else key::iAcc; |
| 3206 | end semiLinearGetSA; | ||
| 3207 | |||
| 3208 | protected function semiLinearOptimize1 | ||
| 3209 | "author: Frenkel TUD 2012-08 | ||
| 3210 | helper for simplifysemiLinear" | ||
| 3211 | input list<tuple<BackendDAE.Equation,Integer>> eqnslst; | ||
| 3212 | input Integer i; | ||
| 3213 | input HashTableExpToIndex.HashTable iHt; | ||
| 3214 | input HashTableExpToIndex.HashTable iHt1; | ||
| 3215 | output HashTableExpToIndex.HashTable oHt; | ||
| 3216 | output HashTableExpToIndex.HashTable oHt1; | ||
| 3217 | algorithm | ||
| 3218 | (oHt,oHt1) := match eqnslst | ||
| 3219 | local | ||
| 3220 | list<tuple<BackendDAE.Equation,Integer>> rest; | ||
| 3221 | HashTableExpToIndex.HashTable ht,ht1; | ||
| 3222 | DAE.Exp sa,sb; | ||
| 3223 | case {} then (iHt,iHt1); | ||
| 3224 | case (BackendDAE.EQUATION(scalar=DAE.CALL(expLst = {_,sa,sb})),_)::rest | ||
| 3225 | algorithm | ||
| 3226 | 39 | ht := BaseHashTable.add((sa,i), iHt); | |
| 3227 | 39 | ht1 := BaseHashTable.add((sb,i), iHt1); | |
| 3228 | 39 | (ht,ht1) := semiLinearOptimize1(rest,i+1,ht,ht1); | |
| 3229 | then | ||
| 3230 | (ht,ht1); | ||
| 3231 | end match; | ||
| 3232 | end semiLinearOptimize1; | ||
| 3233 | |||
| 3234 | protected function semiLinearSort "author: Frenkel TUD 2012-08 | ||
| 3235 | helper for simplifysemiLinear" | ||
| 3236 | input list<tuple<BackendDAE.Equation,Integer>> eqnslst; | ||
| 3237 | input HashTableExpToIndex.HashTable iHt; | ||
| 3238 | input Integer size; | ||
| 3239 | input array<list<tuple<BackendDAE.Equation,Integer>>> iEqnsarray; | ||
| 3240 | output array<list<tuple<BackendDAE.Equation,Integer>>> oEqnsarray; | ||
| 3241 | algorithm | ||
| 3242 | oEqnsarray := matchcontinue eqnslst | ||
| 3243 | local | ||
| 3244 | BackendDAE.Equation eqn; | ||
| 3245 | Integer index,i; | ||
| 3246 | list<tuple<BackendDAE.Equation,Integer>> rest,eqns; | ||
| 3247 | HashTableExpToIndex.HashTable ht; | ||
| 3248 | DAE.Exp y; | ||
| 3249 | array<list<tuple<BackendDAE.Equation,Integer>>> eqnsarray; | ||
| 3250 | case {} then iEqnsarray; | ||
| 3251 | case (eqn as BackendDAE.EQUATION(exp=y),index)::rest | ||
| 3252 | algorithm | ||
| 3253 | 367 | i := BaseHashTable.get(y,iHt); | |
| 3254 | 24 | eqns := iEqnsarray[i]; | |
| 3255 | 48 | eqnsarray := arrayUpdate(iEqnsarray,i,(eqn,index)::eqns); | |
| 3256 | 24 | then | |
| 3257 | semiLinearSort(rest,iHt,size,eqnsarray); | ||
| 3258 | case (eqn as BackendDAE.EQUATION(exp=y),index)::rest | ||
| 3259 | algorithm | ||
| 3260 | 343 | ht := BaseHashTable.add((y,size), iHt); | |
| 3261 | // expand if necesarray | ||
| 3262 |
2/2✓ Branch 0 taken 59 times.
✓ Branch 1 taken 284 times.
|
343 | eqnsarray := if intGt(size,arrayLength(iEqnsarray)) then Array.expand(5, iEqnsarray, {}) else iEqnsarray; |
| 3263 | 686 | eqnsarray := arrayUpdate(eqnsarray,size,{(eqn,index)}); | |
| 3264 | 343 | then | |
| 3265 | semiLinearSort(rest,ht,size+1,eqnsarray); | ||
| 3266 | end matchcontinue; | ||
| 3267 | end semiLinearSort; | ||
| 3268 | |||
| 3269 | protected function semiLinearSort1 | ||
| 3270 | "author: Frenkel TUD 2012-08 | ||
| 3271 | helper for simplifysemiLinear" | ||
| 3272 | input list<list<tuple<BackendDAE.Equation,Integer>>> eqnslstlst; | ||
| 3273 | input Integer size; | ||
| 3274 | input array<list<tuple<BackendDAE.Equation,Integer>>> iEqnsarray; | ||
| 3275 | output array<list<tuple<BackendDAE.Equation,Integer>>> oEqnsarray; | ||
| 3276 | algorithm | ||
| 3277 | oEqnsarray := match eqnslstlst | ||
| 3278 | local | ||
| 3279 | Integer size1; | ||
| 3280 | tuple<BackendDAE.Equation,Integer> tpl; | ||
| 3281 | list<tuple<BackendDAE.Equation,Integer>> eqns; | ||
| 3282 | list<list<tuple<BackendDAE.Equation,Integer>>> rest; | ||
| 3283 | HashTableExpToIndex.HashTable ht; | ||
| 3284 | array<list<tuple<BackendDAE.Equation,Integer>>> eqnsarray; | ||
| 3285 | case {} then iEqnsarray; | ||
| 3286 | case (tpl::{})::rest | ||
| 3287 | algorithm | ||
| 3288 | // expand if necesarray | ||
| 3289 |
2/2✓ Branch 0 taken 59 times.
✓ Branch 1 taken 269 times.
|
328 | eqnsarray := if intGt(size,arrayLength(iEqnsarray)) then Array.expand(5, iEqnsarray, {}) else iEqnsarray; |
| 3290 | 328 | eqnsarray := arrayUpdate(eqnsarray,size,{tpl}); | |
| 3291 | 328 | then | |
| 3292 | semiLinearSort1(rest,size+1,eqnsarray); | ||
| 3293 | case eqns::rest | ||
| 3294 | algorithm | ||
| 3295 | 62 | ht := HashTableExpToIndex.emptyHashTable(); | |
| 3296 | 62 | (size1,eqnsarray) := semiLinearSort2(eqns,ht,size,iEqnsarray); | |
| 3297 | 62 | then | |
| 3298 | semiLinearSort1(rest,size1,eqnsarray); | ||
| 3299 | end match; | ||
| 3300 | end semiLinearSort1; | ||
| 3301 | |||
| 3302 | protected function semiLinearSort2 | ||
| 3303 | "author: Frenkel TUD 2012-08 | ||
| 3304 | helper for simplifysemiLinear" | ||
| 3305 | input list<tuple<BackendDAE.Equation,Integer>> eqnslst; | ||
| 3306 | input HashTableExpToIndex.HashTable iHt; | ||
| 3307 | input Integer size; | ||
| 3308 | input array<list<tuple<BackendDAE.Equation,Integer>>> iEqnsarray; | ||
| 3309 | output Integer osize; | ||
| 3310 | output array<list<tuple<BackendDAE.Equation,Integer>>> oEqnsarray; | ||
| 3311 | algorithm | ||
| 3312 | (osize,oEqnsarray) := matchcontinue eqnslst | ||
| 3313 | local | ||
| 3314 | BackendDAE.Equation eqn; | ||
| 3315 | Integer index,i; | ||
| 3316 | list<tuple<BackendDAE.Equation,Integer>> rest,eqns; | ||
| 3317 | HashTableExpToIndex.HashTable ht; | ||
| 3318 | DAE.Exp x; | ||
| 3319 | array<list<tuple<BackendDAE.Equation,Integer>>> eqnsarray; | ||
| 3320 | 62 | case {} then (size,iEqnsarray); | |
| 3321 | case (eqn as BackendDAE.EQUATION(scalar=DAE.CALL(expLst = x::_)),index)::rest | ||
| 3322 | algorithm | ||
| 3323 | 39 | i := BaseHashTable.get(x,iHt); | |
| 3324 | 24 | eqns := iEqnsarray[i]; | |
| 3325 | 48 | eqnsarray := arrayUpdate(iEqnsarray,i,(eqn,index)::eqns); | |
| 3326 | 24 | (i,eqnsarray) := semiLinearSort2(rest,iHt,size,eqnsarray); | |
| 3327 | then | ||
| 3328 | (i,eqnsarray); | ||
| 3329 | case (eqn as BackendDAE.EQUATION(scalar=DAE.CALL(expLst = x::_)),index)::rest | ||
| 3330 | algorithm | ||
| 3331 | 15 | ht := BaseHashTable.add((x,size), iHt); | |
| 3332 | // expand if necesarray | ||
| 3333 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
|
15 | eqnsarray := if intGt(size,arrayLength(iEqnsarray)) then Array.expand(5, iEqnsarray, {}) else iEqnsarray; |
| 3334 | 30 | eqnsarray := arrayUpdate(eqnsarray,size,{(eqn,index)}); | |
| 3335 | 15 | (i,eqnsarray) := semiLinearSort2(rest,ht,size+1,eqnsarray); | |
| 3336 | then | ||
| 3337 | (i,eqnsarray); | ||
| 3338 | end matchcontinue; | ||
| 3339 | end semiLinearSort2; | ||
| 3340 | |||
| 3341 | protected function simplifysemiLinearFinder | ||
| 3342 | "helper for simplifysemiLinear" | ||
| 3343 | input BackendDAE.Equation inEq; | ||
| 3344 | input tuple<list<tuple<BackendDAE.Equation,Integer>>,Integer,Boolean> inTpl; | ||
| 3345 | output BackendDAE.Equation outEq; | ||
| 3346 | output tuple<list<tuple<BackendDAE.Equation,Integer>>,Integer,Boolean> outTpl; | ||
| 3347 | algorithm | ||
| 3348 | (outEq,outTpl) := matchcontinue (inEq,inTpl) | ||
| 3349 | local | ||
| 3350 | BackendDAE.Equation eqn; | ||
| 3351 | list<tuple<BackendDAE.Equation,Integer>> eqnslst; | ||
| 3352 | Integer index; | ||
| 3353 | Boolean b; | ||
| 3354 | DAE.Exp x,y,sa,sb; | ||
| 3355 | DAE.ElementSource source; | ||
| 3356 | Absyn.Path path; | ||
| 3357 | DAE.CallAttributes attr; | ||
| 3358 | BackendDAE.EquationAttributes eqAttr; | ||
| 3359 | |||
| 3360 | // 0 = semiLinear(0,sa,sb) -> sa=sb | ||
| 3361 | case (BackendDAE.EQUATION(exp=y,scalar=DAE.CALL(path=Absyn.IDENT("semiLinear"),expLst={x,sa,sb}),source=source,attr=eqAttr),(eqnslst,index,_)) | ||
| 3362 | algorithm | ||
| 3363 |
1/2✓ Branch 1 taken 367 times.
✗ Branch 2 not taken.
|
367 | true := Expression.isZero(y); |
| 3364 | ✗ | true := Expression.isZero(x); | |
| 3365 | ✗ | then (BackendDAE.EQUATION(sa,sb,source,eqAttr),(eqnslst,index+1,true)); | |
| 3366 | case (BackendDAE.EQUATION(exp=DAE.CALL(path=Absyn.IDENT("semiLinear"),expLst={x,sa,sb}),scalar=y,source=source,attr=eqAttr),(eqnslst,index,_)) | ||
| 3367 | algorithm | ||
| 3368 | ✗ | true := Expression.isZero(y); | |
| 3369 | ✗ | true := Expression.isZero(x); | |
| 3370 | ✗ | then (BackendDAE.EQUATION(sa,sb,source,eqAttr),(eqnslst,index+1,true)); | |
| 3371 | case (BackendDAE.EQUATION(exp=y,scalar=DAE.UNARY(exp=DAE.CALL(path=Absyn.IDENT("semiLinear"),expLst={x,sa,sb})),source=source,attr=eqAttr),(eqnslst,index,_)) | ||
| 3372 | algorithm | ||
| 3373 | ✗ | true := Expression.isZero(y); | |
| 3374 | ✗ | true := Expression.isZero(x); | |
| 3375 | ✗ | then (BackendDAE.EQUATION(sa,sb,source,eqAttr),(eqnslst,index+1,true)); | |
| 3376 | case (BackendDAE.EQUATION(exp=DAE.UNARY(exp=DAE.CALL(path=Absyn.IDENT("semiLinear"),expLst={x,sa,sb})),scalar=y,source=source,attr=eqAttr),(eqnslst,index,_)) | ||
| 3377 | algorithm | ||
| 3378 | ✗ | true := Expression.isZero(y); | |
| 3379 | ✗ | true := Expression.isZero(x); | |
| 3380 | ✗ | then (BackendDAE.EQUATION(sa,sb,source,eqAttr),(eqnslst,index+1,true)); | |
| 3381 | // y = -semiLinear(-x,sb,sa) -> y = semiLinear(x,sa,sb) | ||
| 3382 | case (BackendDAE.EQUATION(exp=y,scalar=DAE.UNARY(exp=DAE.CALL(path=path as Absyn.IDENT("semiLinear"),expLst={DAE.UNARY(exp=x),sb,sa},attr=attr)),source=source,attr=eqAttr),(eqnslst,index,_)) | ||
| 3383 | algorithm | ||
| 3384 | ✗ | eqn := BackendDAE.EQUATION(y,DAE.CALL(path,{x,sa,sb},attr),source,eqAttr); | |
| 3385 | ✗ | if Flags.isSet(Flags.SEMILINEAR) then | |
| 3386 | ✗ | BackendDump.debugStrEqnStr("Found semiLinear ",eqn,"\n"); | |
| 3387 | end if; | ||
| 3388 | ✗ | then (eqn,((eqn,index)::eqnslst,index+1,true)); | |
| 3389 | case (BackendDAE.EQUATION(exp=DAE.UNARY(exp=DAE.CALL(path=path as Absyn.IDENT("semiLinear"),expLst={DAE.UNARY(exp=x),sb,sa},attr=attr)),scalar=y,source=source,attr=eqAttr),(eqnslst,index,_)) | ||
| 3390 | algorithm | ||
| 3391 | ✗ | eqn := BackendDAE.EQUATION(y,DAE.CALL(path,{x,sa,sb},attr),source,eqAttr); | |
| 3392 | ✗ | if Flags.isSet(Flags.SEMILINEAR) then | |
| 3393 | ✗ | BackendDump.debugStrEqnStr("Found semiLinear ",eqn,"\n"); | |
| 3394 | end if; | ||
| 3395 | ✗ | then (eqn,((eqn,index)::eqnslst,index+1,true)); | |
| 3396 | // -y = semiLinear(-x,sb,sa) -> y = semiLinear(x,sa,sb) | ||
| 3397 | case (BackendDAE.EQUATION(exp=DAE.UNARY(exp=y),scalar=DAE.CALL(path = path as Absyn.IDENT("semiLinear"), expLst = {DAE.UNARY(exp=x),sb,sa},attr=attr),source=source,attr=eqAttr),(eqnslst,index,_)) | ||
| 3398 | algorithm | ||
| 3399 | 14 | eqn := BackendDAE.EQUATION(y,DAE.CALL(path,{x,sa,sb},attr),source,eqAttr); | |
| 3400 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
|
14 | if Flags.isSet(Flags.SEMILINEAR) then |
| 3401 | ✗ | BackendDump.debugStrEqnStr("Found semiLinear ",eqn,"\n"); | |
| 3402 | end if; | ||
| 3403 | 28 | then (eqn,((eqn,index)::eqnslst,index+1,true)); | |
| 3404 | case (BackendDAE.EQUATION(exp=DAE.CALL(path = path as Absyn.IDENT("semiLinear"), expLst = {DAE.UNARY(exp=x),sb,sa},attr=attr),scalar=DAE.UNARY(exp=y),source=source,attr=eqAttr),(eqnslst,index,_)) | ||
| 3405 | algorithm | ||
| 3406 | ✗ | eqn := BackendDAE.EQUATION(y,DAE.CALL(path,{x,sa,sb},attr),source,eqAttr); | |
| 3407 | ✗ | if Flags.isSet(Flags.SEMILINEAR) then | |
| 3408 | ✗ | BackendDump.debugStrEqnStr("Found semiLinear ",eqn,"\n"); | |
| 3409 | end if; | ||
| 3410 | ✗ | then (eqn,((eqn,index)::eqnslst,index+1,true)); | |
| 3411 | // y = semiLinear(-x,sb,sa) -> -y = semiLinear(x,sa,sb) | ||
| 3412 | case (BackendDAE.EQUATION(exp=y,scalar=DAE.CALL(path = path as Absyn.IDENT("semiLinear"), expLst = {DAE.UNARY(exp=x),sb,sa},attr=attr),source=source,attr=eqAttr),(eqnslst,index,_)) | ||
| 3413 | algorithm | ||
| 3414 | 8 | y := Expression.negate(y); | |
| 3415 | 8 | eqn := BackendDAE.EQUATION(y,DAE.CALL(path,{x,sa,sb},attr),source,eqAttr); | |
| 3416 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | if Flags.isSet(Flags.SEMILINEAR) then |
| 3417 | ✗ | BackendDump.debugStrEqnStr("Found semiLinear ",eqn,"\n"); | |
| 3418 | end if; | ||
| 3419 | 16 | then (eqn,((eqn,index)::eqnslst,index+1,true)); | |
| 3420 | case (BackendDAE.EQUATION(exp=DAE.CALL(path = path as Absyn.IDENT("semiLinear"), expLst = {DAE.UNARY(exp=x),sb,sa},attr=attr),scalar=y,source=source,attr=eqAttr),(eqnslst,index,_)) | ||
| 3421 | algorithm | ||
| 3422 | ✗ | y := Expression.negate(y); | |
| 3423 | ✗ | eqn := BackendDAE.EQUATION(y,DAE.CALL(path,{x,sa,sb},attr),source,eqAttr); | |
| 3424 | ✗ | if Flags.isSet(Flags.SEMILINEAR) then | |
| 3425 | ✗ | BackendDump.debugStrEqnStr("Found semiLinear ",eqn,"\n"); | |
| 3426 | end if; | ||
| 3427 | ✗ | then (eqn,((eqn,index)::eqnslst,index+1,true)); | |
| 3428 | // y = semiLinear(x,sa,sb) | ||
| 3429 | case (eqn as BackendDAE.EQUATION(scalar=DAE.CALL(path =Absyn.IDENT("semiLinear"))),(eqnslst,index,_)) | ||
| 3430 | algorithm | ||
| 3431 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 345 times.
|
345 | if Flags.isSet(Flags.SEMILINEAR) then |
| 3432 | ✗ | BackendDump.debugStrEqnStr("Found semiLinear ",eqn,"\n"); | |
| 3433 | end if; | ||
| 3434 | 690 | then (eqn,((eqn,index)::eqnslst,index+1,true)); | |
| 3435 | case (eqn as BackendDAE.EQUATION(exp=DAE.CALL(path =Absyn.IDENT("semiLinear"))),(eqnslst,index,_)) | ||
| 3436 | algorithm | ||
| 3437 | ✗ | if Flags.isSet(Flags.SEMILINEAR) then | |
| 3438 | ✗ | BackendDump.debugStrEqnStr("Found semiLinear ",eqn,"\n"); | |
| 3439 | end if; | ||
| 3440 | ✗ | then (eqn,((eqn,index)::eqnslst,index+1,true)); | |
| 3441 | case (BackendDAE.EQUATION(exp=y,scalar=DAE.UNARY(exp= x as DAE.CALL(path = Absyn.IDENT("semiLinear"))),source=source,attr=eqAttr),(eqnslst,index,_)) | ||
| 3442 | algorithm | ||
| 3443 | ✗ | y := Expression.negate(y); | |
| 3444 | ✗ | eqn := BackendDAE.EQUATION(y,x,source,eqAttr); | |
| 3445 | ✗ | if Flags.isSet(Flags.SEMILINEAR) then | |
| 3446 | ✗ | BackendDump.debugStrEqnStr("Found semiLinear ",eqn,"\n"); | |
| 3447 | end if; | ||
| 3448 | ✗ | then (eqn,((eqn,index)::eqnslst,index+1,true)); | |
| 3449 | case (BackendDAE.EQUATION(exp=DAE.UNARY(exp= x as DAE.CALL(path = Absyn.IDENT("semiLinear"))),scalar=y,source=source,attr=eqAttr),(eqnslst,index,_)) | ||
| 3450 | algorithm | ||
| 3451 | ✗ | y := Expression.negate(y); | |
| 3452 | ✗ | eqn := BackendDAE.EQUATION(y,x,source,eqAttr); | |
| 3453 | ✗ | if Flags.isSet(Flags.SEMILINEAR) then | |
| 3454 | ✗ | BackendDump.debugStrEqnStr("Found semiLinear ",eqn,"\n"); | |
| 3455 | end if; | ||
| 3456 | ✗ | then (eqn,((eqn,index)::eqnslst,index+1,true)); | |
| 3457 | |||
| 3458 |
2/2✓ Branch 0 taken 50274 times.
✓ Branch 1 taken 7157 times.
|
107705 | case (eqn,(eqnslst,index,b)) then (eqn,(eqnslst,index+1,b)); |
| 3459 | end matchcontinue; | ||
| 3460 | end simplifysemiLinearFinder; | ||
| 3461 | |||
| 3462 | // ============================================================================= | ||
| 3463 | // remove constants stuff | ||
| 3464 | // | ||
| 3465 | // ============================================================================= | ||
| 3466 | |||
| 3467 | public function removeConstants "author: Frenkel TUD" | ||
| 3468 | input BackendDAE.BackendDAE inDAE; | ||
| 3469 | output BackendDAE.BackendDAE outDAE; | ||
| 3470 | algorithm | ||
| 3471 | outDAE := match inDAE | ||
| 3472 | local | ||
| 3473 | BackendDAE.Variables globalKnownVars; | ||
| 3474 | BackendVarTransform.VariableReplacements repl; | ||
| 3475 | BackendDAE.EqSystems systs; | ||
| 3476 | BackendDAE.Shared shared; | ||
| 3477 | list<BackendDAE.Equation> lsteqns; | ||
| 3478 | Boolean b; | ||
| 3479 | case BackendDAE.DAE(systs, shared as BackendDAE.SHARED(globalKnownVars=globalKnownVars)) | ||
| 3480 | algorithm | ||
| 3481 | 2824 | repl := BackendVarTransform.emptyReplacements(); | |
| 3482 | 2824 | repl := BackendVariable.traverseBackendDAEVars(globalKnownVars, removeConstantsFinder, repl); | |
| 3483 | |||
| 3484 | 2824 | (globalKnownVars, (repl, _)) := BackendVariable.traverseBackendDAEVarsWithUpdate(globalKnownVars, replaceFinalVarTraverser, (repl, 0)); | |
| 3485 | |||
| 3486 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2824 times.
|
2824 | if Flags.isSet(Flags.DUMP_CONST_REPL) then |
| 3487 | ✗ | BackendVarTransform.dumpReplacements(repl); | |
| 3488 | end if; | ||
| 3489 | |||
| 3490 | 2824 | lsteqns := BackendEquation.equationList(shared.initialEqs); | |
| 3491 | 2824 | (lsteqns, b) := BackendVarTransform.replaceEquations(lsteqns, repl, NONE()); | |
| 3492 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2824 times.
|
2824 | shared.initialEqs := if b then BackendEquation.listEquation(lsteqns) else shared.initialEqs; |
| 3493 | |||
| 3494 | 2824 | lsteqns := BackendEquation.equationList(shared.removedEqs); | |
| 3495 | 2824 | (lsteqns, b) := BackendVarTransform.replaceEquations(lsteqns, repl, NONE()); | |
| 3496 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2824 times.
|
2824 | shared.removedEqs := if b then BackendEquation.listEquation(lsteqns) else shared.removedEqs; |
| 3497 | |||
| 3498 | |||
| 3499 | 2824 | systs := List.map1(systs, removeConstantsWork, repl); | |
| 3500 | |||
| 3501 | 2824 | then BackendDAE.DAE(systs, shared); | |
| 3502 | end match; | ||
| 3503 | end removeConstants; | ||
| 3504 | |||
| 3505 | protected function removeConstantsWork "author: Frenkel TUD" | ||
| 3506 | input BackendDAE.EqSystem inEqSystem; | ||
| 3507 | input BackendVarTransform.VariableReplacements repl; | ||
| 3508 | output BackendDAE.EqSystem outEqSystem; | ||
| 3509 | algorithm | ||
| 3510 | outEqSystem := match inEqSystem | ||
| 3511 | local | ||
| 3512 | BackendDAE.Variables vars; | ||
| 3513 | list<BackendDAE.Equation> lsteqns; | ||
| 3514 | Boolean b; | ||
| 3515 | BackendDAE.EqSystem syst; | ||
| 3516 | case syst as BackendDAE.EQSYSTEM(orderedVars=vars) | ||
| 3517 | algorithm | ||
| 3518 | 5692 | BackendVariable.traverseBackendDAEVarsWithUpdate(vars, replaceFinalVarTraverser, (repl, 0)); | |
| 3519 | |||
| 3520 | 5692 | (lsteqns, b) := BackendVarTransform.replaceEquations(BackendEquation.equationList(syst.orderedEqs), repl, NONE()); | |
| 3521 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5692 times.
|
5692 | if b then |
| 3522 | ✗ | syst.orderedEqs := BackendEquation.listEquation(lsteqns); | |
| 3523 | ✗ | syst := BackendDAEUtil.clearEqSyst(syst); | |
| 3524 | end if; | ||
| 3525 | |||
| 3526 | 5692 | (lsteqns, b) := BackendVarTransform.replaceEquations(BackendEquation.equationList(syst.removedEqs), repl, NONE()); | |
| 3527 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5692 times.
|
5692 | if b then |
| 3528 | ✗ | syst.removedEqs := BackendEquation.listEquation(lsteqns); | |
| 3529 | end if; | ||
| 3530 | |||
| 3531 | then syst; | ||
| 3532 | end match; | ||
| 3533 | end removeConstantsWork; | ||
| 3534 | |||
| 3535 | protected function removeConstantsFinder | ||
| 3536 | input BackendDAE.Var inVar; | ||
| 3537 | input BackendVarTransform.VariableReplacements inRepl; | ||
| 3538 | output BackendDAE.Var outVar; | ||
| 3539 | output BackendVarTransform.VariableReplacements outRepl; | ||
| 3540 | algorithm | ||
| 3541 | (outVar,outRepl) := matchcontinue (inVar,inRepl) | ||
| 3542 | local | ||
| 3543 | BackendDAE.Var v; | ||
| 3544 | BackendVarTransform.VariableReplacements repl, repl_1; | ||
| 3545 | DAE.ComponentRef varName; | ||
| 3546 | DAE.Exp exp; | ||
| 3547 | |||
| 3548 | case (v as BackendDAE.VAR(varName=varName, varKind=BackendDAE.CONST(), bindExp=SOME(exp)), repl) | ||
| 3549 | algorithm | ||
| 3550 | 8092 | repl_1 := BackendVarTransform.addReplacement(repl, varName, exp, NONE()); | |
| 3551 | then (v, repl_1); | ||
| 3552 | |||
| 3553 | else (inVar,inRepl); | ||
| 3554 | end matchcontinue; | ||
| 3555 | end removeConstantsFinder; | ||
| 3556 | |||
| 3557 | |||
| 3558 | // ============================================================================= | ||
| 3559 | // reaplace edge and change with (b and not pre(b)) and (v <> pre(v)) | ||
| 3560 | // | ||
| 3561 | // ============================================================================= | ||
| 3562 | |||
| 3563 | public function replaceEdgeChange "author: Frenkel TUD 2012-11 | ||
| 3564 | edge(b) = b and not pre(b) | ||
| 3565 | change(b) = v <> pre(v)" | ||
| 3566 | input BackendDAE.BackendDAE inDAE; | ||
| 3567 | output BackendDAE.BackendDAE outDAE; | ||
| 3568 | algorithm | ||
| 3569 | 1074 | (outDAE,_) := BackendDAEUtil.mapEqSystemAndFold(inDAE, replaceEdgeChange0, false); | |
| 3570 | 1074 | outDAE := replaceEdgeChangeShared(outDAE); | |
| 3571 | end replaceEdgeChange; | ||
| 3572 | |||
| 3573 | protected function replaceEdgeChange0 "author: Frenkel TUD 2012-11" | ||
| 3574 | input BackendDAE.EqSystem isyst; | ||
| 3575 | input BackendDAE.Shared inShared; | ||
| 3576 | input Boolean inChanged; | ||
| 3577 | output BackendDAE.EqSystem osyst; | ||
| 3578 | output BackendDAE.Shared outShared = inShared; | ||
| 3579 | output Boolean outChanged; | ||
| 3580 | algorithm | ||
| 3581 | (osyst, outChanged) := matchcontinue isyst | ||
| 3582 | local | ||
| 3583 | BackendDAE.EquationArray orderedEqs, removedEqs; | ||
| 3584 | |||
| 3585 | case BackendDAE.EQSYSTEM(orderedEqs=orderedEqs, removedEqs=removedEqs) | ||
| 3586 | algorithm | ||
| 3587 | 18375 | BackendDAEUtil.traverseBackendDAEExpsEqns(orderedEqs, traverserreplaceEdgeChange, false); | |
| 3588 | 18375 | BackendDAEUtil.traverseBackendDAEExpsEqns(removedEqs, traverserreplaceEdgeChange, false); | |
| 3589 | then (isyst, true); | ||
| 3590 | |||
| 3591 | else (isyst, inChanged); | ||
| 3592 | end matchcontinue; | ||
| 3593 | end replaceEdgeChange0; | ||
| 3594 | |||
| 3595 | protected function traverserreplaceEdgeChange "author: Frenkel TUD 2012-11" | ||
| 3596 | input DAE.Exp e; | ||
| 3597 | input Boolean b; | ||
| 3598 | output DAE.Exp oe; | ||
| 3599 | output Boolean ob; | ||
| 3600 | algorithm | ||
| 3601 |
3/4✓ Branch 0 taken 323654 times.
✓ Branch 1 taken 1645 times.
✓ Branch 3 taken 325299 times.
✗ Branch 4 not taken.
|
648953 | (oe,ob) := Expression.traverseExpBottomUp(e,traverserExpreplaceEdgeChange,b); |
| 3602 | end traverserreplaceEdgeChange; | ||
| 3603 | |||
| 3604 | protected function traverserExpreplaceEdgeChange "author: Frenkel TUD 2012-11" | ||
| 3605 | input DAE.Exp inExp; | ||
| 3606 | input Boolean inB; | ||
| 3607 | output DAE.Exp outExp; | ||
| 3608 | output Boolean outB; | ||
| 3609 | algorithm | ||
| 3610 | (outExp,outB) := matchcontinue inExp | ||
| 3611 | local | ||
| 3612 | DAE.Exp e; | ||
| 3613 | DAE.Type ty; | ||
| 3614 | |||
| 3615 | // change(v) -> v <> pre(v) | ||
| 3616 | case DAE.CALL(path=Absyn.IDENT(name = "change"), expLst={e}) | ||
| 3617 | algorithm | ||
| 3618 | 48 | ty := Expression.typeof(e); | |
| 3619 | 96 | then (DAE.RELATION(e, DAE.NEQUAL(ty), DAE.CALL(Absyn.IDENT("pre"), {e}, DAE.CALL_ATTR(ty, false, true, false, false, DAE.NO_INLINE(), DAE.NO_TAIL(), DAE.NoReturn.RETURNS)), -1, NONE()), true); | |
| 3620 | |||
| 3621 | // edge(b) = b and not pre(b) | ||
| 3622 | case DAE.CALL(path=Absyn.IDENT(name = "edge"), expLst={e}) | ||
| 3623 | algorithm | ||
| 3624 | 40 | ty := Expression.typeof(e); | |
| 3625 | 80 | then (DAE.LBINARY(e, DAE.AND(ty), DAE.LUNARY(DAE.NOT(ty), DAE.CALL(Absyn.IDENT("pre"), {e}, DAE.CALL_ATTR(ty, false, true, false, false, DAE.NO_INLINE(), DAE.NO_TAIL(), DAE.NoReturn.RETURNS)))), true); | |
| 3626 | |||
| 3627 | else (inExp,inB); | ||
| 3628 | end matchcontinue; | ||
| 3629 | end traverserExpreplaceEdgeChange; | ||
| 3630 | |||
| 3631 | protected function replaceEdgeChangeShared "author: Frenkel TUD 2012-11" | ||
| 3632 | input BackendDAE.BackendDAE inDAE; | ||
| 3633 | output BackendDAE.BackendDAE outDAE; | ||
| 3634 | algorithm | ||
| 3635 | outDAE := match inDAE | ||
| 3636 | local | ||
| 3637 | BackendDAE.EquationArray remeqns; | ||
| 3638 | BackendDAE.EqSystems systs; | ||
| 3639 | BackendDAE.Shared shared; | ||
| 3640 | case BackendDAE.DAE(systs, shared as BackendDAE.SHARED(removedEqs=remeqns)) | ||
| 3641 | algorithm | ||
| 3642 | 1074 | BackendDAEUtil.traverseBackendDAEExpsEqns(remeqns, traverserreplaceEdgeChange, false); | |
| 3643 | 1074 | then BackendDAE.DAE(systs, shared); | |
| 3644 | end match; | ||
| 3645 | end replaceEdgeChangeShared; | ||
| 3646 | |||
| 3647 | |||
| 3648 | // ============================================================================= | ||
| 3649 | // section for preOptModule >>removeLocalKnownVars<< | ||
| 3650 | // | ||
| 3651 | // ============================================================================= | ||
| 3652 | |||
| 3653 | public function removeLocalKnownVars "Looks for equations only depending on one variable and save them in localKnownVars." | ||
| 3654 | input BackendDAE.BackendDAE inDAE; | ||
| 3655 | output BackendDAE.BackendDAE outDAE; | ||
| 3656 | algorithm | ||
| 3657 | 1 | outDAE := BackendDAEUtil.mapEqSystem(inDAE, removeLocalKnownVars2); | |
| 3658 | end removeLocalKnownVars; | ||
| 3659 | |||
| 3660 | |||
| 3661 | public function removeLocalKnownVars2 | ||
| 3662 | input output BackendDAE.EqSystem syst; | ||
| 3663 | input output BackendDAE.Shared shared; | ||
| 3664 | protected | ||
| 3665 | BackendDAE.AdjacencyMatrix m; | ||
| 3666 | BackendDAE.Var potentialLocalKnownVar; | ||
| 3667 | BackendDAE.Equation potentialGlobalKnownEquation; | ||
| 3668 | BackendDAE.Variables orderedVars = syst.orderedVars; | ||
| 3669 | BackendDAE.EquationArray orderedEqs = syst.orderedEqs; | ||
| 3670 | DAE.Exp lhs; | ||
| 3671 | DAE.Exp rhs; | ||
| 3672 | DAE.Exp crefExp; | ||
| 3673 | DAE.Exp binding; | ||
| 3674 | list<Integer> localKnownVars={}; | ||
| 3675 | list<Integer> localKnownEqns={}; | ||
| 3676 | Integer eindex=0; | ||
| 3677 | Integer vindex; | ||
| 3678 | algorithm | ||
| 3679 | 1 | (_,m,_,_,_) := BackendDAEUtil.getAdjacencyMatrixScalar(syst, BackendDAE.NORMAL(),NONE(), BackendDAEUtil.isInitializationDAE(shared)); | |
| 3680 | |||
| 3681 | // Delete negative entries from adjacency matrix | ||
| 3682 | 1 | m := Array.map(m,Tearing.deleteNegativeEntries); | |
| 3683 | |||
| 3684 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 1 time.
|
7 | for row in m loop |
| 3685 | 5 | eindex := eindex+1; | |
| 3686 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 3 times.
|
5 | if listLength(row) == 1 then |
| 3687 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
|
2 | {vindex} := row; |
| 3688 | //print("Variable: " + intString(vindex) + "\n"); | ||
| 3689 | //print("Equation: " + intString(eindex) + "\n\n"); | ||
| 3690 | |||
| 3691 | 2 | potentialLocalKnownVar := BackendVariable.getVarAt(orderedVars,vindex); | |
| 3692 | 2 | potentialGlobalKnownEquation := BackendEquation.get(orderedEqs,eindex); | |
| 3693 | |||
| 3694 | try | ||
| 3695 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | BackendDAE.EQUATION(exp = lhs, scalar = rhs) := potentialGlobalKnownEquation; |
| 3696 | 2 | crefExp := BackendVariable.varExp(potentialLocalKnownVar); | |
| 3697 | 2 | (binding,_) := ExpressionSolve.solve(lhs,rhs,crefExp, NONE()); | |
| 3698 | 2 | potentialLocalKnownVar := BackendVariable.setBindExp(potentialLocalKnownVar, SOME(binding)); | |
| 3699 | 2 | localKnownVars := vindex::localKnownVars; | |
| 3700 | 2 | localKnownEqns := eindex::localKnownEqns; | |
| 3701 | 2 | shared.localKnownVars := BackendVariable.addVar(potentialLocalKnownVar, shared.localKnownVars); | |
| 3702 | else | ||
| 3703 | end try; | ||
| 3704 | end if; | ||
| 3705 | end for; | ||
| 3706 | 1 | localKnownVars := List.sort(localKnownVars, intLt); | |
| 3707 | 1 | localKnownEqns := listReverse(localKnownEqns); | |
| 3708 | |||
| 3709 | |||
| 3710 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 time.
|
3 | for var in localKnownVars loop |
| 3711 | 2 | orderedVars := BackendVariable.removeVar(var, orderedVars); | |
| 3712 | end for; | ||
| 3713 | |||
| 3714 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 time.
|
3 | for eqn in localKnownEqns loop |
| 3715 | 2 | orderedEqs := BackendEquation.delete(eqn, orderedEqs); | |
| 3716 | end for; | ||
| 3717 | |||
| 3718 | // delete adjacency matrix | ||
| 3719 | 1 | syst.m := NONE(); | |
| 3720 | syst.mT := NONE(); | ||
| 3721 | syst.matching := BackendDAE.NO_MATCHING(); | ||
| 3722 | |||
| 3723 | // TODO: remove this | ||
| 3724 | syst.orderedVars := BackendVariable.listVar(BackendVariable.varList(orderedVars)); | ||
| 3725 | syst.orderedEqs := orderedEqs; | ||
| 3726 | end removeLocalKnownVars2; | ||
| 3727 | |||
| 3728 | |||
| 3729 | // ============================================================================= | ||
| 3730 | // section for postOptModule >>addInitialStmtsToAlgorithms<< | ||
| 3731 | // | ||
| 3732 | // Real a[3]; | ||
| 3733 | // algorithm --> algorithm | ||
| 3734 | // a[1] := 1.0; a[1] := $START.a[1]; | ||
| 3735 | // a[2] := $START.a[2]; | ||
| 3736 | // a[3] := $START.a[3]; | ||
| 3737 | // a[1] := 1.0; | ||
| 3738 | // ============================================================================= | ||
| 3739 | |||
| 3740 | public function addInitialStmtsToAlgorithms " | ||
| 3741 | section are executed in the order of appearance. Whenever an algorithm section is invoked, all variables appearing | ||
| 3742 | on the left hand side of the assignment operator := are initialized (at least conceptually): | ||
| 3743 | - A non-discrete variable is initialized with its start value (i.e. the value of the start-attribute). | ||
| 3744 | - A discrete variable v is initialized with pre(v)." | ||
| 3745 | input BackendDAE.BackendDAE inDAE; | ||
| 3746 | input Boolean isInitialSystem; | ||
| 3747 | output BackendDAE.BackendDAE outDAE; | ||
| 3748 | algorithm | ||
| 3749 |
2/2✓ Branch 0 taken 1085 times.
✓ Branch 1 taken 1120 times.
|
3290 | outDAE := BackendDAEUtil.mapEqSystem1(inDAE, addInitialStmtsToAlgorithms1, isInitialSystem); |
| 3750 | end addInitialStmtsToAlgorithms; | ||
| 3751 | |||
| 3752 | protected function addInitialStmtsToAlgorithms1 "Helper function to addInitialStmtsToAlgorithms." | ||
| 3753 | input BackendDAE.EqSystem syst; | ||
| 3754 | input Boolean isInitialSystem; | ||
| 3755 | input BackendDAE.Shared shared; | ||
| 3756 | output BackendDAE.EqSystem osyst = syst; | ||
| 3757 | output BackendDAE.Shared oshared = shared; | ||
| 3758 | protected | ||
| 3759 | BackendDAE.Variables ordvars; | ||
| 3760 | BackendDAE.EquationArray ordeqns; | ||
| 3761 | algorithm | ||
| 3762 | 49146 | BackendDAE.EQSYSTEM(orderedVars=ordvars, orderedEqs=ordeqns) := osyst; | |
| 3763 |
2/2✓ Branch 0 taken 1583 times.
✓ Branch 1 taken 47563 times.
|
50729 | BackendEquation.traverseEquationArray_WithUpdate(ordeqns, eaddInitialStmtsToAlgorithms1Helper, (ordvars, isInitialSystem)); |
| 3764 | end addInitialStmtsToAlgorithms1; | ||
| 3765 | |||
| 3766 | protected function eaddInitialStmtsToAlgorithms1Helper "Helper function to addInitialStmtsToAlgorithms1." | ||
| 3767 | input BackendDAE.Equation inEq; | ||
| 3768 | input tuple<BackendDAE.Variables, Boolean> inTpl; | ||
| 3769 | output BackendDAE.Equation outEq; | ||
| 3770 | output tuple<BackendDAE.Variables, Boolean> outTpl = inTpl; | ||
| 3771 | algorithm | ||
| 3772 | outEq := match (inEq, inTpl) | ||
| 3773 | local | ||
| 3774 | DAE.Algorithm alg; | ||
| 3775 | list<DAE.Statement> statements; | ||
| 3776 | BackendDAE.Variables vars; | ||
| 3777 | Integer size; | ||
| 3778 | list<DAE.Exp> outputs; | ||
| 3779 | DAE.ElementSource source; | ||
| 3780 | list<DAE.ComponentRef> crlst; | ||
| 3781 | DAE.Expand crExpand; | ||
| 3782 | BackendDAE.EquationAttributes attr; | ||
| 3783 | Boolean isInitialEquations; | ||
| 3784 | |||
| 3785 | case (BackendDAE.ALGORITHM(size=size, alg=alg as DAE.ALGORITHM_STMTS(statements), source=source, expand=crExpand, attr=attr), (vars, isInitialEquations)) | ||
| 3786 | algorithm | ||
| 3787 | 512 | crlst := CheckModel.checkAndGetAlgorithmOutputs(alg, source, crExpand); | |
| 3788 | 512 | outputs := List.map(crlst, Expression.crefExp); | |
| 3789 | 512 | statements := expandAlgorithmStmts(statements, outputs, vars, isInitialEquations); | |
| 3790 | 512 | then BackendDAE.ALGORITHM(size, DAE.ALGORITHM_STMTS(statements), source, crExpand, attr); | |
| 3791 | |||
| 3792 | else inEq; | ||
| 3793 | end match; | ||
| 3794 | end eaddInitialStmtsToAlgorithms1Helper; | ||
| 3795 | |||
| 3796 | public function expandAlgorithmStmts "Helper function to eaddInitialStmtsToAlgorithms1Helper." | ||
| 3797 | input list<DAE.Statement> inAlg; | ||
| 3798 | input list<DAE.Exp> inOutputs; | ||
| 3799 | input BackendDAE.Variables inVars; | ||
| 3800 | input Boolean isInitialEquation; | ||
| 3801 | output list<DAE.Statement> outAlg; | ||
| 3802 | algorithm | ||
| 3803 | outAlg := match(inAlg, inOutputs) | ||
| 3804 | local | ||
| 3805 | DAE.Exp out, initExp; | ||
| 3806 | list<DAE.Exp> rest; | ||
| 3807 | DAE.ComponentRef cref; | ||
| 3808 | list<BackendDAE.Var> vars; | ||
| 3809 | DAE.Statement stmt; | ||
| 3810 | DAE.Type type_; | ||
| 3811 | list<DAE.Statement> statements; | ||
| 3812 | |||
| 3813 | case(statements, {}) | ||
| 3814 | then statements; | ||
| 3815 | |||
| 3816 | case(statements, out::rest) algorithm | ||
| 3817 | 2203 | cref := Expression.expCref(out); | |
| 3818 | 2203 | (vars, _) := BackendVariable.getVar(cref, inVars); | |
| 3819 |
2/2✓ Branch 0 taken 2203 times.
✓ Branch 1 taken 2203 times.
|
4406 | for v in vars loop |
| 3820 | 2203 | type_ := v.varType; | |
| 3821 |
4/4✓ Branch 1 taken 1822 times.
✓ Branch 2 taken 381 times.
✓ Branch 3 taken 1180 times.
✓ Branch 4 taken 642 times.
|
2203 | if BackendVariable.isVarDiscrete(v) and not isInitialEquation then |
| 3822 | 2360 | initExp := Expression.makePureBuiltinCall("pre", {Expression.crefExp(v.varName)}, type_); | |
| 3823 | else | ||
| 3824 | 1023 | initExp := Expression.crefExp(ComponentReference.crefPrefixStart(v.varName)); | |
| 3825 | end if; | ||
| 3826 | 2203 | stmt := Algorithm.makeAssignment(DAE.CREF(v.varName, type_), DAE.PROP(type_, DAE.C_VAR()), initExp, DAE.PROP(type_, DAE.C_VAR()), DAE.dummyAttrVar, SCode.NON_INITIAL(), DAE.emptyElementSource); | |
| 3827 | statements := stmt::statements; | ||
| 3828 | end for; | ||
| 3829 | 2203 | then expandAlgorithmStmts(statements, rest, inVars, isInitialEquation); | |
| 3830 | end match; | ||
| 3831 | end expandAlgorithmStmts; | ||
| 3832 | |||
| 3833 | |||
| 3834 | // ============================================================================= | ||
| 3835 | // section for expandDerOperator | ||
| 3836 | // | ||
| 3837 | // ============================================================================= | ||
| 3838 | |||
| 3839 | public function expandDerOperator " | ||
| 3840 | Expands der(expr) using Derive.differentiteExpTime. | ||
| 3841 | This can not be done in Static, since we need all time- | ||
| 3842 | dependent variables, which is only available in BackendDAE." | ||
| 3843 | input BackendDAE.BackendDAE inDAE; | ||
| 3844 | output BackendDAE.BackendDAE outDAE; | ||
| 3845 | algorithm | ||
| 3846 | 1089 | outDAE := BackendDAEUtil.mapEqSystem(inDAE, expandDerOperatorWork); | |
| 3847 | end expandDerOperator; | ||
| 3848 | |||
| 3849 | protected function expandDerOperatorWork " | ||
| 3850 | expands der(expr) using Derive.differentiteExpTime. | ||
| 3851 | This can not be done in Static, since we need all time- | ||
| 3852 | dependent variables, which is only available in BackendDAE." | ||
| 3853 | input output BackendDAE.EqSystem syst; | ||
| 3854 | input output BackendDAE.Shared shared; | ||
| 3855 | algorithm | ||
| 3856 | (syst, shared) := match (syst, shared) | ||
| 3857 | local | ||
| 3858 | BackendDAE.Variables vars; | ||
| 3859 | BackendDAE.EquationArray eqns, inieqns, remeqns; | ||
| 3860 | Mutable<BackendDAE.Shared> shared_arr; | ||
| 3861 | |||
| 3862 | case (syst as BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns, removedEqs=remeqns), BackendDAE.SHARED(initialEqs=inieqns)) | ||
| 3863 | algorithm | ||
| 3864 | 1089 | shared_arr := Mutable.create(shared); | |
| 3865 | 1089 | (_, vars) := BackendEquation.traverseEquationArray_WithUpdate(eqns, function traverserexpandDerEquation(shared=shared_arr), vars); | |
| 3866 | 1089 | (_, vars) := BackendEquation.traverseEquationArray_WithUpdate(inieqns, function traverserexpandDerEquation(shared=shared_arr), vars); | |
| 3867 | // A side-effect-only when-equation is a removed equation, but its | ||
| 3868 | // condition is still evaluated. | ||
| 3869 | 1089 | (remeqns, vars) := BackendEquation.traverseEquationArray_WithUpdate(remeqns, function traverserexpandDerEquation(shared=shared_arr), vars); | |
| 3870 | 1089 | syst.removedEqs := remeqns; | |
| 3871 | 1089 | syst.orderedVars := vars; | |
| 3872 | 1089 | then (syst, Mutable.access(shared_arr)); | |
| 3873 | end match; | ||
| 3874 | end expandDerOperatorWork; | ||
| 3875 | |||
| 3876 | protected function traverserexpandDerEquation " | ||
| 3877 | Help function to e.g. traverserexpandDerEquation" | ||
| 3878 | input output BackendDAE.Equation eq; | ||
| 3879 | input output BackendDAE.Variables vars; | ||
| 3880 | input Mutable<BackendDAE.Shared> shared; | ||
| 3881 | protected | ||
| 3882 | list<DAE.SymbolicOperation> ops; | ||
| 3883 | algorithm | ||
| 3884 | 162718 | (eq, (vars, ops)) := BackendEquation.traverseExpsOfEquation(eq, function traverserexpandDerExp(shared=shared), (vars, {})); | |
| 3885 | 162718 | eq := List.foldr(ops, BackendEquation.addOperation, eq); | |
| 3886 | end traverserexpandDerEquation; | ||
| 3887 | |||
| 3888 | protected function traverserexpandDerExp " | ||
| 3889 | Help function to e.g. traverserexpandDerExp" | ||
| 3890 | input output DAE.Exp exp; | ||
| 3891 | input output tuple<BackendDAE.Variables, list<DAE.SymbolicOperation>> tpl; | ||
| 3892 | input Mutable<BackendDAE.Shared> shared; | ||
| 3893 | protected | ||
| 3894 | DAE.Exp exp_1; | ||
| 3895 | BackendDAE.Variables vars1, vars2; | ||
| 3896 | list<DAE.SymbolicOperation> ops; | ||
| 3897 | algorithm | ||
| 3898 | 330183 | (vars1, ops) := tpl; | |
| 3899 | 330183 | (exp_1, vars2) := Expression.traverseExpBottomUp(exp, function expandDerExp(inShared=shared), vars1); | |
| 3900 |
4/4✓ Branch 0 taken 317571 times.
✓ Branch 1 taken 12612 times.
✓ Branch 2 taken 317569 times.
✓ Branch 3 taken 2 times.
|
330183 | if not (referenceEq(vars1, vars2) and referenceEq(exp, exp_1)) then |
| 3901 | 12614 | ops := DAE.OP_DIFFERENTIATE(DAE.crefTime, exp, exp_1)::ops; | |
| 3902 | exp := exp_1; | ||
| 3903 | 12614 | tpl := (vars2, ops); | |
| 3904 | end if; | ||
| 3905 | end traverserexpandDerExp; | ||
| 3906 | |||
| 3907 | protected function expandDerExp " | ||
| 3908 | Help function to e.g. expandDerOperatorEqn" | ||
| 3909 | input output DAE.Exp exp; | ||
| 3910 | input output BackendDAE.Variables vars; | ||
| 3911 | input Mutable<BackendDAE.Shared> inShared; | ||
| 3912 | protected | ||
| 3913 | Boolean failed = false; | ||
| 3914 | algorithm | ||
| 3915 | () := match exp | ||
| 3916 | local | ||
| 3917 | DAE.ComponentRef cr; | ||
| 3918 | String str; | ||
| 3919 | case DAE.CALL(path=Absyn.IDENT(name = "der"), expLst={DAE.CALL(path=Absyn.IDENT(name = "der"), expLst={DAE.CREF(componentRef=cr)})}) | ||
| 3920 | algorithm | ||
| 3921 | ✗ | str := ComponentReference.crefStr(cr); | |
| 3922 | ✗ | str := stringAppendList({"The model includes derivatives of order > 1 for: ", str, ". That is not supported. Adding 'Real d", str, " = der(", str, ");' *might* result in a solvable model"}); | |
| 3923 | ✗ | Error.addMessage(Error.INTERNAL_ERROR, {str}); | |
| 3924 | ✗ | then fail(); | |
| 3925 | else (); | ||
| 3926 | end match; | ||
| 3927 | (exp,vars) := matchcontinue exp | ||
| 3928 | local | ||
| 3929 | DAE.Exp e1, e2; | ||
| 3930 | DAE.ComponentRef cr; | ||
| 3931 | list<BackendDAE.Var> varlst; | ||
| 3932 | BackendDAE.Var v; | ||
| 3933 | BackendDAE.Shared shared; | ||
| 3934 | // case for arrays | ||
| 3935 | case e1 as DAE.CALL(path=Absyn.IDENT(name = "der"), expLst={DAE.CREF(ty = DAE.T_ARRAY())}) | ||
| 3936 | algorithm | ||
| 3937 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 119 times.
|
119 | (e2, true) := Expression.extendArrExp(e1, false); |
| 3938 | 119 | (exp,vars) := Expression.traverseExpBottomUp(e2, function expandDerExp(inShared=inShared), vars); | |
| 3939 | then (exp,vars); | ||
| 3940 | // case for records | ||
| 3941 | case e1 as DAE.CALL(path=Absyn.IDENT(name = "der"), expLst={DAE.CREF(ty = DAE.T_COMPLEX(complexClassType=ClassInf.RECORD(_)))}) | ||
| 3942 | algorithm | ||
| 3943 | ✗ | (e2, true) := Expression.extendArrExp(e1, false); | |
| 3944 | ✗ | (exp,vars) := Expression.traverseExpBottomUp(e2, function expandDerExp(inShared=inShared), vars); | |
| 3945 | then (exp,vars); | ||
| 3946 | case e1 as DAE.CALL(path=Absyn.IDENT(name = "der"), expLst={DAE.CREF(componentRef=cr)}) | ||
| 3947 | algorithm | ||
| 3948 | 13514 | (v, _) := BackendVariable.getVarSingle(cr, vars); | |
| 3949 | try | ||
| 3950 | 13511 | (vars, e1) := updateStatesVar(vars, v, e1); | |
| 3951 | else | ||
| 3952 | failed := true; | ||
| 3953 | end try; | ||
| 3954 | 13511 | then (e1, vars); | |
| 3955 | case e1 as DAE.CALL(path=Absyn.IDENT(name = "der"), expLst={DAE.CREF(componentRef=cr)}) | ||
| 3956 | algorithm | ||
| 3957 | 3 | (varlst, _) := BackendVariable.getVar(cr, vars); | |
| 3958 | ✗ | vars := updateStatesVars(vars, varlst, false); | |
| 3959 | ✗ | then (e1, vars); | |
| 3960 | case DAE.CALL(path=Absyn.IDENT(name = "der"), expLst={e1}) | ||
| 3961 | algorithm | ||
| 3962 | 127 | (e2, shared) := Differentiate.differentiateExpTime(e1, vars, Mutable.access(inShared)); | |
| 3963 |
2/2✓ Branch 1 taken 3 times.
✓ Branch 2 taken 124 times.
|
127 | false := Expression.isZero(e2); |
| 3964 | 124 | Mutable.update(inShared, shared); | |
| 3965 | 124 | (e2, _) := ExpressionSimplify.simplify(e2); | |
| 3966 | 124 | (_, vars) := Expression.traverseExpBottomUp(e2, derCrefsExp, vars); | |
| 3967 | 124 | then (e2, vars); | |
| 3968 | 1315047 | else (exp,vars); | |
| 3969 | end matchcontinue; | ||
| 3970 | |||
| 3971 | // FIXME dumb hack to make matchcontinue fail | ||
| 3972 | // I don't want to rewrite the damn thing | ||
| 3973 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1328801 times.
|
1328801 | if failed then |
| 3974 | ✗ | fail(); | |
| 3975 | end if; | ||
| 3976 | end expandDerExp; | ||
| 3977 | |||
| 3978 | protected function derCrefsExp "helper for statesExp" | ||
| 3979 | input DAE.Exp inExp; | ||
| 3980 | input BackendDAE.Variables inVars; | ||
| 3981 | output DAE.Exp outExp; | ||
| 3982 | output BackendDAE.Variables outVars; | ||
| 3983 | algorithm | ||
| 3984 | (outExp,outVars) := matchcontinue (inExp,inVars) | ||
| 3985 | local | ||
| 3986 | DAE.ComponentRef cr; | ||
| 3987 | BackendDAE.Variables vars; | ||
| 3988 | list<BackendDAE.Var> varlst; | ||
| 3989 | BackendDAE.Var v; | ||
| 3990 | DAE.Exp e; | ||
| 3991 | case (e as DAE.CALL(path = Absyn.IDENT(name = "der"), expLst = {DAE.CREF(componentRef = cr)}), vars) | ||
| 3992 | algorithm | ||
| 3993 | 404 | (v, _) := BackendVariable.getVarSingle(cr, vars); | |
| 3994 | 404 | (vars, e) := updateStatesVar(vars, v, e); | |
| 3995 | 404 | then (e, vars); | |
| 3996 | case (e as DAE.CALL(path = Absyn.IDENT(name = "der"), expLst = {DAE.CREF(componentRef = cr)}), vars) | ||
| 3997 | algorithm | ||
| 3998 | ✗ | (varlst, _) := BackendVariable.getVar(cr, vars); | |
| 3999 | ✗ | vars := updateStatesVars(vars, varlst, false); | |
| 4000 | ✗ | then (e, vars); | |
| 4001 | else (inExp,inVars); | ||
| 4002 | end matchcontinue; | ||
| 4003 | end derCrefsExp; | ||
| 4004 | |||
| 4005 | protected function updateStatesVar " | ||
| 4006 | Help function to expandDerExp" | ||
| 4007 | input BackendDAE.Variables inVars; | ||
| 4008 | input BackendDAE.Var var; | ||
| 4009 | input DAE.Exp iExp; | ||
| 4010 | output BackendDAE.Variables outVars = inVars; | ||
| 4011 | output DAE.Exp oExp = iExp; | ||
| 4012 | protected | ||
| 4013 | BackendDAE.Var var1; | ||
| 4014 | DAE.Exp arg; | ||
| 4015 | algorithm | ||
| 4016 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 13915 times.
|
13915 | if BackendVariable.isVarNonDifferentiable(var) then |
| 4017 | ✗ | DAE.CALL(expLst = {arg}) := iExp; | |
| 4018 | ✗ | Error.addSourceMessageAndFail(Error.DER_OF_NONDIFFERENTIABLE_EXP, | |
| 4019 | {ExpressionBasics.printExpStr(arg)}, var.source.info); | ||
| 4020 | elseif BackendVariable.isVarDiscrete(var) then | ||
| 4021 | oExp := DAE.RCONST(0.0); | ||
| 4022 | elseif not BackendVariable.isStateVar(var) or BackendVariable.varStateSelectForced(var) then | ||
| 4023 | 13053 | var1 := BackendVariable.setVarKind(var, BackendDAE.STATE(1, NONE(), true)); | |
| 4024 | 13053 | outVars := BackendVariable.addVar(var1, inVars); | |
| 4025 | oExp := iExp; | ||
| 4026 | else | ||
| 4027 | /* Might be part of a different equation-system... | ||
| 4028 | str = "BackendDAECreate.updateStatesVars failed for: " + ComponentReferenceBasics.printComponentRefStr(cr); | ||
| 4029 | Error.addMessage(Error.INTERNAL_ERROR, {str}); | ||
| 4030 | */ | ||
| 4031 | end if; | ||
| 4032 | end updateStatesVar; | ||
| 4033 | |||
| 4034 | protected function updateStatesVars " | ||
| 4035 | Help function to expandDerExp" | ||
| 4036 | input BackendDAE.Variables inVars; | ||
| 4037 | input list<BackendDAE.Var> inNewStates; | ||
| 4038 | input Boolean noStateFound; | ||
| 4039 | output BackendDAE.Variables outVars; | ||
| 4040 | algorithm | ||
| 4041 | outVars := matchcontinue(inNewStates, noStateFound) | ||
| 4042 | local | ||
| 4043 | BackendDAE.Var var; | ||
| 4044 | list<BackendDAE.Var> newStates; | ||
| 4045 | BackendDAE.Variables vars; | ||
| 4046 | //DAE.ComponentRef cr; | ||
| 4047 | //String str; | ||
| 4048 | |||
| 4049 | case({}, true) then inVars; | ||
| 4050 | case(var::newStates, _) | ||
| 4051 | algorithm | ||
| 4052 | ✗ | false := BackendVariable.isVarDiscrete(var) "do not change discrete vars to states, because they have no derivative" ; | |
| 4053 | ✗ | false := BackendVariable.isStateVar(var); | |
| 4054 | ✗ | var := BackendVariable.setVarKind(var, BackendDAE.STATE(1,NONE(),true)); | |
| 4055 | ✗ | vars := BackendVariable.addVar(var, inVars); | |
| 4056 | ✗ | vars := updateStatesVars(vars, newStates, true); | |
| 4057 | then vars; | ||
| 4058 | case(_::newStates, _) | ||
| 4059 | algorithm | ||
| 4060 | /* Might be part of a different equation-system... | ||
| 4061 | str = "BackendDAECreate.updateStatesVars failed for: " + ComponentReferenceBasics.printComponentRefStr(cr); | ||
| 4062 | Error.addMessage(Error.INTERNAL_ERROR, {str}); | ||
| 4063 | */ | ||
| 4064 | ✗ | vars := updateStatesVars(inVars, newStates, noStateFound); | |
| 4065 | then vars; | ||
| 4066 | end matchcontinue; | ||
| 4067 | end updateStatesVars; | ||
| 4068 | |||
| 4069 | // ============================================================================= | ||
| 4070 | // section for addedScaledVars | ||
| 4071 | // | ||
| 4072 | // ============================================================================= | ||
| 4073 | |||
| 4074 | public function addedScaledVars_states | ||
| 4075 | "added var_norm = var/nominal, where var is state." | ||
| 4076 | input BackendDAE.BackendDAE inDAE; | ||
| 4077 | output BackendDAE.BackendDAE outDAE; | ||
| 4078 | protected | ||
| 4079 | list<BackendDAE.EqSystem> systlst; | ||
| 4080 | list<BackendDAE.EqSystem> osystlst = {}; | ||
| 4081 | BackendDAE.Variables vars; | ||
| 4082 | BackendDAE.EquationArray eqns; | ||
| 4083 | list<BackendDAE.Var> lst_states; | ||
| 4084 | BackendDAE.Var tmpv; | ||
| 4085 | DAE.ComponentRef cref; | ||
| 4086 | DAE.Exp norm, y_norm, y, lhs; | ||
| 4087 | BackendDAE.Equation eqn; | ||
| 4088 | BackendDAE.Shared oshared; | ||
| 4089 | BackendDAE.EqSystem syst; | ||
| 4090 | algorithm | ||
| 4091 | 2 | BackendDAE.DAE(systlst, oshared) := inDAE; | |
| 4092 | |||
| 4093 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | for syst in systlst loop |
| 4094 | syst := match syst | ||
| 4095 | local | ||
| 4096 | BackendDAE.EqSystem syst1; | ||
| 4097 | case syst1 as BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns) | ||
| 4098 | algorithm | ||
| 4099 | // get vars | ||
| 4100 | 2 | lst_states := List.select(BackendVariable.varList(vars), BackendVariable.isStateVar); | |
| 4101 | //BackendDump.printVarList(lst_states); | ||
| 4102 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | for v in lst_states loop |
| 4103 | 2 | cref := BackendVariable.varCref(v); | |
| 4104 | 2 | tmpv := BackendVariable.createVar(cref, "__OMC$scaled_state"); | |
| 4105 | 2 | y := Expression.crefExp(cref); | |
| 4106 | 2 | norm := BackendVariable.getVarNominalValue(v); | |
| 4107 | 2 | y_norm := Expression.expDiv(y,norm); | |
| 4108 | 2 | (y_norm,_) := ExpressionSimplify.simplify(y_norm); | |
| 4109 | // lhs | ||
| 4110 | 2 | cref := BackendVariable.varCref(tmpv); | |
| 4111 | 2 | lhs := Expression.crefExp(cref); | |
| 4112 | 2 | eqn := BackendDAE.EQUATION(lhs, y_norm, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC); | |
| 4113 | //print("\n" + BackendDump.equationString(eqn)); | ||
| 4114 | 2 | eqns := BackendEquation.add(eqn, eqns); | |
| 4115 | 2 | vars := BackendVariable.addVar(tmpv, vars); | |
| 4116 | end for; | ||
| 4117 | 2 | syst1.orderedVars := vars; | |
| 4118 | 2 | syst1.orderedEqs := eqns; | |
| 4119 | 2 | then BackendDAEUtil.clearEqSyst(syst1); | |
| 4120 | end match; | ||
| 4121 | osystlst := syst::osystlst; | ||
| 4122 | end for; | ||
| 4123 | |||
| 4124 | 2 | outDAE := BackendDAE.DAE(osystlst, oshared); | |
| 4125 | end addedScaledVars_states; | ||
| 4126 | |||
| 4127 | public function addedScaledVars_inputs | ||
| 4128 | "added var_norm = var/nominal, where var is state." | ||
| 4129 | input BackendDAE.BackendDAE inDAE; | ||
| 4130 | output BackendDAE.BackendDAE outDAE; | ||
| 4131 | protected | ||
| 4132 | list<BackendDAE.EqSystem> systlst; | ||
| 4133 | list<BackendDAE.EqSystem> osystlst = {}; | ||
| 4134 | BackendDAE.Variables vars; | ||
| 4135 | BackendDAE.EquationArray eqns; | ||
| 4136 | list<BackendDAE.Var> kvarlst, lst_inputs; | ||
| 4137 | BackendDAE.Var tmpv; | ||
| 4138 | DAE.ComponentRef cref; | ||
| 4139 | DAE.Exp norm, y_norm, y, lhs; | ||
| 4140 | BackendDAE.Equation eqn; | ||
| 4141 | BackendDAE.Shared oshared; | ||
| 4142 | BackendDAE.EqSystem syst; | ||
| 4143 | algorithm | ||
| 4144 | 2 | BackendDAE.DAE(systlst, oshared) := inDAE; | |
| 4145 | 2 | kvarlst := BackendVariable.varList(oshared.globalKnownVars); | |
| 4146 | 2 | lst_inputs := List.select(kvarlst, BackendVariable.isVarOnTopLevelAndInputNoDerInput); | |
| 4147 | |||
| 4148 | //BackendDump.printVarList(lst_inputs); | ||
| 4149 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | syst :: osystlst := systlst; |
| 4150 | syst := match syst | ||
| 4151 | local | ||
| 4152 | BackendDAE.EqSystem syst1; | ||
| 4153 | case syst1 as BackendDAE.EQSYSTEM(orderedEqs=eqns, orderedVars=vars) | ||
| 4154 | algorithm | ||
| 4155 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | for v in lst_inputs loop |
| 4156 | 2 | cref := BackendVariable.varCref(v); | |
| 4157 | 2 | tmpv := BackendVariable.createVar(cref, "__OMC$scaled_input"); | |
| 4158 | 2 | y := Expression.crefExp(cref); | |
| 4159 | 2 | norm := BackendVariable.getVarNominalValue(v); | |
| 4160 | 2 | y_norm := Expression.expDiv(y,norm); | |
| 4161 | 2 | (y_norm,_) := ExpressionSimplify.simplify(y_norm); | |
| 4162 | // lhs | ||
| 4163 | 2 | cref := BackendVariable.varCref(tmpv); | |
| 4164 | 2 | lhs := Expression.crefExp(cref); | |
| 4165 | 2 | eqn := BackendDAE.EQUATION(lhs, y_norm, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC); | |
| 4166 | //print("\n" + BackendDump.equationString(eqn)); | ||
| 4167 | 2 | eqns := BackendEquation.add(eqn, eqns); | |
| 4168 | 2 | vars := BackendVariable.addVar(tmpv, vars); | |
| 4169 | end for; | ||
| 4170 | 2 | syst1.orderedEqs := eqns; | |
| 4171 | 2 | syst1.orderedVars := vars; | |
| 4172 | 2 | then BackendDAEUtil.clearEqSyst(syst1); | |
| 4173 | end match; | ||
| 4174 | osystlst := syst::osystlst; | ||
| 4175 | |||
| 4176 | 2 | outDAE := BackendDAE.DAE(osystlst, oshared); | |
| 4177 | end addedScaledVars_inputs; | ||
| 4178 | |||
| 4179 | // ============================================================================= | ||
| 4180 | // section for sortEqnsVars | ||
| 4181 | // | ||
| 4182 | // author: Vitalij Ruge | ||
| 4183 | // ============================================================================= | ||
| 4184 | |||
| 4185 | public function sortEqnsVars | ||
| 4186 | input BackendDAE.BackendDAE inDAE; | ||
| 4187 | output BackendDAE.BackendDAE outDAE = inDAE; | ||
| 4188 | protected | ||
| 4189 | list<BackendDAE.EqSystem> systlst, new_systlst = {}; | ||
| 4190 | BackendDAE.Shared shared; | ||
| 4191 | BackendDAE.Variables vars; | ||
| 4192 | BackendDAE.EquationArray eqns; | ||
| 4193 | BackendDAE.AdjacencyMatrix m; | ||
| 4194 | BackendDAE.AdjacencyMatrixT mT; | ||
| 4195 | Integer ne,nv; | ||
| 4196 | array<Integer> w_vars, w_eqns; | ||
| 4197 | AvlTreePathFunction.Tree functionTree; | ||
| 4198 | list<tuple<Integer,Integer>> tplIndexWeight; | ||
| 4199 | list<Integer> indexs; | ||
| 4200 | list<BackendDAE.Var> var_lst; | ||
| 4201 | list<BackendDAE.Equation> eqn_lst; | ||
| 4202 | algorithm | ||
| 4203 | //BackendDump.bltdump("Start", outDAE); | ||
| 4204 | ✗ | BackendDAE.DAE(systlst, shared) := inDAE; | |
| 4205 | ✗ | BackendDAE.SHARED(functionTree=functionTree) := shared; | |
| 4206 | ✗ | for syst in systlst loop | |
| 4207 | syst := match syst | ||
| 4208 | local | ||
| 4209 | BackendDAE.EqSystem syst1; | ||
| 4210 | case syst1 as BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns) | ||
| 4211 | algorithm | ||
| 4212 | ✗ | (_, m, mT) := BackendDAEUtil.getAdjacencyMatrix(syst, BackendDAE.ABSOLUTE(), SOME(functionTree), BackendDAEUtil.isInitializationDAE(shared)); | |
| 4213 | //debug | ||
| 4214 | ✗ | if Flags.isSet(Flags.SORT_EQNS_AND_VARS) then | |
| 4215 | ✗ | BackendDump.dumpAdjacencyMatrix(m); | |
| 4216 | ✗ | BackendDump.dumpAdjacencyMatrixT(mT); | |
| 4217 | end if; | ||
| 4218 | |||
| 4219 | ✗ | BackendDAE.VARIABLES(varArr = BackendDAE.VARIABLE_ARRAY(numberOfElements = nv)) := vars; | |
| 4220 | ✗ | ne := ExpandableArray.getNumberOfElements(eqns); | |
| 4221 | //init weights | ||
| 4222 | ✗ | w_vars := arrayCreate(nv, -1); | |
| 4223 | ✗ | w_eqns := arrayCreate(ne, -1); | |
| 4224 | //weights vars, TODO: improve me! | ||
| 4225 | ✗ | sortEqnsVarsWeights(w_vars, nv, mT); | |
| 4226 | //weights eqns, TODO: improve me! | ||
| 4227 | ✗ | sortEqnsVarsWeights(w_eqns, ne, m); | |
| 4228 | //sort vars | ||
| 4229 | ✗ | tplIndexWeight := list((i, w_vars[i]) for i in 1:nv); | |
| 4230 | //sorted vars | ||
| 4231 | ✗ | tplIndexWeight := List.sort(tplIndexWeight, Util.compareTuple2IntLt); | |
| 4232 | //new order vars indexs | ||
| 4233 | ✗ | indexs := sortEqnsVarsWorkTpl(tplIndexWeight); | |
| 4234 | ✗ | var_lst := list(BackendVariable.getVarAt(vars, i) for i in indexs); | |
| 4235 | // new vars | ||
| 4236 | ✗ | vars := BackendVariable.listVar1(var_lst); | |
| 4237 | //sort eqns | ||
| 4238 | ✗ | tplIndexWeight := list((i, w_eqns[i]) for i in 1:ne); | |
| 4239 | //sorted eqns | ||
| 4240 | ✗ | tplIndexWeight := List.sort(tplIndexWeight, Util.compareTuple2IntGt); | |
| 4241 | //new order eqns indexs | ||
| 4242 | ✗ | indexs := sortEqnsVarsWorkTpl(tplIndexWeight); | |
| 4243 | ✗ | eqn_lst := list(BackendEquation.get(eqns, i) for i in indexs); | |
| 4244 | //new eqns | ||
| 4245 | ✗ | eqns := BackendEquation.listEquation(eqn_lst); | |
| 4246 | ✗ | syst1.orderedEqs := eqns; | |
| 4247 | ✗ | syst1.orderedVars := vars; | |
| 4248 | |||
| 4249 | //debug | ||
| 4250 | ✗ | if Flags.isSet(Flags.SORT_EQNS_AND_VARS) then | |
| 4251 | ✗ | (_, m, mT) := BackendDAEUtil.getAdjacencyMatrix(syst1, BackendDAE.ABSOLUTE(), SOME(functionTree), BackendDAEUtil.isInitializationDAE(shared)); | |
| 4252 | ✗ | BackendDump.dumpAdjacencyMatrix(m); | |
| 4253 | ✗ | BackendDump.dumpAdjacencyMatrixT(mT); | |
| 4254 | end if; | ||
| 4255 | |||
| 4256 | ✗ | GCExt.free(w_vars); | |
| 4257 | ✗ | GCExt.free(w_eqns); | |
| 4258 | ✗ | then BackendDAEUtil.clearEqSyst(syst1); | |
| 4259 | end match; | ||
| 4260 | new_systlst := syst :: new_systlst; | ||
| 4261 | end for; //syst | ||
| 4262 | |||
| 4263 | ✗ | outDAE:= BackendDAE.DAE(new_systlst, shared); | |
| 4264 | //BackendDump.bltdump("End", outDAE); | ||
| 4265 | end sortEqnsVars; | ||
| 4266 | |||
| 4267 | protected function sortEqnsVarsWorkTpl | ||
| 4268 | input list<tuple<Integer,Integer>> tplIndexWeight; | ||
| 4269 | output list<Integer> outIndexs; | ||
| 4270 | algorithm | ||
| 4271 | ✗ | outIndexs := list(Util.tuple21(elem) for elem in tplIndexWeight); | |
| 4272 | end sortEqnsVarsWorkTpl; | ||
| 4273 | |||
| 4274 | protected function sortEqnsVarsWeights | ||
| 4275 | input array<Integer> inW; | ||
| 4276 | input Integer n; | ||
| 4277 | input BackendDAE.AdjacencyMatrix m; | ||
| 4278 | output array<Integer> outW = inW; | ||
| 4279 | protected | ||
| 4280 | Integer i; | ||
| 4281 | algorithm | ||
| 4282 | ✗ | for i in 1:n loop | |
| 4283 | ✗ | outW[i] := listLength(m[i]); | |
| 4284 | end for; | ||
| 4285 | end sortEqnsVarsWeights; | ||
| 4286 | |||
| 4287 | // ============================================================================= | ||
| 4288 | // fix some bugs for complex function | ||
| 4289 | // | ||
| 4290 | // e.g. (a,-b) = f(.) -> (a,c) = f(.) with c = -b | ||
| 4291 | // (a,b) = (c,d) -> a=c and b = d | ||
| 4292 | // {a,b} = {c,d} -> a=c and b = d | ||
| 4293 | // (a,b) = f(a) fixed iterration var | ||
| 4294 | // author: Vitalij Ruge | ||
| 4295 | // ============================================================================= | ||
| 4296 | |||
| 4297 | |||
| 4298 | public function simplifyComplexFunction | ||
| 4299 | input BackendDAE.BackendDAE inDAE; | ||
| 4300 | output BackendDAE.BackendDAE outDAE; | ||
| 4301 | algorithm | ||
| 4302 | 2190 | outDAE := simplifyComplexFunction1(inDAE, true); | |
| 4303 | end simplifyComplexFunction; | ||
| 4304 | |||
| 4305 | public function simplifyComplexFunction1 | ||
| 4306 | input BackendDAE.BackendDAE inDAE; | ||
| 4307 | input Boolean withTmpVars = false; | ||
| 4308 | output BackendDAE.BackendDAE outDAE = inDAE; | ||
| 4309 | protected | ||
| 4310 | list<BackendDAE.EqSystem> systlst = {}; | ||
| 4311 | BackendDAE.Shared shared; | ||
| 4312 | BackendDAE.EquationArray eqns; | ||
| 4313 | BackendDAE.Variables vars; | ||
| 4314 | Integer n, size, idx = 1, m, j; | ||
| 4315 | BackendDAE.Equation eqn = BackendDAE.DUMMY_EQUATION(), eqn1; | ||
| 4316 | DAE.Exp left, right, e1, e2, e, e3; | ||
| 4317 | list<DAE.Exp> left_lst, right_lst; | ||
| 4318 | list<Integer> indRemove; | ||
| 4319 | DAE.ElementSource source "origin of equation"; | ||
| 4320 | BackendDAE.EquationAttributes attr; | ||
| 4321 | Boolean update, sc; | ||
| 4322 | Absyn.Path path; | ||
| 4323 | list<DAE.Exp> arrayLst, arrayLst2, expLst; | ||
| 4324 | DAE.CallAttributes cattr; | ||
| 4325 | DAE.ComponentRef cr; | ||
| 4326 | BackendDAE.Var tmpvar; | ||
| 4327 | String tmpVarPrefix; | ||
| 4328 | algorithm | ||
| 4329 | 2198 | shared := inDAE.shared; | |
| 4330 | tmpVarPrefix := match shared | ||
| 4331 | case BackendDAE.SHARED(backendDAEType=BackendDAE.SIMULATION()) then "$OMC$CF$sim"; | ||
| 4332 | case BackendDAE.SHARED(backendDAEType=BackendDAE.INITIALSYSTEM()) then "$OMC$CF$init"; | ||
| 4333 | else "$OMC$CF$unknown"; | ||
| 4334 | end match; | ||
| 4335 | |||
| 4336 |
2/2✓ Branch 0 taken 51506 times.
✓ Branch 1 taken 2198 times.
|
53704 | for syst in inDAE.eqs loop |
| 4337 | 51506 | BackendDAE.EQSYSTEM(orderedVars=vars,orderedEqs=eqns) := syst; | |
| 4338 | 51506 | n := ExpandableArray.getNumberOfElements(eqns); | |
| 4339 | update := false; | ||
| 4340 | indRemove := {}; | ||
| 4341 | |||
| 4342 |
2/2✓ Branch 0 taken 51398 times.
✓ Branch 1 taken 108 times.
|
235563 | for i in 1:n loop |
| 4343 | try | ||
| 4344 | 184057 | eqn := BackendEquation.get(eqns, i); | |
| 4345 | else | ||
| 4346 | ✗ | continue; | |
| 4347 | end try; | ||
| 4348 |
4/4✓ Branch 1 taken 182836 times.
✓ Branch 2 taken 1221 times.
✓ Branch 4 taken 563 times.
✓ Branch 5 taken 182273 times.
|
184057 | if BackendEquation.isComplexEquation(eqn) or BackendEquation.isArrayEquation(eqn) then |
| 4349 |
2/2✓ Branch 1 taken 1221 times.
✓ Branch 2 taken 563 times.
|
1784 | if BackendEquation.isComplexEquation(eqn) then |
| 4350 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1221 times.
|
1221 | BackendDAE.COMPLEX_EQUATION(size=size,left=left, right=right, attr= attr, source=source) := eqn; |
| 4351 | else | ||
| 4352 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 563 times.
|
563 | BackendDAE.ARRAY_EQUATION(left=left, right=right, attr= attr, source=source) := eqn; |
| 4353 | end if; | ||
| 4354 | |||
| 4355 |
4/4✓ Branch 1 taken 518 times.
✓ Branch 2 taken 1266 times.
✓ Branch 4 taken 27 times.
✓ Branch 5 taken 491 times.
|
1784 | if Expression.isTuple(left) and Expression.isTuple(right) then // tuple() = tuple() |
| 4356 | //print(BackendDump.equationString(eqn) + "--In--\n"); | ||
| 4357 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
|
27 | DAE.TUPLE(PR = left_lst) := left; |
| 4358 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
|
27 | DAE.TUPLE(PR = right_lst) := right; |
| 4359 | 27 | update := true; | |
| 4360 | 27 | indRemove := i :: indRemove; | |
| 4361 |
2/2✓ Branch 0 taken 55 times.
✓ Branch 1 taken 27 times.
|
82 | for e1 in left_lst loop |
| 4362 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
|
55 | e2 :: right_lst := right_lst; |
| 4363 | //print("=>" + ExpressionBasics.printExpStr(e2) + " = " + ExpressionBasics.printExpStr(e1) + "\n"); | ||
| 4364 |
2/2✓ Branch 1 taken 52 times.
✓ Branch 2 taken 3 times.
|
55 | if not Expression.isWild(e1) then |
| 4365 |
2/2✓ Branch 1 taken 50 times.
✓ Branch 2 taken 2 times.
|
52 | if Expression.isScalar(e2) then |
| 4366 | 50 | eqn1 := BackendEquation.generateEquation(e1, e2, source, attr); | |
| 4367 | 50 | eqns := BackendEquation.add(eqn1, eqns); | |
| 4368 | //print(BackendDump.equationString(eqn1) + "--new--\n"); | ||
| 4369 | else | ||
| 4370 | 2 | expLst := simplifyComplexFunction2(e1); | |
| 4371 | 2 | arrayLst := simplifyComplexFunction2(e2); | |
| 4372 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
|
5 | for e_asub in arrayLst loop |
| 4373 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | e3 :: expLst := expLst; |
| 4374 | 3 | eqn1 := BackendEquation.generateEquation(e_asub, e3, source, attr); | |
| 4375 | 3 | eqns := BackendEquation.add(eqn1, eqns); | |
| 4376 | //print(BackendDump.equationString(eqn1) + "--new--\n"); | ||
| 4377 | end for; | ||
| 4378 | end if; //isScalar | ||
| 4379 | end if; // isWild | ||
| 4380 | end for; | ||
| 4381 | elseif Expression.isArray(left) and Expression.isArray(right) | ||
| 4382 | then // array{} = array{} // not work with arrayType | ||
| 4383 | //print(BackendDump.equationString(eqn) + "--In--\n"); | ||
| 4384 | try | ||
| 4385 | 5 | left_lst := Expression.getArrayOrRangeContents(left); | |
| 4386 | 5 | right_lst := Expression.getArrayOrRangeContents(right); | |
| 4387 | 5 | update := true; | |
| 4388 | 5 | indRemove := i :: indRemove; | |
| 4389 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 5 times.
|
20 | for e1 in left_lst loop |
| 4390 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
|
15 | e2 :: right_lst := right_lst; |
| 4391 | //print("=>" + ExpressionBasics.printExpStr(e2) + " = " + ExpressionBasics.printExpStr(e1) + "\n"); | ||
| 4392 |
1/2✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
|
15 | if not Expression.isWild(e1) then |
| 4393 |
1/2✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
|
15 | if Expression.isScalar(e2) then |
| 4394 | 15 | eqn1 := BackendEquation.generateEquation(e1, e2, source, attr); | |
| 4395 | 15 | eqns := BackendEquation.add(eqn1, eqns); | |
| 4396 | //print(BackendDump.equationString(eqn1) + "--new--\n"); | ||
| 4397 | else | ||
| 4398 | ✗ | expLst := simplifyComplexFunction2(e1); | |
| 4399 | ✗ | arrayLst := simplifyComplexFunction2(e2); | |
| 4400 | ✗ | for e_asub in arrayLst loop | |
| 4401 | ✗ | e3 :: expLst := expLst; | |
| 4402 | ✗ | eqn1 := BackendEquation.generateEquation(e_asub, e3, source, attr); | |
| 4403 | ✗ | eqns := BackendEquation.add(eqn1, eqns); | |
| 4404 | //print(BackendDump.equationString(eqn1) + "--new--\n"); | ||
| 4405 | end for; | ||
| 4406 | end if; //isScalar | ||
| 4407 | end if; // isWild | ||
| 4408 | end for; | ||
| 4409 | else | ||
| 4410 | ✗ | continue; | |
| 4411 | end try; | ||
| 4412 | elseif withTmpVars and Expression.isTuple(left) and Expression.isCall(right) //tuple() = call() | ||
| 4413 | then | ||
| 4414 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 491 times.
|
491 | DAE.TUPLE(PR = left_lst) := left; |
| 4415 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 491 times.
|
491 | DAE.CALL(path=path,expLst = expLst, attr= cattr) := right; |
| 4416 | expLst := {}; | ||
| 4417 |
2/2✓ Branch 0 taken 2880 times.
✓ Branch 1 taken 491 times.
|
3371 | for e1 in left_lst loop |
| 4418 |
2/2✓ Branch 1 taken 2868 times.
✓ Branch 2 taken 12 times.
|
2880 | if Expression.isCref(e1) then |
| 4419 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2868 times.
|
2868 | DAE.CREF(componentRef = cr) := e1; |
| 4420 |
2/2✓ Branch 1 taken 1 time.
✓ Branch 2 taken 2867 times.
|
2868 | if Expression.expHasCrefNoPreOrStart(right, cr) then |
| 4421 | 1 | update := true; | |
| 4422 | 1 | cr := ComponentReferenceBasics.makeCrefIdent(tmpVarPrefix + intString(idx), Expression.typeof(e1) , {}); | |
| 4423 | 1 | idx := idx + 1; | |
| 4424 | 1 | e := Expression.crefExp(cr); | |
| 4425 | 1 | tmpvar := BackendVariable.makeVar(cr); | |
| 4426 | 1 | tmpvar := BackendVariable.setVarTS(tmpvar,SOME(BackendDAE.AVOID())); | |
| 4427 | 1 | vars := BackendVariable.addVar(tmpvar, vars); | |
| 4428 | |||
| 4429 | 1 | eqn1 := BackendDAE.EQUATION(e, e1, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC); | |
| 4430 | 1 | eqns := BackendEquation.add(eqn1, eqns); | |
| 4431 | else | ||
| 4432 | e := e1; | ||
| 4433 | end if; | ||
| 4434 | elseif Expression.isUnaryCref(e1) then | ||
| 4435 | ✗ | update := true; | |
| 4436 | ✗ | cr := ComponentReferenceBasics.makeCrefIdent(tmpVarPrefix + intString(idx), Expression.typeof(e1) , {}); | |
| 4437 | ✗ | idx := idx + 1; | |
| 4438 | ✗ | e := Expression.crefExp(cr); | |
| 4439 | ✗ | tmpvar := BackendVariable.makeVar(cr); | |
| 4440 | ✗ | tmpvar := BackendVariable.setVarTS(tmpvar,SOME(BackendDAE.AVOID())); | |
| 4441 | ✗ | vars := BackendVariable.addVar(tmpvar, vars); | |
| 4442 | ✗ | eqn1 := BackendDAE.EQUATION(e, e1, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC); | |
| 4443 | //print(BackendDump.equationString(eqn1) + "--new--\n"); | ||
| 4444 | ✗ | eqns := BackendEquation.add(eqn1, eqns); | |
| 4445 | elseif Expression.isArray(e1) then | ||
| 4446 | ✗ | update := true; | |
| 4447 | ✗ | DAE.ARRAY(array=arrayLst, scalar=sc) := e1; | |
| 4448 | ✗ | m := listLength(arrayLst); | |
| 4449 | ✗ | cr := ComponentReferenceBasics.makeCrefIdent(tmpVarPrefix + intString(idx), Expression.typeof(e1) , {}); | |
| 4450 | ✗ | idx := idx + 1; | |
| 4451 | ✗ | e := Expression.crefExp(cr); | |
| 4452 | ✗ | tmpvar := BackendVariable.makeVar(cr); | |
| 4453 | ✗ | tmpvar := BackendVariable.setVarTS(tmpvar,SOME(BackendDAE.AVOID())); | |
| 4454 | ✗ | tmpvar.arryDim := {DAE.DIM_INTEGER(m)}; | |
| 4455 | // e[1] | ||
| 4456 | ✗ | arrayLst2 := list( Expression.makeAsubAddIndex(e,k) for k in 1:m); | |
| 4457 | j := 1; | ||
| 4458 | ✗ | for e2 in arrayLst2 loop | |
| 4459 | ✗ | e3 :: arrayLst := arrayLst; | |
| 4460 | ✗ | eqn1 := BackendDAE.EQUATION(e2, e3, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC); | |
| 4461 | //print(BackendDump.equationString(eqn1) + "--new--\n"); | ||
| 4462 | ✗ | eqns := BackendEquation.add(eqn1, eqns); | |
| 4463 | ✗ | cr := ComponentReferenceBasics.makeCrefIdent(tmpVarPrefix + intString(idx-1), Expression.typeof(e1) , {DAE.INDEX(DAE.ICONST(j))}); | |
| 4464 | ✗ | j := j + 1; | |
| 4465 | ✗ | tmpvar.varName := cr; | |
| 4466 | ✗ | vars := BackendVariable.addVar(tmpvar, vars); | |
| 4467 | //vars := BackendVariable.addVar(tmpvar, vars); | ||
| 4468 | end for; | ||
| 4469 | //BackendDump.printVariables(vars); | ||
| 4470 | else | ||
| 4471 | e := e1; | ||
| 4472 | end if; | ||
| 4473 | expLst := e :: expLst; | ||
| 4474 | end for; // lhs | ||
| 4475 | 491 | left := DAE.TUPLE(MetaModelica.Dangerous.listReverseInPlace(expLst)); | |
| 4476 | 491 | eqn := BackendEquation.generateEquation(left, right, source, attr); | |
| 4477 | 491 | eqns := BackendEquation.setAtIndex(eqns, i, eqn); | |
| 4478 | end if; // lhs <-> rhs | ||
| 4479 | end if; // complex | ||
| 4480 | end for; //1:n | ||
| 4481 | |||
| 4482 | |||
| 4483 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 51488 times.
|
51506 | if update then |
| 4484 |
2/2✓ Branch 1 taken 32 times.
✓ Branch 2 taken 18 times.
|
50 | for i in listReverse(indRemove) loop |
| 4485 | //print("\neqns:" + intString(i) + "\n"); | ||
| 4486 | //BackendDump.printEquationArray(eqns); | ||
| 4487 | 32 | eqns := BackendEquation.delete(i,eqns); | |
| 4488 | end for; | ||
| 4489 | 18 | eqns := BackendEquation.listEquation(BackendEquation.equationList(eqns)); | |
| 4490 | 18 | systlst := BackendDAEUtil.createEqSystem(vars, eqns, syst.stateSets, syst.partitionKind, syst.removedEqs) :: systlst; | |
| 4491 | else | ||
| 4492 | systlst := syst :: systlst; | ||
| 4493 | end if; | ||
| 4494 | end for; // syst | ||
| 4495 | |||
| 4496 | 2198 | outDAE.eqs := systlst; | |
| 4497 | end simplifyComplexFunction1; | ||
| 4498 | |||
| 4499 | function simplifyComplexFunction2 | ||
| 4500 | input DAE.Exp e1; | ||
| 4501 | output list<DAE.Exp> out_lst_e1 = {}; | ||
| 4502 | protected | ||
| 4503 | list<DAE.Exp> lst_e; | ||
| 4504 | algorithm | ||
| 4505 | try | ||
| 4506 |
3/4✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 8 times.
|
10 | if Expression.isArray(e1) or Expression.isArrayType(Expression.typeof(e1)) then |
| 4507 | 2 | lst_e := Expression.getArrayOrRangeContents(e1); | |
| 4508 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
|
6 | for e in lst_e loop |
| 4509 | 4 | out_lst_e1 := listAppend(simplifyComplexFunction2(e),out_lst_e1); | |
| 4510 | end for; | ||
| 4511 | elseif Expression.isRecord(e1) then | ||
| 4512 | 2 | lst_e := Expression.splitRecord(e1, Expression.typeof(e1)); | |
| 4513 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | for e in lst_e loop |
| 4514 | 2 | out_lst_e1 := listAppend(simplifyComplexFunction2(e),out_lst_e1); | |
| 4515 | end for; | ||
| 4516 | out_lst_e1 := {e1}; | ||
| 4517 | else | ||
| 4518 | out_lst_e1 := {e1}; | ||
| 4519 | end if; | ||
| 4520 | else | ||
| 4521 | out_lst_e1 := {e1}; | ||
| 4522 | end try; | ||
| 4523 | |||
| 4524 | end simplifyComplexFunction2; | ||
| 4525 | |||
| 4526 | // ============================================================================= | ||
| 4527 | // section for hets | ||
| 4528 | // | ||
| 4529 | // (h)euristic (e)quation (t)erms (s)ort | ||
| 4530 | // heuristic sorting of terms for better numeric in equations(res, torn,...) | ||
| 4531 | // | ||
| 4532 | // author: Vitalij Ruge | ||
| 4533 | // ============================================================================= | ||
| 4534 | |||
| 4535 | public function hets | ||
| 4536 | input BackendDAE.BackendDAE inDAE; | ||
| 4537 | output BackendDAE.BackendDAE outDAE; | ||
| 4538 | algorithm | ||
| 4539 | ✗ | if Flags.getConfigString(Flags.HETS)<> "none" then | |
| 4540 | ✗ | outDAE := hetsWork(inDAE); | |
| 4541 | else | ||
| 4542 | outDAE := inDAE; | ||
| 4543 | end if; | ||
| 4544 | end hets; | ||
| 4545 | |||
| 4546 | protected function hetsWork | ||
| 4547 | input BackendDAE.BackendDAE inDAE; | ||
| 4548 | output BackendDAE.BackendDAE outDAE = inDAE; | ||
| 4549 | protected | ||
| 4550 | BackendDAE.EquationArray eqns; | ||
| 4551 | BackendDAE.Variables vars; | ||
| 4552 | BackendDAE.Matching matching; | ||
| 4553 | BackendDAE.StateSets stateSets; | ||
| 4554 | BackendDAE.BaseClockPartitionKind partitionKind; | ||
| 4555 | BackendDAE.InnerEquations innerEquations; | ||
| 4556 | BackendDAE.InnerEquation innerEquation; | ||
| 4557 | Integer i,j; | ||
| 4558 | BackendDAE.Equation eqn; | ||
| 4559 | list<Integer> tvars "be careful with states, this are solved for der(x)"; | ||
| 4560 | list<Integer> teqns; | ||
| 4561 | DAE.ComponentRef cr; | ||
| 4562 | BackendDAE.StrongComponents comps; | ||
| 4563 | BackendDAE.Shared shared; | ||
| 4564 | algorithm | ||
| 4565 | ✗ | shared := outDAE.shared; | |
| 4566 | ✗ | for syst in outDAE.eqs loop | |
| 4567 | ✗ | BackendDAE.EQSYSTEM(orderedVars=vars,orderedEqs=eqns,matching=matching as BackendDAE.MATCHING(comps=comps),stateSets=stateSets,partitionKind=partitionKind) := syst; | |
| 4568 | |||
| 4569 | ✗ | for comp in comps loop | |
| 4570 | ✗ | if BackendEquation.isTornSystem(comp) then | |
| 4571 | |||
| 4572 | ✗ | BackendDAE.TORNSYSTEM(strictTearingSet = BackendDAE.TEARINGSET(tearingvars=tvars, residualequations=teqns, innerEquations = innerEquations)) := comp; | |
| 4573 | ✗ | for innerEquation in innerEquations loop | |
| 4574 | try | ||
| 4575 | ✗ | (i,{j},_) := BackendDAEUtil.getEqnAndVarsFromInnerEquation(innerEquation); | |
| 4576 | ✗ | eqn := BackendEquation.get(eqns, i); | |
| 4577 | ✗ | BackendDAE.VAR(varName = cr) := BackendVariable.getVarAt(vars, j); | |
| 4578 | ✗ | eqn := BackendEquation.solveEquation(eqn, Expression.crefExp(cr), SOME(shared.functionTree)); | |
| 4579 | ✗ | eqn := hetsSplitRhs(eqn); | |
| 4580 | ✗ | eqns := BackendEquation.setAtIndex(eqns, i, eqn); | |
| 4581 | else | ||
| 4582 | end try; | ||
| 4583 | end for; | ||
| 4584 | |||
| 4585 | ✗ | for i in teqns loop | |
| 4586 | ✗ | eqn := BackendEquation.get(eqns, i); | |
| 4587 | ✗ | eqn := hetsSplitRes(eqn); | |
| 4588 | ✗ | eqns := BackendEquation.setAtIndex(eqns, i, eqn); | |
| 4589 | end for; | ||
| 4590 | elseif BackendEquation.isEquationsSystem(comp) then | ||
| 4591 | ✗ | BackendDAE.EQUATIONSYSTEM(eqns=teqns) := comp; | |
| 4592 | ✗ | for i in teqns loop | |
| 4593 | ✗ | eqn := BackendEquation.get(eqns, i); | |
| 4594 | ✗ | eqn := hetsSplitRes(eqn); | |
| 4595 | ✗ | eqns := BackendEquation.setAtIndex(eqns, i, eqn); | |
| 4596 | end for; | ||
| 4597 | end if; | ||
| 4598 | end for; | ||
| 4599 | end for; | ||
| 4600 | end hetsWork; | ||
| 4601 | |||
| 4602 | function hetsSplitRes | ||
| 4603 | input BackendDAE.Equation iEqn; | ||
| 4604 | output BackendDAE.Equation oEqn; | ||
| 4605 | |||
| 4606 | algorithm | ||
| 4607 | oEqn := match iEqn | ||
| 4608 | local DAE.Exp e1,e2, e; | ||
| 4609 | DAE.ElementSource source; | ||
| 4610 | BackendDAE.EquationAttributes attr; | ||
| 4611 | |||
| 4612 | case BackendDAE.EQUATION(exp=e1, scalar=e2, source=source, attr=attr) | ||
| 4613 | algorithm | ||
| 4614 | ✗ | e := Expression.createResidualExp(e1, e2); | |
| 4615 | ✗ | e := hetsSplitExp(e); | |
| 4616 | ✗ | then BackendDAE.RESIDUAL_EQUATION(e, source, attr); | |
| 4617 | |||
| 4618 | case BackendDAE.RESIDUAL_EQUATION(e, source, attr) | ||
| 4619 | algorithm | ||
| 4620 | ✗ | e := hetsSplitExp(e); | |
| 4621 | ✗ | then BackendDAE.RESIDUAL_EQUATION(e, source, attr); | |
| 4622 | |||
| 4623 | else iEqn; | ||
| 4624 | end match; | ||
| 4625 | end hetsSplitRes; | ||
| 4626 | |||
| 4627 | function hetsSplitRhs | ||
| 4628 | input BackendDAE.Equation iEqn; | ||
| 4629 | output BackendDAE.Equation oEqn; | ||
| 4630 | |||
| 4631 | algorithm | ||
| 4632 | oEqn := match iEqn | ||
| 4633 | local DAE.Exp e1,e2; | ||
| 4634 | DAE.ElementSource source; | ||
| 4635 | BackendDAE.EquationAttributes attr; | ||
| 4636 | |||
| 4637 | case BackendDAE.EQUATION(exp=e1, scalar=e2, source=source, attr=attr) | ||
| 4638 | algorithm | ||
| 4639 | ✗ | e2 := hetsSplitExp(e2); | |
| 4640 | ✗ | then BackendDAE.EQUATION(e1, e2, source, attr); | |
| 4641 | |||
| 4642 | else iEqn; | ||
| 4643 | end match; | ||
| 4644 | end hetsSplitRhs; | ||
| 4645 | |||
| 4646 | function hetsSplitExp | ||
| 4647 | input DAE.Exp iExp; | ||
| 4648 | output DAE.Exp oExp; | ||
| 4649 | algorithm | ||
| 4650 | oExp := match iExp | ||
| 4651 | local DAE.Exp e,e1,e2; DAE.Operator op; | ||
| 4652 | list<DAE.Exp> terms, termsDer; | ||
| 4653 | |||
| 4654 | case DAE.BINARY(e1, op, e2) | ||
| 4655 | guard Expression.isMulOrDiv(op) | ||
| 4656 | algorithm | ||
| 4657 | ✗ | e1 := hetsSplitExp(e1); | |
| 4658 | ✗ | e2 := hetsSplitExp(e2); | |
| 4659 | ✗ | then DAE.BINARY(e1, op, e2); | |
| 4660 | |||
| 4661 | case e as DAE.BINARY(_, op, _) | ||
| 4662 | guard Expression.isAddOrSub(op) | ||
| 4663 | algorithm | ||
| 4664 | ✗ | terms := Expression.terms(e); | |
| 4665 | ✗ | terms := list(hetsSplitExp(t) for t in terms); | |
| 4666 | ✗ | (termsDer, terms) := List.splitOnTrue(terms, Expression.expHasDer); | |
| 4667 | ✗ | then Expression.expAdd(Expression.makeSum1(terms), Expression.makeSum1(termsDer)); | |
| 4668 | else iExp; | ||
| 4669 | end match; | ||
| 4670 | end hetsSplitExp; | ||
| 4671 | |||
| 4672 | // ============================================================================= | ||
| 4673 | // section inlineFunctionInLoops | ||
| 4674 | // force inlining function of loop | ||
| 4675 | // author: Vitalij Ruge | ||
| 4676 | // motivation see #3997 library devs introduce annotation(Inline=true) for simplify loops | ||
| 4677 | // ============================================================================= | ||
| 4678 | public function inlineFunctionInLoops | ||
| 4679 | input output BackendDAE.BackendDAE dae; | ||
| 4680 | algorithm | ||
| 4681 | 4 | dae := inlineFunctionInLoopsMain(dae); | |
| 4682 | end inlineFunctionInLoops; | ||
| 4683 | |||
| 4684 | protected function inlineFunctionInLoopsMain | ||
| 4685 | input BackendDAE.BackendDAE inDAE; | ||
| 4686 | output BackendDAE.BackendDAE outDAE; | ||
| 4687 | protected | ||
| 4688 | BackendDAE.Shared shared; | ||
| 4689 | AvlTreePathFunction.Tree functionTree; | ||
| 4690 | BackendDAE.EqSystems eqs; | ||
| 4691 | BackendDAE.EqSystem _syst; | ||
| 4692 | algorithm | ||
| 4693 | 4 | shared := inDAE.shared; | |
| 4694 | 4 | functionTree := shared.functionTree; | |
| 4695 | eqs := {}; | ||
| 4696 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
|
8 | for syst in inDAE.eqs loop |
| 4697 | 4 | (_syst, shared) := inlineFunctionInLoopsWork(syst, functionTree, shared); | |
| 4698 | eqs := _syst :: eqs; | ||
| 4699 | end for; | ||
| 4700 | 4 | outDAE := BackendDAE.DAE(eqs, shared); | |
| 4701 | end inlineFunctionInLoopsMain; | ||
| 4702 | |||
| 4703 | protected function inlineFunctionInLoopsWork | ||
| 4704 | input output BackendDAE.EqSystem syst; | ||
| 4705 | input AvlTreePathFunction.Tree functionTree; | ||
| 4706 | input output BackendDAE.Shared shared; | ||
| 4707 | protected | ||
| 4708 | BackendDAE.Variables vars; | ||
| 4709 | BackendDAE.EquationArray eqns; | ||
| 4710 | BackendDAE.BaseClockPartitionKind partitionKind; | ||
| 4711 | BackendDAE.StateSets stateSets; | ||
| 4712 | BackendDAE.StrongComponents comps; | ||
| 4713 | BackendDAE.Matching matching; | ||
| 4714 | BackendDAE.StateSets stateSets; | ||
| 4715 | Inline.Functiontuple fns = (SOME(functionTree),{DAE.NORM_INLINE(),DAE.AFTER_INDEX_RED_INLINE(), DAE.DEFAULT_INLINE()}); | ||
| 4716 | Boolean inlined; | ||
| 4717 | BackendDAE.Equation eq, eqNew; | ||
| 4718 | BackendDAE.EqSystem tmpEqs, tmpEqs1; | ||
| 4719 | list<Integer> idEqns; | ||
| 4720 | Boolean inlined1; | ||
| 4721 | Integer id; | ||
| 4722 | algorithm | ||
| 4723 | 4 | inlined := false; | |
| 4724 | inlined1 := false; | ||
| 4725 | 4 | tmpEqs1 := BackendDAEUtil.createEqSystem( BackendVariable.listVar({}), BackendEquation.listEquation({})); | |
| 4726 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | BackendDAE.EQSYSTEM(orderedVars=vars,orderedEqs=eqns,matching=matching as BackendDAE.MATCHING(comps=comps),stateSets=stateSets,partitionKind=partitionKind) := syst; |
| 4727 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
|
12 | for comp in comps |
| 4728 | loop | ||
| 4729 | if BackendEquation.isEquationsSystem(comp) or BackendEquation.isTornSystem(comp) or | ||
| 4730 | (match comp case BackendDAE.SINGLECOMPLEXEQUATION() then true; else false; end match) | ||
| 4731 | then | ||
| 4732 | idEqns := match comp | ||
| 4733 | case BackendDAE.EQUATIONSYSTEM(eqns=idEqns) then idEqns; | ||
| 4734 | case BackendDAE.SINGLECOMPLEXEQUATION(eqn = id) then {id}; | ||
| 4735 | end match; | ||
| 4736 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
|
12 | for id in idEqns |
| 4737 | loop | ||
| 4738 | 8 | eq := BackendEquation.get(eqns, id); | |
| 4739 | //eqn := BackendInline.inlineEqOpt(SOME(eq), fns); | ||
| 4740 | //eqns := BackendEquation.setAtIndexFirst(id, eq, eqns); | ||
| 4741 | 8 | (eqNew, tmpEqs, inlined, shared) := BackendInline.inlineEqAppend_debug(eq, fns, shared); | |
| 4742 |
2/4✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
|
8 | if inlined or not BackendEquation.equationEqual(eq, eqNew) |
| 4743 | then | ||
| 4744 | 8 | tmpEqs1 := BackendDAEUtil.mergeEqSystems(tmpEqs, tmpEqs1); | |
| 4745 | 8 | eqns := BackendEquation.setAtIndexFirst(id, eqNew, eqns); | |
| 4746 | //BackendDump.printEquation(BackendEquation.get(eqns, id)); | ||
| 4747 | inlined1 := true; | ||
| 4748 | end if; | ||
| 4749 | end for; | ||
| 4750 | end if; | ||
| 4751 | end for; | ||
| 4752 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | syst.orderedEqs := eqns; |
| 4753 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if inlined1 then |
| 4754 | 4 | syst := BackendDAEUtil.clearEqSyst(syst); | |
| 4755 | 4 | syst := BackendDAEUtil.mergeEqSystems(tmpEqs1, syst); | |
| 4756 | end if; | ||
| 4757 | end inlineFunctionInLoopsWork; | ||
| 4758 | |||
| 4759 | // ============================================================================= | ||
| 4760 | // section for simplifyLoops | ||
| 4761 | // | ||
| 4762 | // simplify(hopful) loops for simulation/optimization | ||
| 4763 | // author: Vitalij Ruge | ||
| 4764 | // ============================================================================= | ||
| 4765 | |||
| 4766 | public function simplifyLoops | ||
| 4767 | input BackendDAE.BackendDAE inDAE; | ||
| 4768 | output BackendDAE.BackendDAE outDAE; | ||
| 4769 | algorithm | ||
| 4770 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | outDAE := if Flags.getConfigInt(Flags.SIMPLIFY_LOOPS) > 0 then simplifyLoopsMain(inDAE) else inDAE; |
| 4771 | end simplifyLoops; | ||
| 4772 | |||
| 4773 | protected function simplifyLoopsMain | ||
| 4774 | input BackendDAE.BackendDAE inDAE; | ||
| 4775 | output BackendDAE.BackendDAE outDAE = inDAE; | ||
| 4776 | protected | ||
| 4777 | list<BackendDAE.EqSystem> new_systlst = {}; | ||
| 4778 | BackendDAE.Shared shared; | ||
| 4779 | BackendDAE.Variables vars; | ||
| 4780 | BackendDAE.EquationArray eqns; | ||
| 4781 | BackendDAE.BaseClockPartitionKind partitionKind; | ||
| 4782 | BackendDAE.StateSets stateSets; | ||
| 4783 | BackendDAE.StrongComponents comps; | ||
| 4784 | BackendDAE.Matching matching; | ||
| 4785 | AvlTreePathFunction.Tree functionTree; | ||
| 4786 | Boolean update; | ||
| 4787 | Integer index = 1, ii; | ||
| 4788 | BackendDAE.EqSystem nSyst; | ||
| 4789 | list<Integer> ass1; | ||
| 4790 | list<Integer> ass2; | ||
| 4791 | list<Integer> compOrders; | ||
| 4792 | Integer ne, nv; | ||
| 4793 | Boolean simDAE; | ||
| 4794 | algorithm | ||
| 4795 | //BackendDump.bltdump("START:", outDAE); | ||
| 4796 | 8 | shared := inDAE.shared; | |
| 4797 | 8 | functionTree := shared.functionTree; | |
| 4798 | |||
| 4799 | simDAE := match shared | ||
| 4800 | case BackendDAE.SHARED(backendDAEType=BackendDAE.SIMULATION()) then true; | ||
| 4801 | case BackendDAE.SHARED(backendDAEType=BackendDAE.INITIALSYSTEM()) then true; | ||
| 4802 | else false; | ||
| 4803 | end match; | ||
| 4804 | |||
| 4805 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
|
8 | if Flags.isSet(Flags.DUMP_SIMPLIFY_LOOPS) then |
| 4806 | 4 | print("START: simplifyLoops\n"); | |
| 4807 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if not simDAE then |
| 4808 | ✗ | print("\n***noSIM***\n"); | |
| 4809 | end if; | ||
| 4810 | end if; | ||
| 4811 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 8 times.
|
24 | for syst in inDAE.eqs loop |
| 4812 | 16 | update := false; | |
| 4813 | 16 | ass1 := {}; | |
| 4814 | 16 | ass2 := {}; | |
| 4815 | 16 | compOrders := {}; | |
| 4816 | ii := 1; | ||
| 4817 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
|
16 | BackendDAE.EQSYSTEM(orderedVars=vars,orderedEqs=eqns,matching=matching as BackendDAE.MATCHING(comps=comps),stateSets=stateSets,partitionKind=partitionKind) := syst; |
| 4818 | 16 | ne := ExpandableArray.getNumberOfElements(eqns); | |
| 4819 | 16 | BackendDAE.VARIABLES(numberOfVars= nv) := vars; | |
| 4820 | |||
| 4821 |
2/2✓ Branch 0 taken 250 times.
✓ Branch 1 taken 16 times.
|
266 | for comp in comps loop |
| 4822 |
3/4✓ Branch 1 taken 250 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 242 times.
|
250 | if BackendEquation.isEquationsSystem(comp) or BackendEquation.isTornSystem(comp) then |
| 4823 | 8 | (index,vars,eqns,shared,update, ass1, ass2,compOrders) := simplifyLoopsWork(comp, index, vars, eqns, shared, update, ass1, ass2, simDAE, ii, compOrders); | |
| 4824 | end if; | ||
| 4825 | 250 | ii := ii + 1; | |
| 4826 | end for; // comp | ||
| 4827 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 10 times.
|
16 | nSyst := if update then simplifyLoopsUpdateMatching(vars, eqns, syst, listReverse(ass1), listReverse(ass2), ne, nv, functionTree, listReverse(compOrders)) else syst; |
| 4828 | new_systlst := nSyst :: new_systlst; | ||
| 4829 | end for; //syst | ||
| 4830 | 8 | outDAE:= BackendDAE.DAE(new_systlst, shared); | |
| 4831 | //outDAE:= BackendDAE.DAE(listReverse(new_systlst), shared); | ||
| 4832 | //BackendDump.bltdump("ENDE:", outDAE); | ||
| 4833 | |||
| 4834 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
|
8 | if Flags.isSet(Flags.DUMP_SIMPLIFY_LOOPS) then |
| 4835 | 4 | print("END: simplifyLoops\n"); | |
| 4836 | end if; | ||
| 4837 | |||
| 4838 | end simplifyLoopsMain; | ||
| 4839 | |||
| 4840 | protected function simplifyLoopsUpdateMatching | ||
| 4841 | " | ||
| 4842 | TODO: check me! | ||
| 4843 | " | ||
| 4844 | input BackendDAE.Variables inVars "vars array"; | ||
| 4845 | input BackendDAE.EquationArray inEqns "eqns array"; | ||
| 4846 | input BackendDAE.EqSystem inSyst; | ||
| 4847 | input list<Integer> ass1_; | ||
| 4848 | input list<Integer> ass2_; | ||
| 4849 | input Integer nEqns; | ||
| 4850 | input Integer nVars; | ||
| 4851 | input AvlTreePathFunction.Tree functionTree; | ||
| 4852 | input list<Integer> compOrders; | ||
| 4853 | output BackendDAE.EqSystem outSyst = inSyst; | ||
| 4854 | |||
| 4855 | protected | ||
| 4856 | array<Integer> ass1 "eqn := ass1[var]"; | ||
| 4857 | array<Integer> ass2 "var := ass2[eqn]"; | ||
| 4858 | Integer n1, n2; | ||
| 4859 | BackendDAE.Matching matching; | ||
| 4860 | BackendDAE.StrongComponents comps; | ||
| 4861 | algorithm | ||
| 4862 | //print("\nStart simplifyLoopsUpdateMatching"); | ||
| 4863 | 6 | matching := inSyst.matching; | |
| 4864 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
6 | BackendDAE.MATCHING(comps=comps, ass1=ass1, ass2=ass2) := matching; |
| 4865 | |||
| 4866 | 6 | n1 := listLength(ass1_); | |
| 4867 | 6 | n2 := listLength(ass2_); | |
| 4868 | |||
| 4869 | 6 | ass1 := Array.expand(n1, ass1, -1); | |
| 4870 | 6 | ass2 := Array.expand(n2, ass2, -1); | |
| 4871 | |||
| 4872 | //print("ass1 :" + intString(arrayLength(ass1)) + "/" + intString(n1) + "/" + intString(nEqns)); | ||
| 4873 | //print("\nass2 :" + intString(arrayLength(ass2)) + "/" + intString(n2) + "/" + intString(nVars) + "\n"); | ||
| 4874 | //alg fix | ||
| 4875 | |||
| 4876 | 6 | ass1 := simplifyLoopsUpdateAss(ass1, ass1_, nVars); | |
| 4877 | 6 | ass2 := simplifyLoopsUpdateAss(ass2, ass2_, nEqns); | |
| 4878 | |||
| 4879 | 6 | comps := simplifyLoopsUpdateComps(comps, ass1_, ass2_, compOrders); | |
| 4880 | |||
| 4881 | 6 | outSyst.matching := BackendDAE.MATCHING(ass1, ass2, comps); | |
| 4882 | outSyst.orderedEqs := inEqns; | ||
| 4883 | outSyst.orderedVars := inVars; | ||
| 4884 | 6 | outSyst := BackendDAEUtil.setEqSystMatrices(outSyst); | |
| 4885 | |||
| 4886 | //print("\nEnde simplifyLoopsUpdateMatching"); | ||
| 4887 | end simplifyLoopsUpdateMatching; | ||
| 4888 | |||
| 4889 | protected function simplifyLoopsUpdateAss | ||
| 4890 | input array<Integer> inAss; | ||
| 4891 | input list<Integer> new_ass; | ||
| 4892 | input Integer n; | ||
| 4893 | output array<Integer> outAss = inAss; | ||
| 4894 | protected | ||
| 4895 | Integer i = 1; | ||
| 4896 | algorithm | ||
| 4897 |
2/2✓ Branch 0 taken 54 times.
✓ Branch 1 taken 12 times.
|
66 | for a in new_ass loop |
| 4898 | 54 | outAss[i+n] := a; | |
| 4899 | 54 | i := i + 1; | |
| 4900 | end for; | ||
| 4901 | end simplifyLoopsUpdateAss; | ||
| 4902 | |||
| 4903 | protected function simplifyLoopsUpdateComps | ||
| 4904 | input BackendDAE.StrongComponents inComps; | ||
| 4905 | input list<Integer> inAss1; | ||
| 4906 | input list<Integer> inAss2; | ||
| 4907 | input list<Integer> inCompOrders; | ||
| 4908 | output BackendDAE.StrongComponents outComps = inComps; | ||
| 4909 | protected | ||
| 4910 | Integer a1, a2, shift = 0, o; | ||
| 4911 | BackendDAE.StrongComponent comp; | ||
| 4912 | list<Integer> ass1 = inAss1, ass2 = inAss2, compOrders = inCompOrders; | ||
| 4913 | algorithm | ||
| 4914 |
2/2✓ Branch 0 taken 27 times.
✓ Branch 1 taken 6 times.
|
33 | for a1 in ass1 loop |
| 4915 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
|
27 | o :: compOrders := compOrders; |
| 4916 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
|
27 | a2 :: ass2 := ass2; |
| 4917 | 27 | comp := BackendDAE.SINGLEEQUATION(a1, a2); | |
| 4918 | //print("comp: " + intString(a1) + " <->" + intString(a2) + "\n"); | ||
| 4919 | 27 | outComps := List.insert(outComps, o + shift, comp); | |
| 4920 | 27 | shift := shift + 1; | |
| 4921 | //outComps := comp :: outComps; | ||
| 4922 | end for; | ||
| 4923 | end simplifyLoopsUpdateComps; | ||
| 4924 | |||
| 4925 | protected function simplifyLoopsWork | ||
| 4926 | input BackendDAE.StrongComponent inComp; | ||
| 4927 | input Integer inIndx; | ||
| 4928 | input BackendDAE.Variables inVars "vars array"; | ||
| 4929 | input BackendDAE.EquationArray inEqns "eqns array"; | ||
| 4930 | input BackendDAE.Shared inShared; | ||
| 4931 | input Boolean inUpdate; | ||
| 4932 | input list<Integer> ass1_; | ||
| 4933 | input list<Integer> ass2_; | ||
| 4934 | input Boolean simDAE; | ||
| 4935 | input Integer ii; | ||
| 4936 | input list<Integer> inCompOrders; | ||
| 4937 | output Integer outIndx = inIndx; | ||
| 4938 | output BackendDAE.Variables outVars = inVars "vars array"; | ||
| 4939 | output BackendDAE.EquationArray outEqns = inEqns "eqns array"; | ||
| 4940 | output BackendDAE.Shared outShared = inShared; | ||
| 4941 | output Boolean outUpdate = inUpdate; | ||
| 4942 | output list<Integer> ass1 = ass1_; | ||
| 4943 | output list<Integer> ass2 = ass2_; | ||
| 4944 | output list<Integer> outCompOrders = inCompOrders; | ||
| 4945 | protected | ||
| 4946 | list<Integer> eqns; | ||
| 4947 | list<Integer> vv; | ||
| 4948 | list<Integer> vars "be careful with states, this are solved for der(x)"; | ||
| 4949 | list<DAE.ComponentRef> var_lst = {} "varName"; | ||
| 4950 | DAE.ComponentRef cr; | ||
| 4951 | BackendDAE.Equation eqn; | ||
| 4952 | Boolean update, linear; | ||
| 4953 | Integer i, k; | ||
| 4954 | BackendDAE.InnerEquations innerEquations; | ||
| 4955 | BackendDAE.InnerEquation innerEquation; | ||
| 4956 | algorithm | ||
| 4957 | |||
| 4958 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | if BackendEquation.isEquationsSystem(inComp) then |
| 4959 | ✗ | BackendDAE.EQUATIONSYSTEM(eqns=eqns,vars=vars) := inComp; | |
| 4960 | |||
| 4961 | //linear system need simplifications? | ||
| 4962 | ✗ | if BackendDAEUtil.isLinearEqSystemComp(inComp) then | |
| 4963 | ✗ | return; | |
| 4964 | end if; | ||
| 4965 | ✗ | if Flags.isSet(Flags.DUMP_SIMPLIFY_LOOPS) then | |
| 4966 | ✗ | print("------ EquationsSystem ------\n"); | |
| 4967 | end if; | ||
| 4968 | |||
| 4969 | else | ||
| 4970 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | BackendDAE.TORNSYSTEM(linear=linear, strictTearingSet = BackendDAE.TEARINGSET(tearingvars=vars, residualequations=eqns, innerEquations = innerEquations)) := inComp; |
| 4971 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if linear then |
| 4972 | ✗ | return; | |
| 4973 | end if; | ||
| 4974 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
|
8 | if Flags.isSet(Flags.DUMP_SIMPLIFY_LOOPS) then |
| 4975 | 4 | print("------ Tearing ------\n"); | |
| 4976 | end if; | ||
| 4977 | |||
| 4978 |
2/2✓ Branch 0 taken 48 times.
✓ Branch 1 taken 8 times.
|
56 | for innerEquation in innerEquations loop |
| 4979 | 48 | (k,vv) := BackendDAEUtil.getEqnAndVarsFromInnerEquation(innerEquation); | |
| 4980 | eqns := k :: eqns; | ||
| 4981 | 48 | vars := listAppend(vv,vars); | |
| 4982 | end for; | ||
| 4983 | end if; //comp | ||
| 4984 | |||
| 4985 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
|
8 | if Flags.isSet(Flags.DUMP_SIMPLIFY_LOOPS) then |
| 4986 | 4 | print("------ loop-vars ------\n"); | |
| 4987 | end if; | ||
| 4988 | |||
| 4989 |
2/2✓ Branch 0 taken 56 times.
✓ Branch 1 taken 8 times.
|
64 | for i in vars loop |
| 4990 | 56 | BackendDAE.VAR(varName = cr) := BackendVariable.getVarAt(outVars, i); | |
| 4991 | 56 | var_lst := cr :: var_lst; | |
| 4992 |
2/2✓ Branch 1 taken 12 times.
✓ Branch 2 taken 44 times.
|
56 | if Flags.isSet(Flags.DUMP_SIMPLIFY_LOOPS) then |
| 4993 | 12 | print(ComponentReferenceBasics.printComponentRefStr(cr) +"\n"); | |
| 4994 | end if; | ||
| 4995 | end for; | ||
| 4996 | |||
| 4997 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
|
8 | if Flags.isSet(Flags.DUMP_SIMPLIFY_LOOPS) then |
| 4998 | 4 | print("------------\n"); | |
| 4999 | end if; | ||
| 5000 | |||
| 5001 |
2/2✓ Branch 0 taken 56 times.
✓ Branch 1 taken 8 times.
|
64 | for i in eqns loop |
| 5002 | try | ||
| 5003 | 56 | eqn := BackendEquation.get(outEqns, i); | |
| 5004 |
2/2✓ Branch 1 taken 12 times.
✓ Branch 2 taken 44 times.
|
56 | if Flags.isSet(Flags.DUMP_SIMPLIFY_LOOPS) then |
| 5005 | 12 | print("update eqn[" + intString(i) + "]\n"); | |
| 5006 | 12 | print(BackendDump.equationString(eqn) + "--old--\n"); | |
| 5007 | end if; | ||
| 5008 | 56 | (outIndx, outVars, outEqns, outShared, update, eqn, ass1, ass2, outCompOrders) := simplifyLoopEqn(outIndx, outVars, outEqns, outShared, var_lst, eqn, ass1, ass2, simDAE, ii, outCompOrders); | |
| 5009 |
4/4✓ Branch 0 taken 16 times.
✓ Branch 1 taken 40 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 6 times.
|
56 | outUpdate := outUpdate or update; |
| 5010 | //if update then | ||
| 5011 | 56 | outEqns := BackendEquation.setAtIndex(outEqns, i, eqn); | |
| 5012 | //end if; | ||
| 5013 |
2/2✓ Branch 1 taken 12 times.
✓ Branch 2 taken 44 times.
|
56 | if Flags.isSet(Flags.DUMP_SIMPLIFY_LOOPS) then |
| 5014 | 12 | print("=> "); | |
| 5015 | 12 | print(BackendDump.equationString(eqn) + "--new--\n"); | |
| 5016 | end if; | ||
| 5017 | else | ||
| 5018 | end try; | ||
| 5019 | end for; | ||
| 5020 | |||
| 5021 | end simplifyLoopsWork; | ||
| 5022 | |||
| 5023 | protected function simplifyLoopEqn | ||
| 5024 | input Integer inIndx; | ||
| 5025 | input BackendDAE.Variables inVars "vars array"; | ||
| 5026 | input BackendDAE.EquationArray inEqns "eqns array"; | ||
| 5027 | input BackendDAE.Shared inShared; | ||
| 5028 | input list<DAE.ComponentRef> var_lst "filter vars"; | ||
| 5029 | input BackendDAE.Equation inEqn "filter eqn"; | ||
| 5030 | input list<Integer> ass1_; | ||
| 5031 | input list<Integer> ass2_; | ||
| 5032 | input Boolean simDAE; | ||
| 5033 | input Integer ii; | ||
| 5034 | input list<Integer> inCompOrders; | ||
| 5035 | output Integer outIndx = inIndx; | ||
| 5036 | output BackendDAE.Variables outVars = inVars "vars array"; | ||
| 5037 | output BackendDAE.EquationArray outEqns = inEqns "eqns array"; | ||
| 5038 | output BackendDAE.Shared outShared = inShared; | ||
| 5039 | output Boolean outUpdate = false; | ||
| 5040 | output BackendDAE.Equation outEqn = inEqn; | ||
| 5041 | output list<Integer> ass1 = ass1_; | ||
| 5042 | output list<Integer> ass2 = ass2_; | ||
| 5043 | output list<Integer> outCompOrder = inCompOrders; | ||
| 5044 | protected | ||
| 5045 | DAE.Exp rhs, lhs, e; | ||
| 5046 | Boolean update_lhs, update_rhs; | ||
| 5047 | list<DAE.Exp> loopTerms_lhs, noLoopTerms_lhs, loopTerms_rhs, noLoopTerms_rhs; | ||
| 5048 | Boolean useTmpVars = Flags.getConfigInt(Flags.SIMPLIFY_LOOPS) > 1; | ||
| 5049 | algorithm | ||
| 5050 | |||
| 5051 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 56 times.
|
56 | if BackendEquation.isAlgorithm(outEqn) then |
| 5052 | ✗ | return; | |
| 5053 | end if; | ||
| 5054 | |||
| 5055 | //get | ||
| 5056 | 56 | lhs := BackendEquation.getEquationLHS(outEqn); | |
| 5057 | //check | ||
| 5058 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 56 times.
|
56 | if not Types.isIntegerOrRealOrSubTypeOfEither(Expression.typeof(lhs)) then |
| 5059 | ✗ | return ; | |
| 5060 | end if; | ||
| 5061 | 56 | rhs := BackendEquation.getEquationRHS(outEqn); | |
| 5062 | |||
| 5063 | 56 | (loopTerms_lhs, noLoopTerms_lhs) := simplifyLoops_SplitTerms(var_lst, lhs); | |
| 5064 | 56 | (loopTerms_rhs, noLoopTerms_rhs) := simplifyLoops_SplitTerms(var_lst, rhs); | |
| 5065 | |||
| 5066 |
2/2✓ Branch 2 taken 2 times.
✓ Branch 3 taken 54 times.
|
56 | if listLength(loopTerms_lhs) > listLength(loopTerms_rhs) then |
| 5067 | 2 | lhs := Expression.expSub(Expression.makeSum1(loopTerms_lhs), Expression.makeSum1(loopTerms_rhs)); | |
| 5068 | 2 | rhs := Expression.expSub(Expression.makeSum1(noLoopTerms_rhs), Expression.makeSum1(noLoopTerms_lhs)); | |
| 5069 | else | ||
| 5070 | 54 | lhs := Expression.expSub(Expression.makeSum1(loopTerms_rhs), Expression.makeSum1(loopTerms_lhs)); | |
| 5071 | 54 | rhs := Expression.expSub(Expression.makeSum1(noLoopTerms_lhs), Expression.makeSum1(noLoopTerms_rhs)); | |
| 5072 | end if; | ||
| 5073 | |||
| 5074 | // | ||
| 5075 | 56 | (lhs,rhs,_) := Expression.createResidualExp3(lhs,rhs); | |
| 5076 | 56 | (lhs,e) := Expression.makeFraction(lhs); | |
| 5077 | 56 | (lhs, _) := ExpressionSimplify.simplify(lhs); | |
| 5078 | 56 | (e, _) := ExpressionSimplify.simplify(e); | |
| 5079 | |||
| 5080 | //rhs := Expression.expMul(rhs,e); | ||
| 5081 | 56 | rhs := ExpressionSimplify.simplifySumOperatorExpression(rhs, DAE.MUL(Expression.typeof(rhs)), e); | |
| 5082 | |||
| 5083 | //update | ||
| 5084 | 56 | (outIndx, outVars, outEqns, outShared, update_rhs, rhs, ass1, ass2, outCompOrder) := simplifyLoopExp(outIndx, outVars, outEqns, outShared, var_lst, rhs, ass1, ass2, simDAE, useTmpVars,ii,outCompOrder); | |
| 5085 | 56 | (outIndx, outVars, outEqns, outShared, update_lhs, lhs, ass1, ass2, outCompOrder) := simplifyLoopExp(outIndx, outVars, outEqns, outShared, var_lst, lhs, ass1, ass2, simDAE, useTmpVars,ii,outCompOrder); | |
| 5086 | |||
| 5087 | // | ||
| 5088 | 56 | outEqn := BackendEquation.setEquationLHS(outEqn, lhs); | |
| 5089 | 56 | outEqn := BackendEquation.setEquationRHS(outEqn, rhs); | |
| 5090 | |||
| 5091 |
4/4✓ Branch 0 taken 34 times.
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 33 times.
✓ Branch 3 taken 1 time.
|
56 | outUpdate := outUpdate or update_rhs or update_lhs; |
| 5092 | end simplifyLoopEqn; | ||
| 5093 | |||
| 5094 | |||
| 5095 | public function simplifyLoopExp | ||
| 5096 | input Integer inIndx; | ||
| 5097 | input BackendDAE.Variables inVars "vars array"; | ||
| 5098 | input BackendDAE.EquationArray inEqns "eqns array"; | ||
| 5099 | input BackendDAE.Shared inShared; | ||
| 5100 | input list<DAE.ComponentRef> var_lst "filter vars"; | ||
| 5101 | input DAE.Exp inExp; | ||
| 5102 | input list<Integer> ass1_; | ||
| 5103 | input list<Integer> ass2_; | ||
| 5104 | input Boolean simDAE; | ||
| 5105 | input Boolean useTmpVars = true; | ||
| 5106 | input Integer ii; | ||
| 5107 | input list<Integer> inCompOrders; | ||
| 5108 | input String tmpVarName = "LOOP"; | ||
| 5109 | input Boolean noPara = false; | ||
| 5110 | output Integer outIndx = inIndx; | ||
| 5111 | output BackendDAE.Variables outVars = inVars "vars array"; | ||
| 5112 | output BackendDAE.EquationArray outEqns = inEqns "eqns array"; | ||
| 5113 | output BackendDAE.Shared outShared = inShared; | ||
| 5114 | output Boolean outUpdate = false; | ||
| 5115 | output DAE.Exp outExp = inExp; | ||
| 5116 | output list<Integer> ass1 = ass1_; | ||
| 5117 | output list<Integer> ass2 = ass2_; | ||
| 5118 | output list<Integer> outCompOrder = inCompOrders; | ||
| 5119 | protected | ||
| 5120 | list<DAE.Exp> loopTerms, noLoopTerms, loopFactors, noLoopFactors, loopTermsUpdatedFactors, loopFacotrsUpdatedTerms; | ||
| 5121 | DAE.Exp res, noLoopTerm, noLoopFactor, e1, e2; | ||
| 5122 | Boolean update; | ||
| 5123 | DAE.Operator op; | ||
| 5124 | Boolean para; | ||
| 5125 | algorithm | ||
| 5126 | |||
| 5127 | 152 | (loopTerms, noLoopTerms) := simplifyLoops_SplitTerms(var_lst, outExp); | |
| 5128 | |||
| 5129 | //terms | ||
| 5130 | 152 | (noLoopTerm,_) := ExpressionSimplify.simplify1(Expression.makeSum1(noLoopTerms)); | |
| 5131 |
2/2✓ Branch 0 taken 128 times.
✓ Branch 1 taken 24 times.
|
152 | if useTmpVars and simDAE then |
| 5132 | 128 | (noLoopTerm, outEqns, outVars, outShared, update, para) := BackendEquation.makeTmpEqnForExp(noLoopTerm, tmpVarName + "T", System.tmpTickIndex(Global.tmpVariableIndex), outEqns, outVars, outShared); | |
| 5133 | 128 | (outUpdate, ass1, ass2, outIndx, outCompOrder) := simplifyLoopExpHelper(update, outUpdate, para, ass1, ass2, outVars, outEqns, outIndx, ii, outCompOrder); | |
| 5134 | end if; | ||
| 5135 | |||
| 5136 | //factors | ||
| 5137 | loopTermsUpdatedFactors := {}; | ||
| 5138 |
2/2✓ Branch 0 taken 159 times.
✓ Branch 1 taken 152 times.
|
311 | for factor in loopTerms loop |
| 5139 | 159 | (loopFactors, noLoopFactors) := simplifyLoops_SplitFactors(var_lst, factor); | |
| 5140 | 159 | (noLoopFactor,_) := ExpressionSimplify.simplify1(Expression.makeProductLst(noLoopFactors)); | |
| 5141 | |||
| 5142 |
2/2✓ Branch 0 taken 133 times.
✓ Branch 1 taken 26 times.
|
159 | if useTmpVars and simDAE then |
| 5143 | if (match noLoopFactor case DAE.BINARY(operator = DAE.DIV()) then true; case DAE.BINARY(operator = DAE.POW()) then true; else false; end match) then | ||
| 5144 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | DAE.BINARY(e1,op,e2) := noLoopFactor; |
| 5145 | 2 | (e1, outEqns, outVars, outShared, update, para) := BackendEquation.makeTmpEqnForExp(e1, "LOOPF", if simDAE then outIndx else -outIndx, outEqns, outVars, outShared,noPara); | |
| 5146 | 2 | (outUpdate, ass1, ass2, outIndx, outCompOrder) := simplifyLoopExpHelper(update, outUpdate, para, ass1, ass2, outVars, outEqns, outIndx, ii, outCompOrder); | |
| 5147 | 2 | (e2, outEqns, outVars, outShared, update, para) := BackendEquation.makeTmpEqnForExp(e2, "LOOPF", if simDAE then outIndx else -outIndx, outEqns, outVars, outShared,noPara); | |
| 5148 | 2 | (outUpdate, ass1, ass2, outIndx, outCompOrder) := simplifyLoopExpHelper(update, outUpdate, para, ass1, ass2, outVars, outEqns, outIndx, ii, outCompOrder); | |
| 5149 | 2 | noLoopFactor := DAE.BINARY(e1,op,e2); | |
| 5150 | else | ||
| 5151 | 131 | (noLoopFactor, outEqns, outVars, outShared, update, para) := BackendEquation.makeTmpEqnForExp(noLoopFactor, tmpVarName + "F", if simDAE then outIndx else -outIndx, outEqns, outVars, outShared); | |
| 5152 | 131 | (outUpdate, ass1, ass2, outIndx, outCompOrder) := simplifyLoopExpHelper(update, outUpdate, para, ass1, ass2, outVars, outEqns, outIndx, ii, outCompOrder); | |
| 5153 | end if; | ||
| 5154 | end if; | ||
| 5155 | |||
| 5156 | //recursive | ||
| 5157 | loopFacotrsUpdatedTerms := {}; | ||
| 5158 |
2/2✓ Branch 0 taken 159 times.
✓ Branch 1 taken 159 times.
|
318 | for term in loopFactors loop |
| 5159 | 159 | res := term; | |
| 5160 |
2/2✓ Branch 1 taken 18 times.
✓ Branch 2 taken 141 times.
|
159 | if Expression.isBinary(res) then |
| 5161 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
|
18 | DAE.BINARY(operator=op) := res; |
| 5162 |
4/6✓ Branch 1 taken 10 times.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 10 times.
✗ Branch 8 not taken.
|
18 | if Expression.isAddOrSub(op) or Expression.isMulOrDiv(op) or Expression.isPow(op) then |
| 5163 |
1/2✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
|
18 | if not ExpressionBasics.expEqual(res, inExp) then |
| 5164 |
3/4✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 8 times.
|
18 | if Expression.isDiv(op) or Expression.isPow(op) then |
| 5165 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
|
10 | DAE.BINARY(e1,op,e2) := res; |
| 5166 | 10 | (outIndx, outVars, outEqns, outShared, update, e1, ass1, ass2, outCompOrder) := simplifyLoopExp(outIndx, outVars, outEqns, outShared, var_lst, e1, ass1, ass2, simDAE, useTmpVars, ii, outCompOrder); | |
| 5167 | 10 | outUpdate := update or outUpdate; | |
| 5168 | 10 | (outIndx, outVars, outEqns, outShared, update, e2, ass1, ass2, outCompOrder) := simplifyLoopExp(outIndx, outVars, outEqns, outShared, var_lst, e2, ass1, ass2, simDAE, useTmpVars, ii, outCompOrder); | |
| 5169 | 10 | outUpdate := update or outUpdate; | |
| 5170 | 10 | (e2,_) := ExpressionSimplify.simplify1(e2); | |
| 5171 | 10 | res := DAE.BINARY(e1,op,e2); | |
| 5172 | else | ||
| 5173 | 8 | (outIndx, outVars, outEqns, outShared, update, res, ass1, ass2, outCompOrder) := simplifyLoopExp(outIndx, outVars, outEqns, outShared, var_lst, res, ass1, ass2, simDAE, useTmpVars, ii, outCompOrder); | |
| 5174 | 8 | outUpdate := update or outUpdate; | |
| 5175 | end if; // DIV, POW | ||
| 5176 | end if; // equal | ||
| 5177 | end if; // *, /, +, -, ^ | ||
| 5178 | end if; // BINARY | ||
| 5179 | 159 | loopFacotrsUpdatedTerms := res :: loopFacotrsUpdatedTerms; | |
| 5180 | end for; //term2 | ||
| 5181 | 159 | loopTermsUpdatedFactors := Expression.makeProductLst(noLoopFactor :: loopFacotrsUpdatedTerms) :: loopTermsUpdatedFactors; | |
| 5182 | end for; //factor | ||
| 5183 | |||
| 5184 | 152 | outExp := ExpressionSimplify.simplify(Expression.makeSum1(noLoopTerm::loopTermsUpdatedFactors,true)); | |
| 5185 | |||
| 5186 | end simplifyLoopExp; | ||
| 5187 | |||
| 5188 | protected function simplifyLoopExpHelper | ||
| 5189 | input Boolean update; | ||
| 5190 | input Boolean update_; | ||
| 5191 | input Boolean para; | ||
| 5192 | input list<Integer> ass1_; | ||
| 5193 | input list<Integer> ass2_; | ||
| 5194 | input BackendDAE.Variables inVars "vars array"; | ||
| 5195 | input BackendDAE.EquationArray inEqns "eqns array"; | ||
| 5196 | input Integer inIndex; | ||
| 5197 | input Integer ii; | ||
| 5198 | input list<Integer> inCompOrders; | ||
| 5199 | output Boolean outUpdate = update_; | ||
| 5200 | output list<Integer> ass1 = ass1_; | ||
| 5201 | output list<Integer> ass2 = ass2_; | ||
| 5202 | output Integer outIndx = inIndex; | ||
| 5203 | output list<Integer> outCompOrder = inCompOrders; | ||
| 5204 | protected | ||
| 5205 | Integer ne, nv; | ||
| 5206 | algorithm | ||
| 5207 |
2/2✓ Branch 0 taken 228 times.
✓ Branch 1 taken 35 times.
|
263 | if update then |
| 5208 | 35 | outIndx := outIndx + 1; | |
| 5209 | outUpdate := update; | ||
| 5210 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 35 times.
|
35 | if not para then |
| 5211 | 35 | ne := ExpandableArray.getNumberOfElements(inEqns); | |
| 5212 | 35 | BackendDAE.VARIABLES(numberOfVars= nv) := inVars; | |
| 5213 | ass1 := ne :: ass1; | ||
| 5214 | ass2 := nv :: ass2; | ||
| 5215 | outCompOrder := ii :: outCompOrder; | ||
| 5216 | end if; | ||
| 5217 | end if; | ||
| 5218 | end simplifyLoopExpHelper; | ||
| 5219 | |||
| 5220 | public function simplifyLoops_SplitTerms | ||
| 5221 | input list<DAE.ComponentRef> var_lst; | ||
| 5222 | input DAE.Exp inExp; | ||
| 5223 | output list<DAE.Exp> loopTerms = {}; | ||
| 5224 | output list<DAE.Exp> noLoopTerms; | ||
| 5225 | protected | ||
| 5226 | list<DAE.Exp> tmp_loopTerms; | ||
| 5227 | algorithm | ||
| 5228 | 267 | noLoopTerms := Expression.terms(inExp); | |
| 5229 |
2/2✓ Branch 0 taken 1944 times.
✓ Branch 1 taken 128 times.
|
2072 | for cr in var_lst loop |
| 5230 |
2/2✓ Branch 0 taken 139 times.
✓ Branch 1 taken 1805 times.
|
1944 | if listEmpty(noLoopTerms) then |
| 5231 | break; | ||
| 5232 | else | ||
| 5233 | 1805 | (tmp_loopTerms, noLoopTerms) := List.split1OnTrue(noLoopTerms, Expression.expHasCrefNoPreOrStart, cr); | |
| 5234 | 1805 | loopTerms := listAppend(tmp_loopTerms, loopTerms); | |
| 5235 | end if; | ||
| 5236 | end for; | ||
| 5237 | end simplifyLoops_SplitTerms; | ||
| 5238 | |||
| 5239 | protected function simplifyLoops_SplitFactors | ||
| 5240 | input list<DAE.ComponentRef> var_lst; | ||
| 5241 | input DAE.Exp inExp; | ||
| 5242 | output list<DAE.Exp> loopTerms = {}; | ||
| 5243 | output list<DAE.Exp> noLoopTerms; | ||
| 5244 | protected | ||
| 5245 | list<DAE.Exp> tmp_loopTerms; | ||
| 5246 | algorithm | ||
| 5247 | 159 | noLoopTerms := Expression.factors(inExp); | |
| 5248 |
2/2✓ Branch 0 taken 1019 times.
✓ Branch 1 taken 59 times.
|
1078 | for cr in var_lst loop |
| 5249 |
2/2✓ Branch 0 taken 100 times.
✓ Branch 1 taken 919 times.
|
1019 | if listEmpty(noLoopTerms) then |
| 5250 | break; | ||
| 5251 | else | ||
| 5252 | 919 | (tmp_loopTerms, noLoopTerms) := List.split1OnTrue(noLoopTerms, Expression.expHasCrefNoPreOrStart, cr); | |
| 5253 | 919 | loopTerms := listAppend(tmp_loopTerms, loopTerms); | |
| 5254 | end if; | ||
| 5255 | end for; | ||
| 5256 | |||
| 5257 | end simplifyLoops_SplitFactors; | ||
| 5258 | |||
| 5259 | // ============================================================================= | ||
| 5260 | // section for introduceDerAlias | ||
| 5261 | // | ||
| 5262 | // ============================================================================= | ||
| 5263 | |||
| 5264 | public function introduceDerAlias | ||
| 5265 | " This module introduces alias for derivatove call in the form | ||
| 5266 | dx = der(x); | ||
| 5267 | This helps tearing and non-linear solvers to handle them more efficent." | ||
| 5268 | input BackendDAE.BackendDAE inDAE; | ||
| 5269 | output BackendDAE.BackendDAE outDAE; | ||
| 5270 | algorithm | ||
| 5271 | 1 | outDAE := BackendDAEUtil.mapEqSystem(inDAE, introduceDerAliasWork); | |
| 5272 | end introduceDerAlias; | ||
| 5273 | |||
| 5274 | protected function introduceDerAliasWork | ||
| 5275 | input BackendDAE.EqSystem inSyst; | ||
| 5276 | input BackendDAE.Shared shared; | ||
| 5277 | output BackendDAE.EqSystem osyst; | ||
| 5278 | output BackendDAE.Shared oshared = shared; | ||
| 5279 | protected | ||
| 5280 | BackendDAE.Variables vars; | ||
| 5281 | BackendDAE.EquationArray eqns; | ||
| 5282 | list<BackendDAE.Equation> eqnsList; | ||
| 5283 | algorithm | ||
| 5284 | osyst := match inSyst | ||
| 5285 | local | ||
| 5286 | BackendDAE.EqSystem syst; | ||
| 5287 | case syst as BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns) | ||
| 5288 | algorithm | ||
| 5289 | 2 | (eqns, (vars, eqnsList, _, _)) := | |
| 5290 | BackendEquation.traverseEquationArray_WithUpdate( eqns, traverserintroduceDerAliasEquation, | ||
| 5291 | (vars, {}, shared, true) ); | ||
| 5292 | 2 | eqns := BackendEquation.addList(eqnsList, eqns); | |
| 5293 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | syst.orderedEqs := eqns; syst.orderedVars := vars; |
| 5294 | then syst; | ||
| 5295 | end match; | ||
| 5296 | end introduceDerAliasWork; | ||
| 5297 | |||
| 5298 | protected function traverserintroduceDerAliasEquation " | ||
| 5299 | Help function to e.g. introduceDerAliasWork" | ||
| 5300 | input BackendDAE.Equation inEq; | ||
| 5301 | input tuple<BackendDAE.Variables, list<BackendDAE.Equation>, BackendDAE.Shared, Boolean> tpl; | ||
| 5302 | output BackendDAE.Equation outEq; | ||
| 5303 | output tuple<BackendDAE.Variables, list<BackendDAE.Equation>, BackendDAE.Shared, Boolean> outTpl; | ||
| 5304 | protected | ||
| 5305 | BackendDAE.Equation e; | ||
| 5306 | BackendDAE.Variables vars; | ||
| 5307 | Boolean b; | ||
| 5308 | list<DAE.SymbolicOperation> ops; | ||
| 5309 | BackendDAE.Shared shared; | ||
| 5310 | list<BackendDAE.Equation> eqnLst; | ||
| 5311 | algorithm | ||
| 5312 | 15 | (vars, eqnLst, shared, b) := tpl; | |
| 5313 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
|
15 | (e, (vars, eqnLst, shared, ops, _)) := BackendEquation.traverseExpsOfEquation(inEq, traverserintroduceDerAliasExp, (vars, eqnLst, shared, {}, b)); |
| 5314 | 15 | outEq := List.foldr(ops, BackendEquation.addOperation, e); | |
| 5315 | 15 | outTpl := (vars, eqnLst, shared, b); | |
| 5316 | end traverserintroduceDerAliasEquation; | ||
| 5317 | |||
| 5318 | protected function traverserintroduceDerAliasExp " | ||
| 5319 | Help function to e.g. traverserintroduceDerAliasEquation" | ||
| 5320 | input DAE.Exp inExp; | ||
| 5321 | input tuple<BackendDAE.Variables, list<BackendDAE.Equation>, BackendDAE.Shared, list<DAE.SymbolicOperation>, Boolean> tpl; | ||
| 5322 | output DAE.Exp outExp; | ||
| 5323 | output tuple<BackendDAE.Variables, list<BackendDAE.Equation>, BackendDAE.Shared, list<DAE.SymbolicOperation>, Boolean> outTpl; | ||
| 5324 | protected | ||
| 5325 | DAE.Exp e, e1; | ||
| 5326 | tuple<BackendDAE.Variables, list<BackendDAE.Equation>, BackendDAE.Shared, Boolean, Boolean> ext_arg; | ||
| 5327 | BackendDAE.Variables vars; | ||
| 5328 | list<DAE.SymbolicOperation> ops; | ||
| 5329 | Boolean b, addVars; | ||
| 5330 | BackendDAE.Shared shared; | ||
| 5331 | list<BackendDAE.Equation> eqnLst; | ||
| 5332 | algorithm | ||
| 5333 | e := inExp; | ||
| 5334 | 30 | (vars, eqnLst, shared, ops, addVars) := tpl; | |
| 5335 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
|
30 | ext_arg := (vars, eqnLst, shared, addVars, false); |
| 5336 | 30 | (e1, (vars, eqnLst, shared, _, b)) := Expression.traverseExpBottomUp(e, introDerAlias, ext_arg); | |
| 5337 | 30 | ops := List.consOnTrue(b, DAE.SUBSTITUTION({e1}, e), ops); | |
| 5338 | outExp := e1; | ||
| 5339 | 30 | outTpl := (vars, eqnLst, shared, ops, addVars); | |
| 5340 | end traverserintroduceDerAliasExp; | ||
| 5341 | |||
| 5342 | protected function introDerAlias " | ||
| 5343 | Help function to e.g. traverserintroduceDerAliasExp" | ||
| 5344 | input DAE.Exp inExp; | ||
| 5345 | input tuple<BackendDAE.Variables, list<BackendDAE.Equation>, BackendDAE.Shared, Boolean, Boolean> itpl; | ||
| 5346 | output DAE.Exp outExp; | ||
| 5347 | output tuple<BackendDAE.Variables, list<BackendDAE.Equation>, BackendDAE.Shared, Boolean, Boolean> tpl; | ||
| 5348 | algorithm | ||
| 5349 | (outExp,tpl) := matchcontinue (inExp, itpl) | ||
| 5350 | local | ||
| 5351 | BackendDAE.Variables vars; | ||
| 5352 | DAE.ComponentRef cr,cref; | ||
| 5353 | DAE.Type ty; | ||
| 5354 | String str; | ||
| 5355 | BackendDAE.Shared shared; | ||
| 5356 | BackendDAE.Var v, v1; | ||
| 5357 | Boolean addVar; | ||
| 5358 | list<BackendDAE.Equation> eqnLst; | ||
| 5359 | Integer numVars; | ||
| 5360 | list<DAE.Exp> expLst; | ||
| 5361 | String str; | ||
| 5362 | |||
| 5363 | case (DAE.CALL(path=Absyn.IDENT(name="der"), expLst={DAE.CREF(componentRef=cr, ty=ty)}), (vars, eqnLst, shared, addVar, _)) algorithm | ||
| 5364 | 10 | (v, _) := BackendVariable.getVarSingle(cr, vars); | |
| 5365 | 10 | cref := BackendVariable.varCref(v); | |
| 5366 | 10 | v1 := BackendVariable.createAliasDerVar(cref); | |
| 5367 | 10 | v1 := BackendVariable.mergeNominalAttribute(v, v1, false); | |
| 5368 | 10 | cref := BackendVariable.varCref(v1); | |
| 5369 | 10 | outExp := DAE.CREF(cref,ty); | |
| 5370 |
1/2✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
|
10 | if addVar then |
| 5371 | 10 | numVars := BackendVariable.varsSize(vars); | |
| 5372 | 10 | vars := BackendVariable.addVar(v1, vars); | |
| 5373 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 6 times.
|
10 | eqnLst := if numVars < BackendVariable.varsSize(vars) then BackendDAE.EQUATION(inExp, outExp, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC)::eqnLst else eqnLst; |
| 5374 | end if; | ||
| 5375 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
|
10 | then (outExp, (vars, eqnLst, shared, addVar, true)); |
| 5376 | |||
| 5377 | case (DAE.CALL(path=Absyn.IDENT(name="der")), _) algorithm | ||
| 5378 | ✗ | str := "BackendDAEOptimize.introduceDerAlias failed for: " + ExpressionBasics.printExpStr(inExp) + "\n"; | |
| 5379 | ✗ | Error.addMessage(Error.INTERNAL_ERROR, {str}); | |
| 5380 | ✗ | then fail(); | |
| 5381 | |||
| 5382 | else (inExp, itpl); | ||
| 5383 | end matchcontinue; | ||
| 5384 | end introDerAlias; | ||
| 5385 | |||
| 5386 | |||
| 5387 | // ============================================================================= | ||
| 5388 | // section for replaceDerCall | ||
| 5389 | // | ||
| 5390 | // ============================================================================= | ||
| 5391 | |||
| 5392 | public function replaceDerCalls | ||
| 5393 | " This module replaces all der(cref)-calls by $DER.cref crefs expression." | ||
| 5394 | input BackendDAE.BackendDAE inDAE; | ||
| 5395 | output BackendDAE.BackendDAE outDAE; | ||
| 5396 | algorithm | ||
| 5397 | ✗ | outDAE := BackendDAEUtil.mapEqSystem(inDAE, replaceDerCallWork); | |
| 5398 | end replaceDerCalls; | ||
| 5399 | |||
| 5400 | protected function replaceDerCallWork | ||
| 5401 | input BackendDAE.EqSystem inSyst; | ||
| 5402 | input BackendDAE.Shared shared; | ||
| 5403 | output BackendDAE.EqSystem osyst; | ||
| 5404 | output BackendDAE.Shared oshared = shared; | ||
| 5405 | algorithm | ||
| 5406 | osyst := match inSyst | ||
| 5407 | local | ||
| 5408 | BackendDAE.EqSystem syst; | ||
| 5409 | BackendDAE.Variables localKnowns; | ||
| 5410 | BackendDAE.Variables vars; | ||
| 5411 | BackendDAE.EquationArray eqns; | ||
| 5412 | case syst as BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns) | ||
| 5413 | algorithm | ||
| 5414 | ✗ | (eqns, vars) := | |
| 5415 | BackendEquation.traverseEquationArray_WithUpdate(eqns, traverserreplaceDerCall, vars); | ||
| 5416 | ✗ | (localKnowns, vars) := BackendVariable.traverseBackendDAEVars(vars, | |
| 5417 | moveStatesVariables, (oshared.localKnownVars, vars)); | ||
| 5418 | ✗ | oshared.localKnownVars := localKnowns; | |
| 5419 | ✗ | syst.orderedEqs := eqns; | |
| 5420 | ✗ | syst.orderedVars := vars; | |
| 5421 | then syst; | ||
| 5422 | end match; | ||
| 5423 | end replaceDerCallWork; | ||
| 5424 | |||
| 5425 | protected function traverserreplaceDerCall " | ||
| 5426 | Help function to e.g. replaceDerCall" | ||
| 5427 | input BackendDAE.Equation inEq; | ||
| 5428 | input BackendDAE.Variables inVars; | ||
| 5429 | output BackendDAE.Equation outEq; | ||
| 5430 | output BackendDAE.Variables outVars = inVars; | ||
| 5431 | protected | ||
| 5432 | BackendDAE.Equation e; | ||
| 5433 | list<DAE.SymbolicOperation> ops; | ||
| 5434 | algorithm | ||
| 5435 | ✗ | (e, ops) := BackendEquation.traverseExpsOfEquation(inEq, traverserreplaceDerCallExp, {}); | |
| 5436 | ✗ | outEq := List.foldr(ops, BackendEquation.addOperation, e); | |
| 5437 | end traverserreplaceDerCall; | ||
| 5438 | |||
| 5439 | protected function traverserreplaceDerCallExp " | ||
| 5440 | Help function to e.g. traverserreplaceDerCall" | ||
| 5441 | input DAE.Exp inExp; | ||
| 5442 | input list<DAE.SymbolicOperation> tpl; | ||
| 5443 | output DAE.Exp outExp; | ||
| 5444 | output list<DAE.SymbolicOperation> outTpl; | ||
| 5445 | protected | ||
| 5446 | DAE.Exp e, e1; | ||
| 5447 | Boolean b; | ||
| 5448 | algorithm | ||
| 5449 | e := inExp; | ||
| 5450 | ✗ | (e1, b) := Expression.traverseExpBottomUp(e, replaceDerCall, false); | |
| 5451 | ✗ | outTpl := List.consOnTrue(b, DAE.SUBSTITUTION({e1}, e), tpl); | |
| 5452 | outExp := e1; | ||
| 5453 | end traverserreplaceDerCallExp; | ||
| 5454 | |||
| 5455 | protected function replaceDerCall " | ||
| 5456 | Help function to e.g. traverserreplaceDerCallExp" | ||
| 5457 | input DAE.Exp inExp; | ||
| 5458 | input Boolean itpl; | ||
| 5459 | output DAE.Exp outExp; | ||
| 5460 | output Boolean tpl; | ||
| 5461 | algorithm | ||
| 5462 | (outExp,tpl) := matchcontinue inExp | ||
| 5463 | local | ||
| 5464 | DAE.ComponentRef cr,cref; | ||
| 5465 | DAE.Type ty; | ||
| 5466 | |||
| 5467 | case DAE.CALL(path=Absyn.IDENT(name="der"), expLst={DAE.CREF(componentRef=cr, ty=ty)}) algorithm | ||
| 5468 | ✗ | cref := ComponentReference.crefPrefixDer(cr); | |
| 5469 | ✗ | outExp := DAE.CREF(cref,ty); | |
| 5470 | then (outExp, true); | ||
| 5471 | |||
| 5472 | case DAE.CALL(path=Absyn.IDENT(name="der")) algorithm | ||
| 5473 | ✗ | Error.addMessage(Error.INTERNAL_ERROR, {getInstanceName() + " failed for: " + ExpressionBasics.printExpStr(inExp) + "\n"}); | |
| 5474 | ✗ | then fail(); | |
| 5475 | |||
| 5476 | else (inExp, itpl); | ||
| 5477 | end matchcontinue; | ||
| 5478 | end replaceDerCall; | ||
| 5479 | |||
| 5480 | protected function moveStatesVariables | ||
| 5481 | input BackendDAE.Var inVar; | ||
| 5482 | input tuple<BackendDAE.Variables, BackendDAE.Variables> inTpl; | ||
| 5483 | output BackendDAE.Var outVar = inVar; | ||
| 5484 | output tuple<BackendDAE.Variables, BackendDAE.Variables> outTpl = inTpl; | ||
| 5485 | algorithm | ||
| 5486 | () := match inVar | ||
| 5487 | local | ||
| 5488 | DAE.ComponentRef cref; | ||
| 5489 | BackendDAE.Var newVar; | ||
| 5490 | BackendDAE.Variables localKnowns, newVars; | ||
| 5491 | case BackendDAE.VAR(varKind = BackendDAE.STATE(), varName=cref) algorithm | ||
| 5492 | ✗ | (localKnowns, newVars) := inTpl; | |
| 5493 | // remove the state from variables | ||
| 5494 | ✗ | newVars := BackendVariable.deleteVar(cref, newVars); | |
| 5495 | // push it to the local knows | ||
| 5496 | ✗ | localKnowns := BackendVariable.addVar(inVar, localKnowns); | |
| 5497 | |||
| 5498 | ✗ | cref := ComponentReference.crefPrefixDer(cref); | |
| 5499 | ✗ | newVar := BackendVariable.copyVarNewName(cref, inVar); | |
| 5500 | ✗ | newVar := BackendVariable.setVarKind(newVar, BackendDAE.STATE_DER()); | |
| 5501 | |||
| 5502 | ✗ | newVars := BackendVariable.addVar(newVar, newVars); | |
| 5503 | ✗ | outTpl := (localKnowns, newVars); | |
| 5504 | then (); | ||
| 5505 | else (); | ||
| 5506 | end match; | ||
| 5507 | end moveStatesVariables; | ||
| 5508 | |||
| 5509 | |||
| 5510 | // ============================================================================= | ||
| 5511 | // replace expression with rewritten expression | ||
| 5512 | // | ||
| 5513 | // ============================================================================= | ||
| 5514 | |||
| 5515 | public function applyRewriteRulesBackend | ||
| 5516 | "@author: adrpo" | ||
| 5517 | input BackendDAE.BackendDAE inDAE; | ||
| 5518 | output BackendDAE.BackendDAE outDAE; | ||
| 5519 | algorithm | ||
| 5520 | ✗ | (outDAE, _) := BackendDAEUtil.mapEqSystemAndFold(inDAE, applyRewriteRulesBackend0, false); | |
| 5521 | ✗ | outDAE := applyRewriteRulesBackendShared(outDAE); | |
| 5522 | end applyRewriteRulesBackend; | ||
| 5523 | |||
| 5524 | protected function applyRewriteRulesBackend0 | ||
| 5525 | "@author: adrpo" | ||
| 5526 | input BackendDAE.EqSystem isyst; | ||
| 5527 | input BackendDAE.Shared inShared; | ||
| 5528 | input Boolean inChanged; | ||
| 5529 | output BackendDAE.EqSystem osyst = isyst; | ||
| 5530 | output BackendDAE.Shared outShared = inShared; | ||
| 5531 | output Boolean outChanged; | ||
| 5532 | algorithm | ||
| 5533 | try | ||
| 5534 | ✗ | BackendDAEUtil.traverseBackendDAEExpsVarsWithUpdate(isyst.orderedVars, traverserapplyRewriteRulesBackend, false); | |
| 5535 | ✗ | BackendDAEUtil.traverseBackendDAEExpsEqns(isyst.orderedEqs, traverserapplyRewriteRulesBackend, false); | |
| 5536 | ✗ | BackendDAEUtil.traverseBackendDAEExpsEqns(isyst.removedEqs, traverserapplyRewriteRulesBackend, false); | |
| 5537 | outChanged := true; | ||
| 5538 | else | ||
| 5539 | outChanged := false; | ||
| 5540 | end try; | ||
| 5541 | end applyRewriteRulesBackend0; | ||
| 5542 | |||
| 5543 | protected function traverserapplyRewriteRulesBackend | ||
| 5544 | "@author: adrpo" | ||
| 5545 | input DAE.Exp inExp; | ||
| 5546 | input Boolean inB; | ||
| 5547 | output DAE.Exp outExp; | ||
| 5548 | output Boolean outB; | ||
| 5549 | algorithm | ||
| 5550 | ✗ | (outExp,outB) := Expression.traverseExpBottomUp(inExp,traverserExpapplyRewriteRulesBackend,inB); | |
| 5551 | end traverserapplyRewriteRulesBackend; | ||
| 5552 | |||
| 5553 | protected function traverserExpapplyRewriteRulesBackend | ||
| 5554 | "@author: adrpo" | ||
| 5555 | input DAE.Exp inExp; | ||
| 5556 | input Boolean inB; | ||
| 5557 | output DAE.Exp outExp; | ||
| 5558 | output Boolean outB; | ||
| 5559 | algorithm | ||
| 5560 | (outExp,outB) := matchcontinue inExp | ||
| 5561 | local | ||
| 5562 | DAE.Exp e; | ||
| 5563 | |||
| 5564 | // apply rewrite rule | ||
| 5565 | case e algorithm | ||
| 5566 | ✗ | (e, true) := RewriteRules.rewriteBackEnd(e); | |
| 5567 | then (e, true); | ||
| 5568 | |||
| 5569 | else (inExp,inB); | ||
| 5570 | end matchcontinue; | ||
| 5571 | end traverserExpapplyRewriteRulesBackend; | ||
| 5572 | |||
| 5573 | protected function applyRewriteRulesBackendShared "@author: adrpo" | ||
| 5574 | input BackendDAE.BackendDAE inDAE; | ||
| 5575 | output BackendDAE.BackendDAE outDAE; | ||
| 5576 | protected | ||
| 5577 | BackendDAE.Shared shared; | ||
| 5578 | algorithm | ||
| 5579 | ✗ | shared := inDAE.shared; | |
| 5580 | ✗ | BackendDAEUtil.traverseBackendDAEExpsVarsWithUpdate(shared.globalKnownVars, traverserapplyRewriteRulesBackend, false); | |
| 5581 | ✗ | BackendDAEUtil.traverseBackendDAEExpsEqns(shared.initialEqs, traverserapplyRewriteRulesBackend, false); | |
| 5582 | ✗ | BackendDAEUtil.traverseBackendDAEExpsEqns(shared.removedEqs, traverserapplyRewriteRulesBackend, false); | |
| 5583 | // not sure if we should apply the rules on the event info! | ||
| 5584 | // (ei, _) := traverseEventInfoExps(eventInfo, traverserapplyRewriteRulesBackend, false); | ||
| 5585 | ✗ | outDAE := BackendDAE.DAE(inDAE.eqs, shared); | |
| 5586 | end applyRewriteRulesBackendShared; | ||
| 5587 | |||
| 5588 | // ============================================================================= | ||
| 5589 | // generates a list with all iteration variables | ||
| 5590 | // | ||
| 5591 | // ============================================================================= | ||
| 5592 | |||
| 5593 | public function listAllIterationVariables "author: lochel" | ||
| 5594 | input BackendDAE.BackendDAE inBackendDAE; | ||
| 5595 | protected | ||
| 5596 | BackendDAE.BackendDAEType backendDAEType; | ||
| 5597 | list<String> warnings; | ||
| 5598 | algorithm | ||
| 5599 | 4 | BackendDAE.DAE(shared=BackendDAE.SHARED(backendDAEType=backendDAEType)) := inBackendDAE; | |
| 5600 | 4 | (warnings, _) := listAllIterationVariables0(inBackendDAE.eqs); | |
| 5601 | |||
| 5602 | 4 | Error.addCompilerNotification("List of all iteration variables (DAE kind: " + BackendDump.printBackendDAEType2String(backendDAEType) + ")\n" + stringDelimitList(warnings, "\n")); | |
| 5603 | end listAllIterationVariables; | ||
| 5604 | |||
| 5605 | public function listAllIterationVariables0 "author: lochel" | ||
| 5606 | input list<BackendDAE.EqSystem> inEqs; | ||
| 5607 | output list<String> outWarnings; | ||
| 5608 | output list<DAE.ComponentRef> outComponentRef; | ||
| 5609 | protected | ||
| 5610 | list<String> warnings; | ||
| 5611 | list<DAE.ComponentRef> crefs; | ||
| 5612 | list<list<String>> warnings_accum = {}; | ||
| 5613 | list<list<DAE.ComponentRef>> crefs_accum = {}; | ||
| 5614 | algorithm | ||
| 5615 |
2/2✓ Branch 0 taken 44822 times.
✓ Branch 1 taken 1123 times.
|
45945 | for eq in inEqs loop |
| 5616 | 44822 | (warnings, crefs) := listAllIterationVariables1(eq); | |
| 5617 | warnings_accum := warnings :: warnings_accum; | ||
| 5618 | 44822 | crefs_accum := crefs :: crefs_accum; | |
| 5619 | end for; | ||
| 5620 | |||
| 5621 | 1123 | outWarnings := List.flattenReverse(warnings_accum); | |
| 5622 | 1123 | outComponentRef := List.flattenReverse(crefs_accum); | |
| 5623 | end listAllIterationVariables0; | ||
| 5624 | |||
| 5625 | protected function listAllIterationVariables1 "author: lochel" | ||
| 5626 | input BackendDAE.EqSystem inEqSystem; | ||
| 5627 | output list<String> outWarning; | ||
| 5628 | output list<DAE.ComponentRef> outComponentRef; | ||
| 5629 | protected | ||
| 5630 | BackendDAE.Variables vars; | ||
| 5631 | BackendDAE.StrongComponents comps; | ||
| 5632 | algorithm | ||
| 5633 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 44822 times.
|
44822 | BackendDAE.EQSYSTEM(orderedVars=vars, |
| 5634 | matching=BackendDAE.MATCHING(comps=comps)) := inEqSystem; | ||
| 5635 | 44822 | (outWarning, outComponentRef) := listAllIterationVariables2(comps, vars); | |
| 5636 | end listAllIterationVariables1; | ||
| 5637 | |||
| 5638 | protected function listAllIterationVariables2 | ||
| 5639 | input BackendDAE.StrongComponents comps; | ||
| 5640 | input BackendDAE.Variables vars; | ||
| 5641 | output list<String> warnings = {}; | ||
| 5642 | output list<DAE.ComponentRef> componentRefs = {}; | ||
| 5643 | protected | ||
| 5644 | list<Integer> var_idxs, var_idxs2; | ||
| 5645 | |||
| 5646 | constant String NONLINEAR_SYSTEM = "Iteration variables of nonlinear equation system:\n"; | ||
| 5647 | constant String ANALYTIC_JACOBIAN = "Iteration variables of equation system with analytic Jacobian:\n"; | ||
| 5648 | constant String NO_ANALYTIC_JACOBIAN = "Iteration variables of equation system without analytic Jacobian:\n"; | ||
| 5649 | constant String TORN_LINEAR = "Iteration variables of torn linear equation system:\n"; | ||
| 5650 | constant String TORN_NONLINEAR = "Iteration variables of torn nonlinear equation system:\n"; | ||
| 5651 | algorithm | ||
| 5652 |
2/2✓ Branch 1 taken 92463 times.
✓ Branch 2 taken 44822 times.
|
137285 | for comp in listReverse(comps) loop |
| 5653 | (warnings, componentRefs) := match comp | ||
| 5654 | case BackendDAE.EQUATIONSYSTEM(jacType = BackendDAE.JAC_NONLINEAR()) | ||
| 5655 | ✗ | then listAllIterationVariables3(comp.vars, vars, NONLINEAR_SYSTEM, warnings, componentRefs); | |
| 5656 | |||
| 5657 | case BackendDAE.EQUATIONSYSTEM(jacType = BackendDAE.JAC_GENERIC()) | ||
| 5658 | 175 | then listAllIterationVariables3(comp.vars, vars, ANALYTIC_JACOBIAN, warnings, componentRefs); | |
| 5659 | |||
| 5660 | case BackendDAE.EQUATIONSYSTEM(jacType = BackendDAE.JAC_NO_ANALYTIC()) | ||
| 5661 | 1 | then listAllIterationVariables3(comp.vars, vars, NO_ANALYTIC_JACOBIAN, warnings, componentRefs); | |
| 5662 | |||
| 5663 | case BackendDAE.TORNSYSTEM(strictTearingSet = BackendDAE.TEARINGSET(tearingvars = var_idxs), | ||
| 5664 | casualTearingSet = NONE()) | ||
| 5665 |
2/2✓ Branch 0 taken 329 times.
✓ Branch 1 taken 410 times.
|
1068 | then listAllIterationVariables3(var_idxs, vars, |
| 5666 | if comp.linear then TORN_LINEAR else TORN_NONLINEAR, warnings, componentRefs); | ||
| 5667 | |||
| 5668 | case BackendDAE.TORNSYSTEM(strictTearingSet = BackendDAE.TEARINGSET(tearingvars = var_idxs), | ||
| 5669 | casualTearingSet = SOME(BackendDAE.TEARINGSET(tearingvars = var_idxs2))) | ||
| 5670 | ✗ | then | |
| 5671 | listAllIterationVariables3(List.union(var_idxs, var_idxs2), vars, | ||
| 5672 | if comp.linear then TORN_LINEAR else TORN_NONLINEAR, warnings, componentRefs); | ||
| 5673 | |||
| 5674 | 91548 | else (warnings, componentRefs); | |
| 5675 | end match; | ||
| 5676 | end for; | ||
| 5677 | end listAllIterationVariables2; | ||
| 5678 | |||
| 5679 | protected function listAllIterationVariables3 | ||
| 5680 | input list<Integer> varIndices; | ||
| 5681 | input BackendDAE.Variables allVars; | ||
| 5682 | input String message; | ||
| 5683 | input output list<String> warnings; | ||
| 5684 | input output list<DAE.ComponentRef> crefs; | ||
| 5685 | protected | ||
| 5686 | list<BackendDAE.Var> vars; | ||
| 5687 | algorithm | ||
| 5688 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 915 times.
|
915 | if not listEmpty(varIndices) then |
| 5689 |
4/4✓ Branch 0 taken 3422 times.
✓ Branch 1 taken 915 times.
✓ Branch 2 taken 3422 times.
✓ Branch 3 taken 915 times.
|
4337 | vars := list(BackendVariable.getVarAt(allVars, v) for v in varIndices); |
| 5690 |
4/4✓ Branch 0 taken 3422 times.
✓ Branch 1 taken 915 times.
✓ Branch 2 taken 3422 times.
✓ Branch 3 taken 915 times.
|
4337 | crefs := List.append_reverse(list(BackendVariable.varCref(v) for v in vars), crefs); |
| 5691 | 915 | warnings := (message + warnAboutVars(vars)) :: warnings; | |
| 5692 | end if; | ||
| 5693 | end listAllIterationVariables3; | ||
| 5694 | |||
| 5695 | protected function warnAboutVars | ||
| 5696 | input list<BackendDAE.Var> vars; | ||
| 5697 | output String str; | ||
| 5698 | algorithm | ||
| 5699 |
4/4✓ Branch 0 taken 3422 times.
✓ Branch 1 taken 915 times.
✓ Branch 2 taken 3422 times.
✓ Branch 3 taken 915 times.
|
4337 | str := stringDelimitList(list(" " + BackendDump.varString(v) for v in vars), "\n"); |
| 5700 | end warnAboutVars; | ||
| 5701 | |||
| 5702 | public function addTimeAsState | ||
| 5703 | input BackendDAE.BackendDAE inDAE; | ||
| 5704 | output BackendDAE.BackendDAE outDAE = inDAE; | ||
| 5705 | protected | ||
| 5706 | BackendDAE.EqSystems eqs; | ||
| 5707 | BackendDAE.EqSystem eq; | ||
| 5708 | BackendDAE.Shared shared; | ||
| 5709 | BackendDAE.Variables orderedVars "ordered Variables, only states and alg. vars"; | ||
| 5710 | BackendDAE.EquationArray orderedEqs "ordered Equations"; | ||
| 5711 | BackendDAE.Var var; | ||
| 5712 | algorithm | ||
| 5713 | ✗ | (BackendDAE.DAE(eqs, shared), _) := BackendDAEUtil.mapEqSystemAndFold(inDAE, addTimeAsState1, 0); | |
| 5714 | ✗ | orderedVars := BackendVariable.emptyVars(); | |
| 5715 | var := BackendDAE.VAR(DAE.crefTimeState, BackendDAE.STATE(1, NONE(), true), DAE.BIDIR(), DAE.NON_PARALLEL(), DAE.T_REAL_DEFAULT, NONE(), NONE(), {}, DAE.emptyElementSource, NONE(), NONE(), NONE(), NONE(), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER(), true, false, false); | ||
| 5716 | ✗ | var := BackendVariable.setVarFixed(var, true); | |
| 5717 | ✗ | var := BackendVariable.setVarStartValue(var, DAE.CREF(DAE.crefTime, DAE.T_REAL_DEFAULT)); | |
| 5718 | ✗ | orderedVars := BackendVariable.addVar(var, orderedVars); | |
| 5719 | ✗ | orderedEqs := BackendEquation.emptyEqnsSized(1); | |
| 5720 | ✗ | orderedEqs := BackendEquation.add(BackendDAE.EQUATION(DAE.CALL(Absyn.IDENT("der"), {DAE.CREF(DAE.crefTimeState, DAE.T_REAL_DEFAULT)}, DAE.callAttrBuiltinReal), DAE.RCONST(1.0), DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC), orderedEqs); | |
| 5721 | ✗ | eq := BackendDAEUtil.createEqSystem(orderedVars, orderedEqs, {}, BackendDAE.CONTINUOUS_TIME_PARTITION()); | |
| 5722 | ✗ | outDAE := BackendDAE.DAE(eq::eqs, shared); | |
| 5723 | end addTimeAsState; | ||
| 5724 | |||
| 5725 | protected function addTimeAsState1 | ||
| 5726 | input BackendDAE.EqSystem inSystem; | ||
| 5727 | input BackendDAE.Shared inShared; | ||
| 5728 | input Integer inFoo; | ||
| 5729 | output BackendDAE.EqSystem outSystem; | ||
| 5730 | output BackendDAE.Shared outShared = inShared; | ||
| 5731 | output Integer outFoo = inFoo; | ||
| 5732 | algorithm | ||
| 5733 | outSystem := matchcontinue inSystem | ||
| 5734 | local | ||
| 5735 | BackendDAE.EquationArray orderedEqs; | ||
| 5736 | BackendDAE.EqSystem syst; | ||
| 5737 | |||
| 5738 | case syst as BackendDAE.EQSYSTEM( orderedEqs=orderedEqs) | ||
| 5739 | algorithm | ||
| 5740 | ✗ | BackendEquation.traverseEquationArray_WithUpdate(orderedEqs, addTimeAsState2, inFoo); | |
| 5741 | then syst; | ||
| 5742 | |||
| 5743 | else inSystem; | ||
| 5744 | end matchcontinue; | ||
| 5745 | end addTimeAsState1; | ||
| 5746 | |||
| 5747 | protected function addTimeAsState2 | ||
| 5748 | input BackendDAE.Equation inEq; | ||
| 5749 | input Integer inFoo; | ||
| 5750 | output BackendDAE.Equation outEq; | ||
| 5751 | output Integer outFoo = inFoo; | ||
| 5752 | algorithm | ||
| 5753 | ✗ | (outEq, _) := BackendEquation.traverseExpsOfEquation(inEq, addTimeAsState3, inFoo); | |
| 5754 | end addTimeAsState2; | ||
| 5755 | |||
| 5756 | protected function addTimeAsState3 | ||
| 5757 | input DAE.Exp inExp; | ||
| 5758 | input Integer inTuple; | ||
| 5759 | output DAE.Exp outExp; | ||
| 5760 | output Integer outTuple; | ||
| 5761 | algorithm | ||
| 5762 | ✗ | (outExp, outTuple) := Expression.traverseExpTopDown(inExp, addTimeAsState4, inTuple); | |
| 5763 | end addTimeAsState3; | ||
| 5764 | |||
| 5765 | protected function addTimeAsState4 | ||
| 5766 | input DAE.Exp inExp; | ||
| 5767 | input Integer inTuple; | ||
| 5768 | output DAE.Exp outExp; | ||
| 5769 | output Boolean cont = true; | ||
| 5770 | output Integer outTuple = inTuple; | ||
| 5771 | algorithm | ||
| 5772 | outExp := match inExp | ||
| 5773 | local | ||
| 5774 | DAE.Type ty; | ||
| 5775 | |||
| 5776 | case DAE.CREF(componentRef=DAE.CREF_IDENT(ident="time"), ty=ty) algorithm | ||
| 5777 | ✗ | then DAE.CREF(DAE.crefTimeState, ty); | |
| 5778 | |||
| 5779 | else inExp; | ||
| 5780 | end match; | ||
| 5781 | end addTimeAsState4; | ||
| 5782 | |||
| 5783 | //------------------------------------- | ||
| 5784 | //Evaluate Output Variables Only. | ||
| 5785 | //------------------------------------- | ||
| 5786 | public function evaluateOutputsOnly"Computes only the scc which are necessary in order to calculate the output vars. | ||
| 5787 | author: Waurich TUD 09/2015" | ||
| 5788 | input BackendDAE.BackendDAE daeIn; | ||
| 5789 | output BackendDAE.BackendDAE daeOut; | ||
| 5790 | protected | ||
| 5791 | Integer size, nVars, nEqs; | ||
| 5792 | array<Integer> ass1,ass2, varVisited; | ||
| 5793 | list<Integer> outputVarIndxs, stateIndxs, stateTasks, stateTasks1 , outputTasks, predecessors, tasks; | ||
| 5794 | list<BackendDAE.StrongComponent> comps, compsNew, addComps; | ||
| 5795 | BackendDAE.StrongComponent comp; | ||
| 5796 | BackendDAE.EqSystem syst; | ||
| 5797 | BackendDAE.EqSystems systs, systsNew; | ||
| 5798 | BackendDAE.Equation eq; | ||
| 5799 | BackendDAE.EquationArray eqs; | ||
| 5800 | BackendDAE.AdjacencyMatrix m, mT; | ||
| 5801 | BackendDAE.Matching matching; | ||
| 5802 | BackendDAE.Shared shared; | ||
| 5803 | BackendDAE.Variables vars; | ||
| 5804 | AvlTreePathFunction.Tree funcTree; | ||
| 5805 | list<BackendDAE.Equation> eqLst, eqLstNew; | ||
| 5806 | list<BackendDAE.Var> varLst, varLstNew, states; | ||
| 5807 | list<DAE.ComponentRef> crefs; | ||
| 5808 | HpcOmTaskGraph.TaskGraph taskGraph, taskGraphT; | ||
| 5809 | HpcOmTaskGraph.TaskGraphMeta taskGraphData; | ||
| 5810 | array<tuple<Integer,Integer,Integer>> varCompMapping; | ||
| 5811 | array<tuple<Integer,Integer,Integer>> eqCompMapping; | ||
| 5812 | |||
| 5813 | array<list<Integer>> mapEqnIncRow; | ||
| 5814 | array<Integer> mapIncRowEqn; | ||
| 5815 | Integer systemNumber=0, numberOfSystems; | ||
| 5816 | |||
| 5817 | list<Integer> eqIndLst, eqIndexLst = {}; | ||
| 5818 | UnorderedMap<DAE.ComponentRef, DAE.Exp> der_replacement; | ||
| 5819 | BackendDAE.Var derVar; | ||
| 5820 | |||
| 5821 | constant Boolean debug = false; | ||
| 5822 | algorithm | ||
| 5823 | daeOut := daeIn; | ||
| 5824 | |||
| 5825 | 1 | BackendDAE.DAE(systs,shared) := daeIn; | |
| 5826 | 1 | BackendDAE.SHARED(functionTree = funcTree) := shared; | |
| 5827 | systsNew := {}; | ||
| 5828 | //traverse the simulation-DAE systems | ||
| 5829 | 1 | numberOfSystems := listLength(systs); | |
| 5830 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 time.
|
5 | for syst in systs loop |
| 5831 | systemNumber := systemNumber+1; | ||
| 5832 | 4 | BackendDAE.EQSYSTEM(orderedVars = vars, orderedEqs=eqs, matching=matching) := syst; | |
| 5833 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | BackendDAE.MATCHING(ass1=ass1, ass2=ass2, comps=comps) := matching; |
| 5834 | |||
| 5835 | // get taskgraph and transposed taskgraph for simulation eqsystem | ||
| 5836 | 4 | (taskGraph,taskGraphData) := HpcOmTaskGraph.getEmptyTaskGraph(0,0,0); | |
| 5837 | 4 | (taskGraph,taskGraphData,_) := HpcOmTaskGraph.createTaskGraph0(syst,shared,false,(taskGraph,taskGraphData,1)); | |
| 5838 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | HpcOmTaskGraph.TASKGRAPHMETA(varCompMapping=varCompMapping, eqCompMapping=eqCompMapping) := taskGraphData; |
| 5839 | size := arrayLength(taskGraph); | ||
| 5840 | 4 | taskGraphT := AdjacencyMatrix.transposeAdjacencyMatrix(taskGraph,size); | |
| 5841 | |||
| 5842 | //get output variables | ||
| 5843 | 4 | BackendDAE.EQSYSTEM(orderedVars = vars) := syst; | |
| 5844 | 4 | varLst := BackendVariable.varList(vars); | |
| 5845 | 4 | varLst := List.filterOnTrue(varLst,BackendVariable.isVarOnTopLevelAndOutput); | |
| 5846 | |||
| 5847 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 3 times.
|
4 | if not listEmpty(varLst) then |
| 5848 | |||
| 5849 | //THIS SYSTEM CONTAINS OUTPUT VARIABLES | ||
| 5850 | //------------------------------------- | ||
| 5851 | 1 | outputVarIndxs := BackendVariable.getVarIndexFromVars(varLst,vars); | |
| 5852 | 1 | outputTasks := List.map(List.map1(outputVarIndxs,Array.getIndexFirst,varCompMapping),Util.tuple31); | |
| 5853 | if debug then print("outputTasks "+stringDelimitList(List.map(outputTasks,intString),", ")+"\n"); end if; | ||
| 5854 | |||
| 5855 | //get all necessary components to calculate the outputs | ||
| 5856 | 1 | predecessors := HpcOmTaskGraph.getAllSuccessors(outputTasks,taskGraphT); | |
| 5857 | 1 | predecessors := List.sort(predecessors,intGt); | |
| 5858 | 1 | compsNew := List.map1(listAppend(outputTasks,predecessors),List.getIndexFirst,comps); | |
| 5859 | if debug then print("predecessors of outputs "+stringDelimitList(List.map(predecessors,intString),", ")+"\n"); end if; | ||
| 5860 | |||
| 5861 | //get equations from the new reduced set of comps | ||
| 5862 | 1 | eqLstNew := BackendDAEUtil.getStrongComponentEquations(compsNew,eqs,vars); | |
| 5863 | |||
| 5864 | // Get all state-variables which are needed in these equations and apply the same search for these equations. | ||
| 5865 | // The according state-derivatives have to be computed. | ||
| 5866 | stateTasks := {}; | ||
| 5867 | 1 | varVisited := arrayCreate(BackendVariable.varsSize(vars),-1); | |
| 5868 |
2/2✓ Branch 0 taken 178 times.
✓ Branch 1 taken 1 time.
|
179 | while not listEmpty(eqLstNew) loop |
| 5869 | 178 | eq::eqLstNew := eqLstNew; | |
| 5870 | if debug then print("eq: "+BackendDump.equationString(eq)+"\n"); end if; | ||
| 5871 | 178 | crefs := BackendEquation.equationCrefs(eq); | |
| 5872 | 178 | crefs := List.filter1OnTrue(crefs,BackendVariable.isState,vars); | |
| 5873 | 178 | (states,stateIndxs) := BackendVariable.getVarLst(crefs,vars); | |
| 5874 | 178 | (stateIndxs,states) := List.filter1OnTrueSync(stateIndxs,stateVarIsNotVisited,varVisited,states);//not yet visited | |
| 5875 |
2/2✓ Branch 0 taken 176 times.
✓ Branch 1 taken 2 times.
|
178 | if not listEmpty(stateIndxs) then |
| 5876 | if debug then print("states "+stringDelimitList(List.map(states,BackendDump.varString),"\n ")+"\n"); end if; | ||
| 5877 | 2 | List.map2_0(stateIndxs,Array.updateIndexFirst,1,varVisited); | |
| 5878 | //add the new tasks which are necessary for the states | ||
| 5879 | 2 | stateTasks1 := List.map(List.map1(stateIndxs,Array.getIndexFirst,varCompMapping),Util.tuple31); | |
| 5880 | 2 | stateTasks := List.append_reverse(stateTasks1,stateTasks); | |
| 5881 | //get their predecessor tasks, the corresponding comps and add their equations | ||
| 5882 | 2 | predecessors := HpcOmTaskGraph.getAllSuccessors(stateTasks1,taskGraphT); | |
| 5883 | 2 | addComps := List.map1(listAppend(stateTasks1,predecessors),List.getIndexFirst,comps); | |
| 5884 | 2 | eqLstNew := listAppend(BackendDAEUtil.getStrongComponentEquations(addComps,eqs,vars), eqLstNew); | |
| 5885 | end if; | ||
| 5886 | end while; | ||
| 5887 | 1 | stateTasks := Dangerous.listReverseInPlace(stateTasks); | |
| 5888 | |||
| 5889 | //get all necessary components to calculate the outputs and the state derivatives | ||
| 5890 | 1 | predecessors := HpcOmTaskGraph.getAllSuccessors(listAppend(outputTasks,stateTasks),taskGraphT); | |
| 5891 | 1 | tasks := List.sort(listAppend(predecessors,listAppend(outputTasks,stateTasks)),intGt); | |
| 5892 | if debug then print("predecessors of outputs and states "+stringDelimitList(List.map(tasks,intString),", ")+"\n"); end if; | ||
| 5893 | 1 | compsNew := List.map1(tasks,List.getIndexFirst,comps); | |
| 5894 | 1 | compsNew := List.unique(compsNew); | |
| 5895 | if debug then print("There have been "+intString(listLength(comps))+" SCCs and now there are "+intString(listLength(compsNew))+" SCCs.\n"); end if; | ||
| 5896 | |||
| 5897 | //get vars and equations from the new reduced set of comps and make a equationIdxMap | ||
| 5898 | eqLstNew := {}; | ||
| 5899 | varLstNew := {}; | ||
| 5900 |
2/2✓ Branch 0 taken 66 times.
✓ Branch 1 taken 1 time.
|
67 | for comp in compsNew loop |
| 5901 | 66 | (varLst,_,eqLst,eqIndLst) := BackendDAEUtil.getStrongComponentVarsAndEquations(comp,vars,eqs); | |
| 5902 | 66 | varLstNew := listAppend(varLst,varLstNew); | |
| 5903 | 66 | eqLstNew := listAppend(eqLst,eqLstNew); | |
| 5904 | 66 | eqIndexLst := listAppend(eqIndLst,eqIndexLst); | |
| 5905 | end for; | ||
| 5906 | |||
| 5907 | // causalize again | ||
| 5908 | 1 | syst.orderedVars := BackendVariable.listVar1(listReverse(varLstNew)); | |
| 5909 | syst.orderedEqs := BackendEquation.listEquation(listReverse(eqLstNew)); | ||
| 5910 | |||
| 5911 | syst.m := NONE(); | ||
| 5912 | syst.mT := NONE(); | ||
| 5913 | syst.matching := BackendDAE.NO_MATCHING(); | ||
| 5914 | 1 | (m,mT) := BackendDAEUtil.adjacencyMatrix(syst,BackendDAE.NORMAL(),NONE(),BackendDAEUtil.isInitializationDAE(shared)); | |
| 5915 | 1 | syst.m := SOME(m); | |
| 5916 | syst.mT := SOME(mT); | ||
| 5917 | 1 | nVars := listLength(varLstNew); | |
| 5918 | 1 | nEqs := listLength(eqLstNew); | |
| 5919 | 1 | ass1 := arrayCreate(nVars, -1); | |
| 5920 | 1 | ass2 := arrayCreate(nEqs, -1); | |
| 5921 | 1 | Matching.matchingExternalsetAdjacencyMatrix(nVars, nEqs, m); | |
| 5922 | 1 | BackendDAEEXT.matching(nVars, nEqs, 5, -1, 0.0, 1); | |
| 5923 | 1 | BackendDAEEXT.getAssignment(ass2, ass1); | |
| 5924 | 1 | matching := BackendDAE.MATCHING(ass1,ass2,compsNew); | |
| 5925 | 1 | syst.matching := matching; | |
| 5926 | |||
| 5927 | 2 | (syst, _, _, mapEqnIncRow, mapIncRowEqn) := BackendDAEUtil.getAdjacencyMatrixScalar(syst, BackendDAE.NORMAL(), SOME(funcTree), BackendDAEUtil.isInitializationDAE(shared)); | |
| 5928 | 1 | syst := BackendDAETransform.strongComponentsScalar(syst,shared,mapEqnIncRow,mapIncRowEqn); | |
| 5929 | 1 | syst.removedEqs := BackendEquation.emptyEqns(); | |
| 5930 | |||
| 5931 | systsNew := syst::systsNew; | ||
| 5932 | |||
| 5933 | // find unneeded vars and equations | ||
| 5934 | 1 | vars := BackendVariable.deleteVars(syst.orderedVars, vars); | |
| 5935 | 1 | eqs := BackendEquation.deleteList(eqs, eqIndexLst); | |
| 5936 | else | ||
| 5937 | if debug then print("No output variables in this system ("+intString(systemNumber)+"/"+intString(numberOfSystems)+")\n"); end if; | ||
| 5938 | end if; | ||
| 5939 | |||
| 5940 | // make unneeded state derivatives and add them to unneeded vars | ||
| 5941 | 4 | der_replacement := UnorderedMap.new<DAE.Exp>(ComponentReferenceBasics.hashComponentRef, ComponentReferenceBasics.crefEqual); | |
| 5942 |
2/2✓ Branch 1 taken 163 times.
✓ Branch 2 taken 4 times.
|
167 | for state in BackendVariable.varList(vars) loop |
| 5943 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 163 times.
|
163 | if BackendVariable.isStateVar(state) then |
| 5944 | ✗ | derVar := BackendVariable.makeVar(ComponentReference.prependStringCref("$DER_REM_", state.varName)); | |
| 5945 | ✗ | UnorderedMap.add(state.varName, Expression.crefExp(derVar.varName), der_replacement); | |
| 5946 | ✗ | vars := BackendVariable.addVar(derVar, vars); | |
| 5947 | end if; | ||
| 5948 | end for; | ||
| 5949 | |||
| 5950 | // replace unneeded der() calls with derivative crefs | ||
| 5951 | 4 | eqs := BackendEquation.traverseEquationArray_WithUpdate(eqs, function BackendEquation.traverseExpsOfEquation(inFunc = replaceDerCallOutputsOnly), der_replacement); | |
| 5952 | |||
| 5953 | // make unneeded vars parameters and equations initial equations | ||
| 5954 | 4 | (vars, _) := BackendVariable.traverseBackendDAEVarsWithUpdate(vars, BackendVariable.makeParamOutputsOnly, false); | |
| 5955 | 4 | (eqs, _) := BackendEquation.traverseEquationArray_WithUpdate(eqs,BackendEquation.setEquationKind, BackendDAE.INITIAL_EQUATION()); | |
| 5956 | |||
| 5957 | // add unneeded variables and equations | ||
| 5958 | 4 | shared.globalKnownVars := BackendVariable.addVariables(vars, shared.globalKnownVars); | |
| 5959 | shared.initialEqs := BackendEquation.addList(BackendEquation.equationList(eqs), shared.initialEqs); | ||
| 5960 | end for; | ||
| 5961 | |||
| 5962 | // alias vars are not necessary anymore | ||
| 5963 | 1 | shared.aliasVars := BackendVariable.emptyVars(); | |
| 5964 | 1 | daeOut := BackendDAE.DAE(systsNew,shared); | |
| 5965 | end evaluateOutputsOnly; | ||
| 5966 | |||
| 5967 | protected function stateVarIsNotVisited"checks if the indexed entry in the array is less than 0" | ||
| 5968 | input Integer idx; | ||
| 5969 | input array<Integer> varArr; | ||
| 5970 | output Boolean b; | ||
| 5971 | algorithm | ||
| 5972 | 16 | b := intLt(arrayGet(varArr,idx),0); | |
| 5973 | end stateVarIsNotVisited; | ||
| 5974 | |||
| 5975 | protected function replaceDerCallOutputsOnly | ||
| 5976 | input output DAE.Exp exp; | ||
| 5977 | input output UnorderedMap<DAE.ComponentRef, DAE.Exp> der_replacement; | ||
| 5978 | algorithm | ||
| 5979 | exp := match exp | ||
| 5980 | local | ||
| 5981 | DAE.ComponentRef cr; | ||
| 5982 | case DAE.CALL(path = Absyn.IDENT("der"), expLst = {DAE.CREF(cr)}) | ||
| 5983 | ✗ | then UnorderedMap.getOrDefault(cr, der_replacement, exp); | |
| 5984 | else exp; | ||
| 5985 | end match; | ||
| 5986 | end replaceDerCallOutputsOnly; | ||
| 5987 | |||
| 5988 | // ============================================================================= | ||
| 5989 | // section for initOptModule >>inlineHomotopy<< | ||
| 5990 | // | ||
| 5991 | // ============================================================================= | ||
| 5992 | |||
| 5993 | public function inlineHomotopy | ||
| 5994 | input BackendDAE.BackendDAE inDAE; | ||
| 5995 | output BackendDAE.BackendDAE outDAE = inDAE; | ||
| 5996 | protected | ||
| 5997 | BackendDAE.EquationArray orderedEqs; | ||
| 5998 | Boolean foundHomotopy; | ||
| 5999 | algorithm | ||
| 6000 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
|
8 | for syst in inDAE.eqs loop |
| 6001 | 4 | orderedEqs := syst.orderedEqs; | |
| 6002 | 4 | (orderedEqs, foundHomotopy) := BackendEquation.traverseEquationArray_WithUpdate(orderedEqs, inlineHomotopy2, false); | |
| 6003 | 4 | syst.orderedEqs := orderedEqs; | |
| 6004 | end for; | ||
| 6005 | end inlineHomotopy; | ||
| 6006 | |||
| 6007 | protected function inlineHomotopy2 | ||
| 6008 | input BackendDAE.Equation inEq; | ||
| 6009 | input Boolean inFoundHomotopy; | ||
| 6010 | output BackendDAE.Equation outEq; | ||
| 6011 | output Boolean outFoundHomotopy = inFoundHomotopy; | ||
| 6012 | algorithm | ||
| 6013 |
3/4✓ Branch 0 taken 19 times.
✓ Branch 1 taken 22 times.
✓ Branch 3 taken 41 times.
✗ Branch 4 not taken.
|
60 | (outEq, outFoundHomotopy) := BackendEquation.traverseExpsOfEquation(inEq, inlineHomotopy3, inFoundHomotopy); |
| 6014 | end inlineHomotopy2; | ||
| 6015 | |||
| 6016 | protected function inlineHomotopy3 | ||
| 6017 | input DAE.Exp inExp; | ||
| 6018 | input Boolean inFoundHomotopy; | ||
| 6019 | output DAE.Exp outExp; | ||
| 6020 | output Boolean outFoundHomotopy = inFoundHomotopy; | ||
| 6021 | algorithm | ||
| 6022 |
3/4✓ Branch 0 taken 36 times.
✓ Branch 1 taken 46 times.
✓ Branch 3 taken 82 times.
✗ Branch 4 not taken.
|
118 | (outExp, outFoundHomotopy) := Expression.traverseExpTopDown(inExp, replaceHomotopyWithLambdaExpression, inFoundHomotopy); |
| 6023 | end inlineHomotopy3; | ||
| 6024 | |||
| 6025 | protected function replaceHomotopyWithLambdaExpression | ||
| 6026 | input DAE.Exp inExp; | ||
| 6027 | input Boolean inFoundHomotopy; | ||
| 6028 | output DAE.Exp outExp = inExp; | ||
| 6029 | output Boolean cont = true; | ||
| 6030 | output Boolean outFoundHomotopy; | ||
| 6031 | algorithm | ||
| 6032 | outFoundHomotopy := match inExp | ||
| 6033 | local | ||
| 6034 | DAE.Exp actual, simplified, lambda; | ||
| 6035 | |||
| 6036 | case DAE.CALL(path=Absyn.IDENT("homotopy"), expLst={actual,simplified}) | ||
| 6037 | algorithm | ||
| 6038 | 8 | lambda := Expression.crefExp(ComponentReferenceBasics.makeCrefIdent(BackendDAE.homotopyLambda, DAE.T_REAL_DEFAULT, {})); | |
| 6039 | 8 | outExp := DAE.BINARY(DAE.BINARY(simplified, DAE.MUL(DAE.T_REAL_DEFAULT), DAE.BINARY(DAE.RCONST(1.0), DAE.SUB(DAE.T_REAL_DEFAULT), lambda)), DAE.ADD(DAE.T_REAL_DEFAULT), DAE.BINARY(actual, DAE.MUL(DAE.T_REAL_DEFAULT), lambda)); | |
| 6040 | then true; | ||
| 6041 | |||
| 6042 | else inFoundHomotopy; | ||
| 6043 | end match; | ||
| 6044 | end replaceHomotopyWithLambdaExpression; | ||
| 6045 | |||
| 6046 | // ============================================================================= | ||
| 6047 | // section for initOptModule >>generateHomotopyComponents<< | ||
| 6048 | // | ||
| 6049 | // ============================================================================= | ||
| 6050 | |||
| 6051 | public function generateHomotopyComponents " finds the smallest homotopy loop and creates a component out of it | ||
| 6052 | author: ptaeuber 2017" | ||
| 6053 | input BackendDAE.BackendDAE inDAE; | ||
| 6054 | output BackendDAE.BackendDAE outDAE = inDAE; | ||
| 6055 | protected | ||
| 6056 | BackendDAE.StrongComponents comps; | ||
| 6057 | BackendDAE.EqSystems newEqSystems={}; | ||
| 6058 | array<Integer> ass1, ass2; | ||
| 6059 | algorithm | ||
| 6060 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | if Config.adaptiveHomotopy() then |
| 6061 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
|
8 | for syst in outDAE.eqs loop |
| 6062 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | BackendDAE.MATCHING(ass1=ass1, ass2=ass2, comps=comps) := syst.matching; |
| 6063 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
|
4 | if Config.globalHomotopy() then |
| 6064 | 2 | (comps, syst) := traverseStrongComponentsForHomotopyLoop(comps, syst); | |
| 6065 | else | ||
| 6066 | 2 | (comps, syst) := traverseStrongComponentsAddLambda(comps, syst); | |
| 6067 | end if; | ||
| 6068 | 8 | syst.matching := BackendDAE.MATCHING(ass1=ass1, ass2=ass2, comps=comps); | |
| 6069 | newEqSystems := syst::newEqSystems; | ||
| 6070 | end for; | ||
| 6071 | 4 | outDAE.eqs := listReverse(newEqSystems); | |
| 6072 | else | ||
| 6073 | ✗ | Error.addCompilerWarning("InitOptModule generateHomotopyComponents is activated for an equidistant homotopy method and will therefore be ignored."); | |
| 6074 | end if; | ||
| 6075 | end generateHomotopyComponents; | ||
| 6076 | |||
| 6077 | protected function traverseStrongComponentsForHomotopyLoop " traverses all the strong components and finds the smallest homotopy loop | ||
| 6078 | author: ptaeuber 2017" | ||
| 6079 | input output BackendDAE.StrongComponents comps; | ||
| 6080 | input output BackendDAE.EqSystem system; | ||
| 6081 | protected | ||
| 6082 | Integer nComps, compIndex=0, homotopyLoopBeginning=0, homotopyLoopEnd=0; | ||
| 6083 | BackendDAE.StrongComponents preHomotopyComponents, homotopyComponents, postHomotopyComponents; | ||
| 6084 | BackendDAE.StrongComponent homotopyComponent; | ||
| 6085 | BackendDAE.Var lambda; | ||
| 6086 | Integer lambdaIdx; | ||
| 6087 | algorithm | ||
| 6088 | 2 | nComps := listLength(comps); | |
| 6089 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 2 times.
|
15 | for comp in comps loop |
| 6090 |
2/9✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
|
13 | compIndex := compIndex + 1; |
| 6091 | () := match comp | ||
| 6092 | local | ||
| 6093 | Integer eqnIndex; | ||
| 6094 | list<Integer> eqnIndexes, resEqnIndexes, innerEqnIndexes; | ||
| 6095 | BackendDAE.InnerEquations innerEquations; | ||
| 6096 | BackendDAE.Equation eqn; | ||
| 6097 | list<BackendDAE.Equation> eqnLst; | ||
| 6098 | Boolean hasHomotopy; | ||
| 6099 | |||
| 6100 | case BackendDAE.SINGLEEQUATION(eqn=eqnIndex) | ||
| 6101 | algorithm | ||
| 6102 | 9 | eqn := BackendEquation.get(system.orderedEqs, eqnIndex); | |
| 6103 | 9 | (_, hasHomotopy) := BackendEquation.traverseExpsOfEquation(eqn, BackendDAEUtil.containsHomotopyCall, false); | |
| 6104 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7 times.
|
9 | if hasHomotopy then |
| 6105 | homotopyLoopEnd := compIndex; | ||
| 6106 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (homotopyLoopBeginning == 0) then |
| 6107 | homotopyLoopBeginning := compIndex; | ||
| 6108 | end if; | ||
| 6109 | end if; | ||
| 6110 | then(); | ||
| 6111 | |||
| 6112 | case BackendDAE.EQUATIONSYSTEM(eqns=eqnIndexes) | ||
| 6113 | algorithm | ||
| 6114 | ✗ | if (homotopyLoopBeginning == 0) then | |
| 6115 | ✗ | eqnLst := BackendEquation.getList(eqnIndexes, system.orderedEqs); | |
| 6116 | ✗ | (_, hasHomotopy) := BackendEquation.traverseExpsOfEquationList(eqnLst, BackendDAEUtil.containsHomotopyCall, false); | |
| 6117 | |||
| 6118 | ✗ | if hasHomotopy then | |
| 6119 | homotopyLoopBeginning := compIndex; | ||
| 6120 | homotopyLoopEnd := compIndex; | ||
| 6121 | end if; | ||
| 6122 | else | ||
| 6123 | homotopyLoopEnd := compIndex; | ||
| 6124 | end if; | ||
| 6125 | then(); | ||
| 6126 | |||
| 6127 | case BackendDAE.SINGLEARRAY(eqn=eqnIndex) | ||
| 6128 | algorithm | ||
| 6129 | ✗ | eqn := BackendEquation.get(system.orderedEqs, eqnIndex); | |
| 6130 | ✗ | (_, hasHomotopy) := BackendEquation.traverseExpsOfEquation(eqn, BackendDAEUtil.containsHomotopyCall, false); | |
| 6131 | |||
| 6132 | ✗ | if hasHomotopy then | |
| 6133 | homotopyLoopEnd := compIndex; | ||
| 6134 | ✗ | if (homotopyLoopBeginning == 0) then | |
| 6135 | homotopyLoopBeginning := compIndex; | ||
| 6136 | end if; | ||
| 6137 | end if; | ||
| 6138 | then(); | ||
| 6139 | |||
| 6140 | case BackendDAE.SINGLEALGORITHM(eqn=eqnIndex) | ||
| 6141 | algorithm | ||
| 6142 | ✗ | eqn := BackendEquation.get(system.orderedEqs, eqnIndex); | |
| 6143 | ✗ | (_, hasHomotopy) := BackendEquation.traverseExpsOfEquation(eqn, BackendDAEUtil.containsHomotopyCall, false); | |
| 6144 | |||
| 6145 | ✗ | if hasHomotopy then | |
| 6146 | homotopyLoopEnd := compIndex; | ||
| 6147 | ✗ | if (homotopyLoopBeginning == 0) then | |
| 6148 | homotopyLoopBeginning := compIndex; | ||
| 6149 | end if; | ||
| 6150 | end if; | ||
| 6151 | then(); | ||
| 6152 | |||
| 6153 | case BackendDAE.SINGLECOMPLEXEQUATION(eqn=eqnIndex) | ||
| 6154 | algorithm | ||
| 6155 | ✗ | eqn := BackendEquation.get(system.orderedEqs, eqnIndex); | |
| 6156 | ✗ | (_, hasHomotopy) := BackendEquation.traverseExpsOfEquation(eqn, BackendDAEUtil.containsHomotopyCall, false); | |
| 6157 | |||
| 6158 | ✗ | if hasHomotopy then | |
| 6159 | homotopyLoopEnd := compIndex; | ||
| 6160 | ✗ | if (homotopyLoopBeginning == 0) then | |
| 6161 | homotopyLoopBeginning := compIndex; | ||
| 6162 | end if; | ||
| 6163 | end if; | ||
| 6164 | then(); | ||
| 6165 | |||
| 6166 | case BackendDAE.SINGLEWHENEQUATION(eqn=eqnIndex) | ||
| 6167 | algorithm | ||
| 6168 | ✗ | eqn := BackendEquation.get(system.orderedEqs, eqnIndex); | |
| 6169 | ✗ | (_, hasHomotopy) := BackendEquation.traverseExpsOfEquation(eqn, BackendDAEUtil.containsHomotopyCall, false); | |
| 6170 | |||
| 6171 | ✗ | if hasHomotopy then | |
| 6172 | homotopyLoopEnd := compIndex; | ||
| 6173 | ✗ | if (homotopyLoopBeginning == 0) then | |
| 6174 | homotopyLoopBeginning := compIndex; | ||
| 6175 | end if; | ||
| 6176 | end if; | ||
| 6177 | then(); | ||
| 6178 | |||
| 6179 | case BackendDAE.SINGLEIFEQUATION(eqn=eqnIndex) | ||
| 6180 | algorithm | ||
| 6181 | ✗ | eqn := BackendEquation.get(system.orderedEqs, eqnIndex); | |
| 6182 | ✗ | (_, hasHomotopy) := BackendEquation.traverseExpsOfEquation(eqn, BackendDAEUtil.containsHomotopyCall, false); | |
| 6183 | |||
| 6184 | ✗ | if hasHomotopy then | |
| 6185 | homotopyLoopEnd := compIndex; | ||
| 6186 | ✗ | if (homotopyLoopBeginning == 0) then | |
| 6187 | homotopyLoopBeginning := compIndex; | ||
| 6188 | end if; | ||
| 6189 | end if; | ||
| 6190 | then(); | ||
| 6191 | |||
| 6192 | case BackendDAE.TORNSYSTEM(strictTearingSet=BackendDAE.TEARINGSET(residualequations=resEqnIndexes, innerEquations=innerEquations)) | ||
| 6193 | algorithm | ||
| 6194 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 3 times.
|
4 | if (homotopyLoopBeginning == 0) then |
| 6195 | 1 | eqnLst := BackendEquation.getList(resEqnIndexes, system.orderedEqs); | |
| 6196 | 1 | (_, hasHomotopy) := BackendEquation.traverseExpsOfEquationList(eqnLst, BackendDAEUtil.containsHomotopyCall, false); | |
| 6197 | |||
| 6198 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if not hasHomotopy then |
| 6199 | 1 | (innerEqnIndexes,_,_) := List.map_3(innerEquations, BackendDAEUtil.getEqnAndVarsFromInnerEquation); | |
| 6200 | 1 | eqnLst := BackendEquation.getList(innerEqnIndexes, system.orderedEqs); | |
| 6201 | 1 | (_, hasHomotopy) := BackendEquation.traverseExpsOfEquationList(eqnLst, BackendDAEUtil.containsHomotopyCall, false); | |
| 6202 | end if; | ||
| 6203 | |||
| 6204 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if hasHomotopy then |
| 6205 | homotopyLoopBeginning := compIndex; | ||
| 6206 | homotopyLoopEnd := compIndex; | ||
| 6207 | end if; | ||
| 6208 | else | ||
| 6209 | homotopyLoopEnd := compIndex; | ||
| 6210 | end if; | ||
| 6211 | then(); | ||
| 6212 | end match; | ||
| 6213 | end for; | ||
| 6214 | |||
| 6215 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if homotopyLoopBeginning > 0 then |
| 6216 | // Add homotopy lambda to system | ||
| 6217 | 2 | lambda := BackendDAE.VAR(ComponentReferenceBasics.makeCrefIdent(BackendDAE.homotopyLambda, DAE.T_REAL_DEFAULT, {}), BackendDAE.VARIABLE(), DAE.BIDIR(), DAE.NON_PARALLEL(), DAE.T_REAL_DEFAULT, NONE(), NONE(), {}, DAE.emptyElementSource, NONE(), NONE(), NONE(), NONE(), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER(), true, false, false); | |
| 6218 | 2 | system.orderedVars := BackendVariable.addVar(lambda, system.orderedVars); | |
| 6219 | 2 | lambdaIdx := BackendVariable.varsSize(system.orderedVars); | |
| 6220 | |||
| 6221 | 2 | (preHomotopyComponents, homotopyComponents, postHomotopyComponents) := getHomotopyComponents(List.intRange(nComps), comps, homotopyLoopBeginning, homotopyLoopEnd); | |
| 6222 | |||
| 6223 | 2 | homotopyComponent := createOneHomotopyComponent(homotopyComponents, system, lambdaIdx); | |
| 6224 | |||
| 6225 | 2 | comps := homotopyComponent::postHomotopyComponents; | |
| 6226 | 2 | comps := listAppend(preHomotopyComponents, comps); | |
| 6227 | end if; | ||
| 6228 | end traverseStrongComponentsForHomotopyLoop; | ||
| 6229 | |||
| 6230 | |||
| 6231 | protected function getHomotopyComponents " divides the components into pre-homotopy, homotopy and post-homotopy parts | ||
| 6232 | author: ptaeuber 2017" | ||
| 6233 | input list<Integer> componentIndexes; | ||
| 6234 | input BackendDAE.StrongComponents components; | ||
| 6235 | input Integer homotopyLoopBeginning; | ||
| 6236 | input Integer homotopyLoopEnd; | ||
| 6237 | input output BackendDAE.StrongComponents outPreHomotopyComponents = {}; | ||
| 6238 | input output BackendDAE.StrongComponents outHomotopyComponents = {}; | ||
| 6239 | input output BackendDAE.StrongComponents outPostHomotopyComponents = {}; | ||
| 6240 | algorithm | ||
| 6241 | (outPreHomotopyComponents, outHomotopyComponents, outPostHomotopyComponents) := match(componentIndexes, components) | ||
| 6242 | local | ||
| 6243 | Integer i; | ||
| 6244 | list<Integer> indexes; | ||
| 6245 | BackendDAE.StrongComponent comp; | ||
| 6246 | BackendDAE.StrongComponents comps; | ||
| 6247 | |||
| 6248 | case(i::{}, comp::{}) | ||
| 6249 | algorithm | ||
| 6250 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if intLt(i, homotopyLoopBeginning) then |
| 6251 | outPreHomotopyComponents := comp::outPreHomotopyComponents; | ||
| 6252 | elseif intGt(i, homotopyLoopEnd) then | ||
| 6253 | outPostHomotopyComponents := comp::outPostHomotopyComponents; | ||
| 6254 | else | ||
| 6255 | outHomotopyComponents := comp::outHomotopyComponents; | ||
| 6256 | end if; | ||
| 6257 | 2 | then (listReverse(outPreHomotopyComponents), listReverse(outHomotopyComponents), listReverse(outPostHomotopyComponents)); | |
| 6258 | |||
| 6259 | case(i::indexes, comp::comps) | ||
| 6260 | algorithm | ||
| 6261 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 7 times.
|
11 | if intLt(i, homotopyLoopBeginning) then |
| 6262 | outPreHomotopyComponents := comp::outPreHomotopyComponents; | ||
| 6263 | elseif intGt(i, homotopyLoopEnd) then | ||
| 6264 | outPostHomotopyComponents := comp::outPostHomotopyComponents; | ||
| 6265 | else | ||
| 6266 | outHomotopyComponents := comp::outHomotopyComponents; | ||
| 6267 | end if; | ||
| 6268 | 11 | then getHomotopyComponents(indexes, comps, homotopyLoopBeginning, homotopyLoopEnd, outPreHomotopyComponents, outHomotopyComponents, outPostHomotopyComponents); | |
| 6269 | end match; | ||
| 6270 | end getHomotopyComponents; | ||
| 6271 | |||
| 6272 | protected function createOneHomotopyComponent " creates one BackendDAE.TORNSYSTEM out of all homotopy components | ||
| 6273 | author: ptaeuber 2017" | ||
| 6274 | input BackendDAE.StrongComponents homotopyComponents; | ||
| 6275 | input BackendDAE.EqSystem inSystem; | ||
| 6276 | input Integer lambdaIdx; | ||
| 6277 | output BackendDAE.StrongComponent outHomotopyComponent; | ||
| 6278 | protected | ||
| 6279 | BackendDAE.InnerEquations newInnerEquations = {}; | ||
| 6280 | list<Integer> newResEquations = {}; | ||
| 6281 | list<Integer> newIterationVars = {}; | ||
| 6282 | Boolean isMixed = false; | ||
| 6283 | algorithm | ||
| 6284 |
4/11✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 7 times.
✓ Branch 10 taken 2 times.
|
9 | for comp in homotopyComponents loop |
| 6285 | (newInnerEquations, newResEquations, newIterationVars) := match comp | ||
| 6286 | local | ||
| 6287 | Integer eqnIndex, varIndex; | ||
| 6288 | list<Integer> eqnIndexes, varIndexes, resEqnIndexes, tVarIndexes; | ||
| 6289 | BackendDAE.InnerEquations innerEquations; | ||
| 6290 | BackendDAE.InnerEquation newInnerEquation; | ||
| 6291 | Boolean mixedSystem; | ||
| 6292 | |||
| 6293 | case BackendDAE.SINGLEEQUATION(eqn=eqnIndex, var=varIndex) | ||
| 6294 | algorithm | ||
| 6295 | 4 | newInnerEquation := BackendDAE.INNEREQUATION(eqn=eqnIndex, vars={varIndex}); | |
| 6296 | then (newInnerEquation::newInnerEquations, newResEquations, newIterationVars); | ||
| 6297 | |||
| 6298 | case BackendDAE.EQUATIONSYSTEM(eqns=eqnIndexes, vars=varIndexes, mixedSystem=mixedSystem) | ||
| 6299 | algorithm | ||
| 6300 | ✗ | if mixedSystem then | |
| 6301 | isMixed := true; | ||
| 6302 | end if; | ||
| 6303 | ✗ | then (newInnerEquations, listAppend(newResEquations, eqnIndexes), listAppend(newIterationVars, varIndexes)); | |
| 6304 | |||
| 6305 | case BackendDAE.SINGLEARRAY(eqn=eqnIndex, vars=varIndexes) | ||
| 6306 | algorithm | ||
| 6307 | ✗ | newInnerEquation := BackendDAE.INNEREQUATION(eqn=eqnIndex, vars=varIndexes); | |
| 6308 | then (newInnerEquation::newInnerEquations, newResEquations, newIterationVars); | ||
| 6309 | |||
| 6310 | case BackendDAE.SINGLEALGORITHM(eqn=eqnIndex, vars=varIndexes) | ||
| 6311 | algorithm | ||
| 6312 | ✗ | newInnerEquation := BackendDAE.INNEREQUATION(eqn=eqnIndex, vars=varIndexes); | |
| 6313 | then (newInnerEquation::newInnerEquations, newResEquations, newIterationVars); | ||
| 6314 | |||
| 6315 | case BackendDAE.SINGLECOMPLEXEQUATION(eqn=eqnIndex, vars=varIndexes) | ||
| 6316 | algorithm | ||
| 6317 | ✗ | newInnerEquation := BackendDAE.INNEREQUATION(eqn=eqnIndex, vars=varIndexes); | |
| 6318 | then (newInnerEquation::newInnerEquations, newResEquations, newIterationVars); | ||
| 6319 | |||
| 6320 | case BackendDAE.SINGLEWHENEQUATION(eqn=eqnIndex, vars=varIndexes) | ||
| 6321 | algorithm | ||
| 6322 | ✗ | newInnerEquation := BackendDAE.INNEREQUATION(eqn=eqnIndex, vars=varIndexes); | |
| 6323 | then (newInnerEquation::newInnerEquations, newResEquations, newIterationVars); | ||
| 6324 | |||
| 6325 | case BackendDAE.SINGLEIFEQUATION(eqn=eqnIndex, vars=varIndexes) | ||
| 6326 | algorithm | ||
| 6327 | ✗ | newInnerEquation := BackendDAE.INNEREQUATION(eqn=eqnIndex, vars=varIndexes); | |
| 6328 | then (newInnerEquation::newInnerEquations, newResEquations, newIterationVars); | ||
| 6329 | |||
| 6330 | case BackendDAE.TORNSYSTEM(strictTearingSet=BackendDAE.TEARINGSET(residualequations=resEqnIndexes, tearingvars=tVarIndexes, innerEquations=innerEquations), mixedSystem=mixedSystem) | ||
| 6331 | algorithm | ||
| 6332 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | if mixedSystem then |
| 6333 | isMixed := true; | ||
| 6334 | end if; | ||
| 6335 |
2/2✓ Branch 1 taken 6 times.
✓ Branch 2 taken 3 times.
|
9 | for innerEquation in innerEquations loop |
| 6336 | newInnerEquations := innerEquation::newInnerEquations; | ||
| 6337 | end for; | ||
| 6338 | 3 | then (newInnerEquations, listAppend(newResEquations, resEqnIndexes), listAppend(newIterationVars, tVarIndexes)); | |
| 6339 | end match; | ||
| 6340 | end for; | ||
| 6341 | |||
| 6342 |
1/2✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
|
4 | outHomotopyComponent := BackendDAE.TORNSYSTEM(BackendDAE.TEARINGSET(listAppend(newIterationVars,{lambdaIdx}), newResEquations, listReverse(newInnerEquations), BackendDAE.EMPTY_JACOBIAN()), NONE(), false, isMixed); |
| 6343 | end createOneHomotopyComponent; | ||
| 6344 | |||
| 6345 | protected function traverseStrongComponentsAddLambda " traverses all the strong components and adds lambda as the last variable if the system contains homotopy | ||
| 6346 | author: ptaeuber 2017" | ||
| 6347 | input output BackendDAE.StrongComponents comps; | ||
| 6348 | input output BackendDAE.EqSystem system; | ||
| 6349 | protected | ||
| 6350 | BackendDAE.StrongComponents newComps={}; | ||
| 6351 | BackendDAE.Var lambda; | ||
| 6352 | Integer lambdaIdx; | ||
| 6353 | Boolean hasAnyHomotopy = false; | ||
| 6354 | algorithm | ||
| 6355 | 2 | lambdaIdx := BackendVariable.varsSize(system.orderedVars) + 1; | |
| 6356 | |||
| 6357 |
2/2✓ Branch 0 taken 11 times.
✓ Branch 1 taken 2 times.
|
13 | for comp in comps loop |
| 6358 | comp := match comp | ||
| 6359 | local | ||
| 6360 | list<Integer> eqnIndexes, varIndexes, resEqnIndexes, tVarIndexes, innerEqnIndexes; | ||
| 6361 | Option<BackendDAE.TearingSet> casualTearingSet; | ||
| 6362 | BackendDAE.InnerEquations innerEquations; | ||
| 6363 | BackendDAE.Jacobian jac; | ||
| 6364 | BackendDAE.JacobianType jacType; | ||
| 6365 | list<BackendDAE.Equation> eqnLst; | ||
| 6366 | Boolean linear, mixedSystem, hasHomotopy; | ||
| 6367 | |||
| 6368 | case BackendDAE.EQUATIONSYSTEM(eqns=eqnIndexes, vars=varIndexes, jac=jac, jacType=jacType, mixedSystem=mixedSystem) | ||
| 6369 | algorithm | ||
| 6370 | ✗ | eqnLst := BackendEquation.getList(eqnIndexes, system.orderedEqs); | |
| 6371 | ✗ | (_, hasHomotopy) := BackendEquation.traverseExpsOfEquationList(eqnLst, BackendDAEUtil.containsHomotopyCall, false); | |
| 6372 | |||
| 6373 | ✗ | if hasHomotopy then | |
| 6374 | hasAnyHomotopy := true; | ||
| 6375 | // Add lambda in front of the list, list seems to be reversed later for EQUATIONSYSTEM | ||
| 6376 | ✗ | comp := BackendDAE.EQUATIONSYSTEM(eqnIndexes, lambdaIdx::varIndexes, jac, jacType, mixedSystem); | |
| 6377 | end if; | ||
| 6378 | then comp; | ||
| 6379 | |||
| 6380 | case BackendDAE.TORNSYSTEM(strictTearingSet=BackendDAE.TEARINGSET(residualequations=resEqnIndexes, tearingvars=tVarIndexes, innerEquations=innerEquations, jac=jac), casualTearingSet=casualTearingSet, linear=linear, mixedSystem=mixedSystem) | ||
| 6381 | algorithm | ||
| 6382 | 5 | eqnLst := BackendEquation.getList(resEqnIndexes, system.orderedEqs); | |
| 6383 | 5 | (_, hasHomotopy) := BackendEquation.traverseExpsOfEquationList(eqnLst, BackendDAEUtil.containsHomotopyCall, false); | |
| 6384 | |||
| 6385 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 time.
|
5 | if not hasHomotopy then |
| 6386 | 4 | (innerEqnIndexes,_,_) := List.map_3(innerEquations, BackendDAEUtil.getEqnAndVarsFromInnerEquation); | |
| 6387 | 4 | eqnLst := BackendEquation.getList(innerEqnIndexes, system.orderedEqs); | |
| 6388 | 4 | (_, hasHomotopy) := BackendEquation.traverseExpsOfEquationList(eqnLst, BackendDAEUtil.containsHomotopyCall, false); | |
| 6389 | end if; | ||
| 6390 | |||
| 6391 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
|
5 | if hasHomotopy then |
| 6392 | hasAnyHomotopy := true; | ||
| 6393 |
2/4✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
6 | comp := BackendDAE.TORNSYSTEM(BackendDAE.TEARINGSET(listAppend(tVarIndexes, {lambdaIdx}), resEqnIndexes, innerEquations, jac), casualTearingSet, linear, mixedSystem); |
| 6394 | end if; | ||
| 6395 | then comp; | ||
| 6396 | else comp; | ||
| 6397 | end match; | ||
| 6398 | newComps := comp::newComps; | ||
| 6399 | end for; | ||
| 6400 | |||
| 6401 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if hasAnyHomotopy then |
| 6402 | // Add homotopy lambda to system | ||
| 6403 | 2 | lambda := BackendDAE.VAR(ComponentReferenceBasics.makeCrefIdent(BackendDAE.homotopyLambda, DAE.T_REAL_DEFAULT, {}), BackendDAE.VARIABLE(), DAE.BIDIR(), DAE.NON_PARALLEL(), DAE.T_REAL_DEFAULT, NONE(), NONE(), {}, DAE.emptyElementSource, NONE(), NONE(), NONE(), NONE(), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER(), true, false, false); | |
| 6404 | 2 | system.orderedVars := BackendVariable.addVar(lambda, system.orderedVars); | |
| 6405 | end if; | ||
| 6406 | 2 | comps := listReverse(newComps); | |
| 6407 | end traverseStrongComponentsAddLambda; | ||
| 6408 | |||
| 6409 | annotation(__OpenModelica_Interface="backend"); | ||
| 6410 | end BackendDAEOptimize; | ||
| 6411 |