OMCompiler/Compiler/NSimCode/NSimVar.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 NSimVar | ||
| 37 | "file: NSimVar.mo | ||
| 38 | package: NSimVar | ||
| 39 | description: This file contains the data types and functions for variables | ||
| 40 | in simulation code phase. | ||
| 41 | " | ||
| 42 | protected | ||
| 43 | // OF imports | ||
| 44 | import DAE; | ||
| 45 | import SCode; | ||
| 46 | |||
| 47 | // NF imports | ||
| 48 | import NFBackendExtension.{BackendInfo, VariableAttributes, VariableKind}; | ||
| 49 | import Binding = NFBinding; | ||
| 50 | import ComponentRef = NFComponentRef; | ||
| 51 | import Dimension = NFDimension; | ||
| 52 | import Expression = NFExpression; | ||
| 53 | import NFInstNode.InstNode; | ||
| 54 | import Operator = NFOperator; | ||
| 55 | import Prefixes = NFPrefixes; | ||
| 56 | import SimplifyExp = NFSimplifyExp; | ||
| 57 | import Type = NFType; | ||
| 58 | import Variable = NFVariable; | ||
| 59 | import MetaModelica.Dangerous.listReverseInPlace; | ||
| 60 | import NBVariable.VariablePointers; | ||
| 61 | |||
| 62 | // Old Backend imports | ||
| 63 | import OldBackendDAE = BackendDAE; | ||
| 64 | |||
| 65 | // Backend imports | ||
| 66 | import BVariable = NBVariable; | ||
| 67 | import NBEquation.Equation; | ||
| 68 | import NBEvents.{EventInfo, Condition, MathEvent}; | ||
| 69 | import NBPartition.Partition; | ||
| 70 | import Slice = NBSlice; | ||
| 71 | import StrongComponent = NBStrongComponent; | ||
| 72 | |||
| 73 | // Old Simcode imports | ||
| 74 | import OldSimCode = SimCode; | ||
| 75 | import OldSimCodeVar = SimCodeVar; | ||
| 76 | |||
| 77 | // SimCode imports | ||
| 78 | import SimCode = NSimCode; | ||
| 79 | import NSimCode.SimCodeIndices; | ||
| 80 | |||
| 81 | // Util imports | ||
| 82 | import Config; | ||
| 83 | import Error; | ||
| 84 | import Pointer; | ||
| 85 | import PointerWeak; | ||
| 86 | import StringUtil; | ||
| 87 | import Util; | ||
| 88 | |||
| 89 | public | ||
| 90 | type ConvertEntry = tuple<SimVar, OldSimCodeVar.SimVar>; | ||
| 91 | type ConvertMemo = UnorderedMap<ComponentRef, ConvertEntry> "SimVar -> old SimVar conversions already made"; | ||
| 92 | |||
| 93 | uniontype SimVar "Information about a variable in a Modelica model." | ||
| 94 | record SIMVAR | ||
| 95 | ComponentRef name; | ||
| 96 | VariableKind varKind; | ||
| 97 | String comment; | ||
| 98 | String unit; | ||
| 99 | String displayUnit; | ||
| 100 | Integer index; | ||
| 101 | Option<Expression> min; | ||
| 102 | Option<Expression> max; | ||
| 103 | Option<Expression> start; | ||
| 104 | Option<Expression> nominal; | ||
| 105 | Boolean isFixed; | ||
| 106 | Type type_; | ||
| 107 | Boolean isDiscrete; | ||
| 108 | Option<ComponentRef> arrayCref "the name of the array if this variable is the first in that array"; | ||
| 109 | Alias aliasvar; | ||
| 110 | SourceInfo info; | ||
| 111 | Option<Causality> causality; | ||
| 112 | Option<Integer> variable_index "valueReference"; | ||
| 113 | Option<Integer> fmi_index "index of variable in modelDescription.xml"; | ||
| 114 | list<Expression> numArrayElement; | ||
| 115 | Boolean isValueChangeable; | ||
| 116 | Boolean isProtected; | ||
| 117 | Boolean hideResult; | ||
| 118 | Boolean isEncrypted; | ||
| 119 | Option<array<Integer>> inputIndex; | ||
| 120 | Option<String> matrixName "if the varibale is a jacobian var, this is the corresponding matrix"; | ||
| 121 | Option<Variability> variability "FMI-2.0 variabilty attribute"; | ||
| 122 | Option<Initial> initial_ "FMI-2.0 initial attribute"; | ||
| 123 | Option<ComponentRef> exportVar "variables will only be exported to the modelDescription.xml if this attribute is SOME(cref) and this cref is only used in ModelDescription.xml for FMI-2.0 export"; | ||
| 124 | Boolean isConnectorFlow "true if the variable is a flow connector member (FMI 3.0 terminal variableKind inflow/outflow)"; | ||
| 125 | end SIMVAR; | ||
| 126 | |||
| 127 | function toString | ||
| 128 | input SimVar var; | ||
| 129 | input output String str = ""; | ||
| 130 | algorithm | ||
| 131 | 250 | str := str + "(" + intString(var.index) + ")" + VariableKind.toString(var.varKind) | |
| 132 | + " (" + intString(SimVar.size(var)) + ") " + Type.toString(var.type_) + " " + ComponentRef.toString(var.name); | ||
| 133 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 250 times.
✓ Branch 2 taken 40 times.
✓ Branch 3 taken 210 times.
|
250 | if isSome(var.start) then |
| 134 | 40 | str := str + " = " + Expression.toString(Util.getOption(var.start)); | |
| 135 | end if; | ||
| 136 | end toString; | ||
| 137 | |||
| 138 | function listToString | ||
| 139 | input list<SimVar> var_lst; | ||
| 140 | input output String str = ""; | ||
| 141 | input Boolean printAlias = false; | ||
| 142 | algorithm | ||
| 143 |
2/2✓ Branch 0 taken 17 times.
✓ Branch 1 taken 55 times.
|
72 | if not listEmpty(var_lst) then |
| 144 | 17 | str := StringUtil.headline_4(str + " (" + intString(listLength(var_lst)) + ")"); | |
| 145 |
2/2✓ Branch 0 taken 145 times.
✓ Branch 1 taken 17 times.
|
162 | for var in var_lst loop |
| 146 | 145 | str := str + toString(var, " "); | |
| 147 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 145 times.
|
145 | str := if printAlias then str + " " + Alias.toString(var.aliasvar) + "\n" else str + "\n"; |
| 148 | end for; | ||
| 149 | 17 | str := str + "\n"; | |
| 150 | else | ||
| 151 | str := ""; | ||
| 152 | end if; | ||
| 153 | end listToString; | ||
| 154 | |||
| 155 | function create | ||
| 156 | input Variable var; | ||
| 157 | output SimVar simVar; | ||
| 158 | input Integer uniqueIndex; | ||
| 159 | input Integer typeIndex; | ||
| 160 | input Alias alias = Alias.NO_ALIAS(); | ||
| 161 | algorithm | ||
| 162 | simVar := match var | ||
| 163 | local | ||
| 164 | VariableKind varKind; | ||
| 165 | String comment, unit, displayUnit; | ||
| 166 | Option<Expression> min; | ||
| 167 | Option<Expression> max; | ||
| 168 | Option<Expression> start; | ||
| 169 | Option<Expression> nominal; | ||
| 170 | Boolean isFixed, isDiscrete, isProtected, isValueChangeable; | ||
| 171 | Causality causality; | ||
| 172 | SimVar result; | ||
| 173 | |||
| 174 | case Variable.VARIABLE() algorithm | ||
| 175 | 21434 | comment := parseComment(var.comment); | |
| 176 | 21434 | (varKind, unit, displayUnit, min, max, start, nominal, isFixed, isDiscrete, isProtected) | |
| 177 | := parseAttributes(var.backendinfo); | ||
| 178 | // for parameters the binding supersedes the start value if it exists and is constant | ||
| 179 | // ToDo: also for other cases? (constant, struct param ...) | ||
| 180 | 21434 | (start, isValueChangeable, causality) := parseBinding(start, var); | |
| 181 |
14/16✓ Branch 1 taken 456 times.
✓ Branch 2 taken 21434 times.
✓ Branch 3 taken 456 times.
✓ Branch 4 taken 21434 times.
✓ Branch 7 taken 20520 times.
✓ Branch 8 taken 914 times.
✓ Branch 11 taken 21434 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 21434 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 19147 times.
✓ Branch 16 taken 2287 times.
✓ Branch 19 taken 13710 times.
✓ Branch 20 taken 7724 times.
✓ Branch 21 taken 14522 times.
✓ Branch 22 taken 6912 times.
|
134944 | result := SIMVAR( |
| 182 | name = var.name, | ||
| 183 | varKind = varKind, | ||
| 184 | comment = comment, | ||
| 185 | unit = unit, | ||
| 186 | displayUnit = displayUnit, | ||
| 187 | index = typeIndex, | ||
| 188 | min = min, | ||
| 189 | max = max, | ||
| 190 | start = start, | ||
| 191 | nominal = nominal, | ||
| 192 | isFixed = isFixed, | ||
| 193 | type_ = var.ty, | ||
| 194 | isDiscrete = isDiscrete, | ||
| 195 | arrayCref = ComponentRef.getArrayCrefOpt(var.name), | ||
| 196 | aliasvar = alias, | ||
| 197 | info = var.info, | ||
| 198 | causality = SOME(causality), | ||
| 199 | variable_index = SOME(uniqueIndex), | ||
| 200 | fmi_index = SOME(typeIndex), | ||
| 201 | // dimension sizes (row-major); empty for scalars. Used for FMI array variables. | ||
| 202 | numArrayElement = list(Dimension.sizeExp(dim) for dim in Type.arrayDims(var.ty)), | ||
| 203 | isValueChangeable = isValueChangeable, | ||
| 204 | isProtected = isProtected, | ||
| 205 | hideResult = var.backendinfo.annotations.hideResult, | ||
| 206 | isEncrypted = NFVariable.isEncrypted(var), | ||
| 207 | inputIndex = NONE(), | ||
| 208 | matrixName = NONE(), | ||
| 209 | variability = NONE(), | ||
| 210 | initial_ = NONE(), | ||
| 211 | exportVar = SOME(var.name), | ||
| 212 | isConnectorFlow = Variable.isFlow(var) | ||
| 213 | ); | ||
| 214 | then result; | ||
| 215 | |||
| 216 | else algorithm | ||
| 217 | ✗ | Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed for variable " + ComponentRef.toString(var.name) + "."}); | |
| 218 | ✗ | then fail(); | |
| 219 | |||
| 220 | end match; | ||
| 221 | end create; | ||
| 222 | |||
| 223 | function traverseCreate | ||
| 224 | input output Variable var; | ||
| 225 | input Pointer<list<SimVar>> acc; | ||
| 226 | input Pointer<SimCode.SimCodeIndices> indices_ptr; | ||
| 227 | input VarType varType = VarType.SIMULATION; | ||
| 228 | protected | ||
| 229 | SimCode.SimCodeIndices simCodeIndices = Pointer.access(indices_ptr); | ||
| 230 | algorithm | ||
| 231 | () := match varType | ||
| 232 | |||
| 233 | case VarType.SIMULATION algorithm | ||
| 234 | ✗ | Pointer.update(acc, create(var, simCodeIndices.uniqueIndex, simCodeIndices.realVarIndex) :: Pointer.access(acc)); | |
| 235 | ✗ | simCodeIndices.uniqueIndex := simCodeIndices.uniqueIndex + 1; | |
| 236 | ✗ | simCodeIndices.realVarIndex := simCodeIndices.realVarIndex + 1; | |
| 237 | then (); | ||
| 238 | |||
| 239 | case VarType.PARAMETER algorithm | ||
| 240 | ✗ | Pointer.update(acc, create(var, simCodeIndices.uniqueIndex, simCodeIndices.realParamIndex) :: Pointer.access(acc)); | |
| 241 | ✗ | simCodeIndices.uniqueIndex := simCodeIndices.uniqueIndex + 1; | |
| 242 | ✗ | simCodeIndices.realParamIndex := simCodeIndices.realParamIndex + 1; | |
| 243 | then (); | ||
| 244 | |||
| 245 | case VarType.ALIAS algorithm | ||
| 246 | ✗ | Pointer.update(acc, create(var, simCodeIndices.uniqueIndex, simCodeIndices.realAliasIndex, Alias.fromBinding(var.binding)) :: Pointer.access(acc)); | |
| 247 | ✗ | simCodeIndices.uniqueIndex := simCodeIndices.uniqueIndex + 1; | |
| 248 | ✗ | simCodeIndices.realAliasIndex := simCodeIndices.realAliasIndex + 1; | |
| 249 | then (); | ||
| 250 | |||
| 251 | case VarType.RESIDUAL algorithm | ||
| 252 | 2 | Pointer.update(acc, create(var, simCodeIndices.uniqueIndex, simCodeIndices.residualIndex) :: Pointer.access(acc)); | |
| 253 | 1 | simCodeIndices.uniqueIndex := simCodeIndices.uniqueIndex + 1; | |
| 254 | 1 | simCodeIndices.residualIndex := simCodeIndices.residualIndex + 1; | |
| 255 | then (); | ||
| 256 | |||
| 257 | case VarType.EXTERNAL_OBJECT algorithm | ||
| 258 | ✗ | Pointer.update(acc, create(var, simCodeIndices.uniqueIndex, simCodeIndices.extObjIndex) :: Pointer.access(acc)); | |
| 259 | ✗ | simCodeIndices.uniqueIndex := simCodeIndices.uniqueIndex + 1; | |
| 260 | ✗ | simCodeIndices.extObjIndex := simCodeIndices.extObjIndex + 1; | |
| 261 | then (); | ||
| 262 | |||
| 263 | else algorithm | ||
| 264 | ✗ | Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed for variable " + ComponentRef.toString(var.name) + "."}); | |
| 265 | ✗ | then fail(); | |
| 266 | |||
| 267 | end match; | ||
| 268 | 1 | Pointer.update(indices_ptr, simCodeIndices); | |
| 269 | end traverseCreate; | ||
| 270 | |||
| 271 | function createList | ||
| 272 | "SimVars for scalar variables in list order, with running indices." | ||
| 273 | input list<Pointer<Variable>> vars; | ||
| 274 | input VarType varType; | ||
| 275 | output list<SimVar> simVars = {}; | ||
| 276 | input output SimCode.SimCodeIndices indices; | ||
| 277 | input Boolean elementIndex = false "the index of an array variable is the position of its first element"; | ||
| 278 | protected | ||
| 279 | Integer uniq = indices.uniqueIndex; | ||
| 280 | Integer idx = getTypeIndex(indices, varType); | ||
| 281 | Variable var; | ||
| 282 | algorithm | ||
| 283 |
2/2✓ Branch 0 taken 12320 times.
✓ Branch 1 taken 1817 times.
|
14137 | for var_ptr in vars loop |
| 284 | 12320 | var := Pointer.access(var_ptr); | |
| 285 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12320 times.
|
12320 | simVars := create(var, uniq, idx, if varType == VarType.ALIAS then Alias.fromBinding(var.binding) else Alias.NO_ALIAS()) :: simVars; |
| 286 | 12320 | uniq := uniq + 1; | |
| 287 |
2/2✓ Branch 0 taken 301 times.
✓ Branch 1 taken 12019 times.
|
12320 | idx := idx + (if elementIndex then Variable.size(var) else 1); |
| 288 | end for; | ||
| 289 | 1817 | simVars := listReverseInPlace(simVars); | |
| 290 | 1817 | indices.uniqueIndex := uniq; | |
| 291 | 1817 | indices := setTypeIndex(indices, varType, idx); | |
| 292 | end createList; | ||
| 293 | |||
| 294 | function createListsByType | ||
| 295 | "One SimVar list per basic type (real, integer, boolean, string, enumeration), | ||
| 296 | each with its own running index." | ||
| 297 | input list<Pointer<Variable>> vars; | ||
| 298 | input VarType varType; | ||
| 299 | output list<list<SimVar>> simVars; | ||
| 300 | input output SimCode.SimCodeIndices indices; | ||
| 301 | protected | ||
| 302 | Integer uniq = indices.uniqueIndex; | ||
| 303 | Integer real_idx, int_idx, bool_idx, string_idx, enum_idx; | ||
| 304 | list<SimVar> real_lst = {}, int_lst = {}, bool_lst = {}, string_lst = {}, enum_lst = {}; | ||
| 305 | Variable var; | ||
| 306 | Alias alias; | ||
| 307 | algorithm | ||
| 308 | 1316 | (real_idx, int_idx, bool_idx, string_idx, enum_idx) := getTypeIndices(indices, varType); | |
| 309 |
2/2✓ Branch 0 taken 9114 times.
✓ Branch 1 taken 1316 times.
|
10430 | for var_ptr in vars loop |
| 310 | 9114 | var := Pointer.access(var_ptr); | |
| 311 |
2/2✓ Branch 0 taken 1488 times.
✓ Branch 1 taken 7626 times.
|
9114 | alias := if varType == VarType.ALIAS then Alias.fromBinding(var.binding) else Alias.NO_ALIAS(); |
| 312 | () := match Type.arrayElementType(var.ty) | ||
| 313 | case Type.REAL() algorithm | ||
| 314 | 7572 | real_lst := create(var, uniq, real_idx, alias) :: real_lst; | |
| 315 | 7572 | real_idx := real_idx + 1; | |
| 316 | 7572 | uniq := uniq + 1; | |
| 317 | then (); | ||
| 318 | |||
| 319 | case Type.INTEGER() algorithm | ||
| 320 | 423 | int_lst := create(var, uniq, int_idx, alias) :: int_lst; | |
| 321 | 423 | int_idx := int_idx + 1; | |
| 322 | 423 | uniq := uniq + 1; | |
| 323 | then (); | ||
| 324 | |||
| 325 | case Type.BOOLEAN() algorithm | ||
| 326 | 1018 | bool_lst := create(var, uniq, bool_idx, alias) :: bool_lst; | |
| 327 | 1018 | bool_idx := bool_idx + 1; | |
| 328 | 1018 | uniq := uniq + 1; | |
| 329 | then (); | ||
| 330 | |||
| 331 | case Type.STRING() algorithm | ||
| 332 | 30 | string_lst := create(var, uniq, string_idx, alias) :: string_lst; | |
| 333 | 30 | string_idx := string_idx + 1; | |
| 334 | 30 | uniq := uniq + 1; | |
| 335 | then (); | ||
| 336 | |||
| 337 | case Type.ENUMERATION() algorithm | ||
| 338 | 70 | enum_lst := create(var, uniq, enum_idx, alias) :: enum_lst; | |
| 339 | 70 | enum_idx := enum_idx + 1; | |
| 340 | 70 | uniq := uniq + 1; | |
| 341 | then (); | ||
| 342 | |||
| 343 | // clock variables do not exist anymore | ||
| 344 | case Type.CLOCK() then (); | ||
| 345 | |||
| 346 | else algorithm | ||
| 347 | ✗ | Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed because of unhandled Variable " + ComponentRef.toString(var.name) + "."}); | |
| 348 | ✗ | then fail(); | |
| 349 | end match; | ||
| 350 | end for; | ||
| 351 | 6580 | simVars := {listReverseInPlace(real_lst), listReverseInPlace(int_lst), listReverseInPlace(bool_lst), | |
| 352 | listReverseInPlace(string_lst), listReverseInPlace(enum_lst)}; | ||
| 353 | 1316 | indices.uniqueIndex := uniq; | |
| 354 | 1316 | indices := setTypeIndices(indices, varType, real_idx, int_idx, bool_idx, string_idx, enum_idx); | |
| 355 | end createListsByType; | ||
| 356 | |||
| 357 | function getTypeIndex | ||
| 358 | input SimCode.SimCodeIndices indices; | ||
| 359 | input VarType varType; | ||
| 360 | output Integer idx; | ||
| 361 | algorithm | ||
| 362 | idx := match varType | ||
| 363 | 1441 | case VarType.SIMULATION then indices.realVarIndex; | |
| 364 | ✗ | case VarType.PARAMETER then indices.realParamIndex; | |
| 365 | ✗ | case VarType.ALIAS then indices.realAliasIndex; | |
| 366 | 188 | case VarType.RESIDUAL then indices.residualIndex; | |
| 367 | 188 | case VarType.EXTERNAL_OBJECT then indices.extObjIndex; | |
| 368 | end match; | ||
| 369 | end getTypeIndex; | ||
| 370 | |||
| 371 | function setTypeIndex | ||
| 372 | input output SimCode.SimCodeIndices indices; | ||
| 373 | input VarType varType; | ||
| 374 | input Integer idx; | ||
| 375 | algorithm | ||
| 376 | () := match varType | ||
| 377 | 1441 | case VarType.SIMULATION algorithm indices.realVarIndex := idx; then (); | |
| 378 | ✗ | case VarType.PARAMETER algorithm indices.realParamIndex := idx; then (); | |
| 379 | ✗ | case VarType.ALIAS algorithm indices.realAliasIndex := idx; then (); | |
| 380 | 188 | case VarType.RESIDUAL algorithm indices.residualIndex := idx; then (); | |
| 381 | 188 | case VarType.EXTERNAL_OBJECT algorithm indices.extObjIndex := idx; then (); | |
| 382 | end match; | ||
| 383 | end setTypeIndex; | ||
| 384 | |||
| 385 | function getTypeIndices | ||
| 386 | input SimCode.SimCodeIndices indices; | ||
| 387 | input VarType varType; | ||
| 388 | output Integer real_idx; | ||
| 389 | output Integer int_idx; | ||
| 390 | output Integer bool_idx; | ||
| 391 | output Integer string_idx; | ||
| 392 | output Integer enum_idx; | ||
| 393 | algorithm | ||
| 394 | (real_idx, int_idx, bool_idx, string_idx, enum_idx) := match varType | ||
| 395 | 752 | case VarType.SIMULATION then (indices.realVarIndex, indices.integerVarIndex, indices.booleanVarIndex, indices.stringVarIndex, indices.enumerationVarIndex); | |
| 396 | 376 | case VarType.PARAMETER then (indices.realParamIndex, indices.integerParamIndex, indices.booleanParamIndex, indices.stringParamIndex, indices.enumerationParamIndex); | |
| 397 | 188 | case VarType.ALIAS then (indices.realAliasIndex, indices.integerAliasIndex, indices.booleanAliasIndex, indices.stringAliasIndex, indices.enumerationAliasIndex); | |
| 398 | else algorithm | ||
| 399 | ✗ | Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed because of unhandled VarType."}); | |
| 400 | ✗ | then fail(); | |
| 401 | end match; | ||
| 402 | end getTypeIndices; | ||
| 403 | |||
| 404 | function setTypeIndices | ||
| 405 | input output SimCode.SimCodeIndices indices; | ||
| 406 | input VarType varType; | ||
| 407 | input Integer real_idx; | ||
| 408 | input Integer int_idx; | ||
| 409 | input Integer bool_idx; | ||
| 410 | input Integer string_idx; | ||
| 411 | input Integer enum_idx; | ||
| 412 | algorithm | ||
| 413 | () := match varType | ||
| 414 | case VarType.SIMULATION algorithm | ||
| 415 | 752 | indices.realVarIndex := real_idx; | |
| 416 | 752 | indices.integerVarIndex := int_idx; | |
| 417 | 752 | indices.booleanVarIndex := bool_idx; | |
| 418 | 752 | indices.stringVarIndex := string_idx; | |
| 419 | 752 | indices.enumerationVarIndex := enum_idx; | |
| 420 | then (); | ||
| 421 | case VarType.PARAMETER algorithm | ||
| 422 | 376 | indices.realParamIndex := real_idx; | |
| 423 | 376 | indices.integerParamIndex := int_idx; | |
| 424 | 376 | indices.booleanParamIndex := bool_idx; | |
| 425 | 376 | indices.stringParamIndex := string_idx; | |
| 426 | 376 | indices.enumerationParamIndex := enum_idx; | |
| 427 | then (); | ||
| 428 | case VarType.ALIAS algorithm | ||
| 429 | 188 | indices.realAliasIndex := real_idx; | |
| 430 | 188 | indices.integerAliasIndex := int_idx; | |
| 431 | 188 | indices.booleanAliasIndex := bool_idx; | |
| 432 | 188 | indices.stringAliasIndex := string_idx; | |
| 433 | 188 | indices.enumerationAliasIndex := enum_idx; | |
| 434 | then (); | ||
| 435 | end match; | ||
| 436 | end setTypeIndices; | ||
| 437 | |||
| 438 | function createFromResidualComponent | ||
| 439 | input output StrongComponent comp; | ||
| 440 | input Pointer<list<SimVar>> acc; | ||
| 441 | input Pointer<SimCode.SimCodeIndices> indices_ptr; | ||
| 442 | input VarType varType = VarType.SIMULATION; | ||
| 443 | algorithm | ||
| 444 | () := match comp | ||
| 445 | case StrongComponent.SINGLE_COMPONENT() guard(Equation.isResidual(comp.eqn)) algorithm | ||
| 446 | 1 | traverseCreate(Pointer.access(Equation.getResidualVar(comp.eqn)), acc, indices_ptr, varType); | |
| 447 | then (); | ||
| 448 | else (); | ||
| 449 | end match; | ||
| 450 | end createFromResidualComponent; | ||
| 451 | |||
| 452 | function size | ||
| 453 | input SimVar var; | ||
| 454 | output Integer s = Type.sizeOf(var.type_); | ||
| 455 | end size; | ||
| 456 | |||
| 457 | function getName | ||
| 458 | input SimVar var; | ||
| 459 | output ComponentRef name = var.name; | ||
| 460 | end getName; | ||
| 461 | |||
| 462 | function getIndex | ||
| 463 | input ComponentRef cref; | ||
| 464 | input UnorderedMap<ComponentRef, SimVar> sim_map; | ||
| 465 | output Integer index; | ||
| 466 | protected | ||
| 467 | SimVar var; | ||
| 468 | algorithm | ||
| 469 | try | ||
| 470 | ✗ | var := UnorderedMap.getSafe(cref, sim_map, sourceInfo()); | |
| 471 | ✗ | index := var.index; | |
| 472 | else | ||
| 473 | ✗ | Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed to get index for cref: " + ComponentRef.toString(cref)}); | |
| 474 | ✗ | fail(); | |
| 475 | end try; | ||
| 476 | end getIndex; | ||
| 477 | |||
| 478 | function shiftIndex | ||
| 479 | "Shift index by some value. Used to append `enumVars` onto `intVars`." | ||
| 480 | input output SimVar var; | ||
| 481 | input Integer shift; | ||
| 482 | algorithm | ||
| 483 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 70 times.
|
70 | var.index := var.index + shift; |
| 484 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 70 times.
✓ Branch 2 taken 70 times.
✗ Branch 3 not taken.
|
70 | if isSome(var.fmi_index) then |
| 485 | 70 | var.fmi_index := SOME(Util.getOption(var.fmi_index) + shift); | |
| 486 | end if; | ||
| 487 | end shiftIndex; | ||
| 488 | |||
| 489 | function convert | ||
| 490 | input SimVar simVar; | ||
| 491 | output OldSimCodeVar.SimVar oldSimVar; | ||
| 492 | protected | ||
| 493 | DAE.ComponentRef name = ComponentRef.toDAE(simVar.name); | ||
| 494 | algorithm | ||
| 495 |
4/4✓ Branch 0 taken 1203 times.
✓ Branch 1 taken 36273 times.
✓ Branch 2 taken 1203 times.
✓ Branch 3 taken 36273 times.
|
73749 | oldSimVar := OldSimCodeVar.SIMVAR( |
| 496 | name = name, | ||
| 497 | varKind = convertVarKind(simVar.varKind), | ||
| 498 | comment = simVar.comment, | ||
| 499 | unit = simVar.unit, | ||
| 500 | displayUnit = simVar.displayUnit, | ||
| 501 | index = simVar.index, | ||
| 502 | minValue = convertAttribute(simVar.min), | ||
| 503 | maxValue = convertAttribute(simVar.max), | ||
| 504 | initialValue = convertAttribute(simVar.start), | ||
| 505 | nominalValue = convertAttribute(simVar.nominal), | ||
| 506 | isFixed = simVar.isFixed, | ||
| 507 | type_ = Type.toDAE(simVar.type_), | ||
| 508 | isDiscrete = simVar.isDiscrete, | ||
| 509 | arrayCref = Util.applyOption(simVar.arrayCref, ComponentRef.toDAE), | ||
| 510 | aliasvar = Alias.convert(simVar.aliasvar), | ||
| 511 | source = DAE.emptyElementSource, //ToDo update this! | ||
| 512 | causality = Util.applyOption(simVar.causality, convertCausality), | ||
| 513 | variable_index = simVar.variable_index, | ||
| 514 | fmi_index = simVar.fmi_index, | ||
| 515 | numArrayElement = list(Expression.toString(e) for e in simVar.numArrayElement), | ||
| 516 | isValueChangeable = simVar.isValueChangeable, | ||
| 517 | isProtected = simVar.isProtected, | ||
| 518 | hideResult = SOME(simVar.hideResult), | ||
| 519 | isEncrypted = simVar.isEncrypted, | ||
| 520 | inputIndex = simVar.inputIndex, | ||
| 521 | initNonlinear = false, // TODO: Check what to add here! | ||
| 522 | matrixName = simVar.matrixName, | ||
| 523 | variability = SOME(convertVariability(simVar.varKind)), | ||
| 524 | initial_ = convertInitial(convertVariability(simVar.varKind), Util.applyOption(simVar.causality, convertCausality)), | ||
| 525 | exportVar = convertExportVar(simVar.exportVar, simVar.name, name), | ||
| 526 | relativeQuantity = false, | ||
| 527 | isConnectorFlow = simVar.isConnectorFlow); | ||
| 528 | end convert; | ||
| 529 | |||
| 530 | function convertExportVar | ||
| 531 | "the export variable is the variable itself unless something replaced it, | ||
| 532 | so the converted name is usually the same cref again" | ||
| 533 | input Option<ComponentRef> exportVar; | ||
| 534 | input ComponentRef varName; | ||
| 535 | input DAE.ComponentRef converted "varName converted"; | ||
| 536 | output Option<DAE.ComponentRef> dcref; | ||
| 537 | algorithm | ||
| 538 | dcref := match exportVar | ||
| 539 | local ComponentRef cref; | ||
| 540 |
2/2✓ Branch 0 taken 233 times.
✓ Branch 1 taken 36040 times.
|
36273 | case SOME(cref) then SOME(if referenceEq(cref, varName) then converted else ComponentRef.toDAE(cref)); |
| 541 | else NONE(); | ||
| 542 | end match; | ||
| 543 | end convertExportVar; | ||
| 544 | |||
| 545 | function convertAttribute | ||
| 546 | "Util.applyOption would build the partial application once per attribute | ||
| 547 | and variable, which is millions of closures on a scalarized model." | ||
| 548 | input Option<Expression> exp; | ||
| 549 | output Option<DAE.Exp> dexp; | ||
| 550 | algorithm | ||
| 551 | dexp := match exp | ||
| 552 | local Expression e; | ||
| 553 | 12307 | case SOME(e) then SOME(Expression.toDAE(e, allowEmpty = false)); | |
| 554 | else NONE(); | ||
| 555 | end match; | ||
| 556 | end convertAttribute; | ||
| 557 | |||
| 558 | function convertCausality | ||
| 559 | "Convert the new-backend Causality enum to the old SimCodeVar.Causality used | ||
| 560 | by the FMI model-description templates." | ||
| 561 | input Causality c; | ||
| 562 | output OldSimCodeVar.Causality oc; | ||
| 563 | algorithm | ||
| 564 | oc := match c | ||
| 565 | case Causality.NONE then OldSimCodeVar.NONECAUS(); | ||
| 566 | case Causality.OUTPUT then OldSimCodeVar.OUTPUT(); | ||
| 567 | case Causality.INPUT then OldSimCodeVar.INPUT(); | ||
| 568 | case Causality.LOCAL then OldSimCodeVar.LOCAL(); | ||
| 569 | case Causality.PARAMETER then OldSimCodeVar.PARAMETER(); | ||
| 570 | case Causality.CALCULATED_PARAMETER then OldSimCodeVar.CALCULATED_PARAMETER(); | ||
| 571 | end match; | ||
| 572 | end convertCausality; | ||
| 573 | |||
| 574 | function convertVariability | ||
| 575 | "Derive the FMI variability attribute from the variable kind." | ||
| 576 | input VariableKind vk; | ||
| 577 | output OldSimCodeVar.Variability v; | ||
| 578 | algorithm | ||
| 579 | v := match vk | ||
| 580 | case VariableKind.CONSTANT() then OldSimCodeVar.CONSTANT(); | ||
| 581 | case VariableKind.PARAMETER() then OldSimCodeVar.FIXED(); | ||
| 582 | case VariableKind.DISCRETE() then OldSimCodeVar.DISCRETE(); | ||
| 583 | case VariableKind.DISCRETE_STATE() then OldSimCodeVar.DISCRETE(); | ||
| 584 | case VariableKind.CLOCKED() then OldSimCodeVar.DISCRETE(); | ||
| 585 | case VariableKind.PREVIOUS() then OldSimCodeVar.DISCRETE(); | ||
| 586 | else OldSimCodeVar.CONTINUOUS(); | ||
| 587 | end match; | ||
| 588 | end convertVariability; | ||
| 589 | |||
| 590 | function convertInitial | ||
| 591 | "Default FMI initial attribute from variability + causality (mirrors | ||
| 592 | SimCodeUtil.getDefaultFmiInitialAttribute). Only the EXACT cases matter | ||
| 593 | for now: they make the start value be emitted to modelDescription.xml." | ||
| 594 | input OldSimCodeVar.Variability v; | ||
| 595 | input Option<OldSimCodeVar.Causality> c; | ||
| 596 | output Option<OldSimCodeVar.Initial> initial_; | ||
| 597 | algorithm | ||
| 598 | initial_ := match (v, c) | ||
| 599 | case (OldSimCodeVar.CONSTANT(), _) then SOME(OldSimCodeVar.EXACT()); | ||
| 600 | case (OldSimCodeVar.FIXED(), SOME(OldSimCodeVar.PARAMETER())) then SOME(OldSimCodeVar.EXACT()); | ||
| 601 | case (OldSimCodeVar.TUNABLE(), SOME(OldSimCodeVar.PARAMETER())) then SOME(OldSimCodeVar.EXACT()); | ||
| 602 | else NONE(); | ||
| 603 | end match; | ||
| 604 | end convertInitial; | ||
| 605 | |||
| 606 | function convertList | ||
| 607 | input list<SimVar> simVar_lst; | ||
| 608 | output list<OldSimCodeVar.SimVar> oldSimVar_lst = list(convert(simVar) for simVar in simVar_lst); | ||
| 609 | end convertList; | ||
| 610 | |||
| 611 | function newConvertMemo | ||
| 612 | input Integer size; | ||
| 613 | output ConvertMemo memo = UnorderedMap.new<ConvertEntry>(ComponentRef.hash, ComponentRef.isEqual, Util.nextPrime(size)); | ||
| 614 | end newConvertMemo; | ||
| 615 | |||
| 616 | function convertMemo | ||
| 617 | input SimVar simVar; | ||
| 618 | input ConvertMemo memo; | ||
| 619 | output OldSimCodeVar.SimVar oldSimVar = convert(simVar); | ||
| 620 | algorithm | ||
| 621 | 27611 | UnorderedMap.add(simVar.name, (simVar, oldSimVar), memo); | |
| 622 | end convertMemo; | ||
| 623 | |||
| 624 | function convertListMemo | ||
| 625 | input list<SimVar> simVar_lst; | ||
| 626 | input ConvertMemo memo; | ||
| 627 | output list<OldSimCodeVar.SimVar> oldSimVar_lst = list(convertMemo(simVar, memo) for simVar in simVar_lst); | ||
| 628 | end convertListMemo; | ||
| 629 | |||
| 630 | function convertMemoized | ||
| 631 | "the remembered conversion of exactly this record, or a fresh one" | ||
| 632 | input SimVar simVar; | ||
| 633 | input ConvertMemo memo; | ||
| 634 | output OldSimCodeVar.SimVar oldSimVar; | ||
| 635 | protected | ||
| 636 | SimVar orig; | ||
| 637 | algorithm | ||
| 638 | oldSimVar := match UnorderedMap.get(simVar.name, memo) | ||
| 639 | case SOME((orig, oldSimVar)) guard referenceEq(orig, simVar) then oldSimVar; | ||
| 640 | 7508 | else convert(simVar); | |
| 641 | end match; | ||
| 642 | end convertMemoized; | ||
| 643 | |||
| 644 | function convertTpl | ||
| 645 | input tuple<SimVar, Boolean> tpl; | ||
| 646 | output tuple<OldSimCodeVar.SimVar, Boolean> oldTpl; | ||
| 647 | protected | ||
| 648 | SimVar var; | ||
| 649 | Boolean b; | ||
| 650 | algorithm | ||
| 651 | 24 | (var, b) := tpl; | |
| 652 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 | oldTpl := (convert(var), b); |
| 653 | end convertTpl; | ||
| 654 | |||
| 655 | function isOutputSimVar | ||
| 656 | "True if the SimVar is an FMI output (causality OUTPUT), used to collect the | ||
| 657 | output interface variables (the new backend has no top-level-output list)." | ||
| 658 | input SimVar v; | ||
| 659 | output Boolean b; | ||
| 660 | algorithm | ||
| 661 | b := match v.causality | ||
| 662 | case SOME(Causality.OUTPUT) then true; | ||
| 663 | else false; | ||
| 664 | end match; | ||
| 665 | end isOutputSimVar; | ||
| 666 | |||
| 667 | protected | ||
| 668 | function parseAttributes | ||
| 669 | input BackendInfo backendInfo; | ||
| 670 | output VariableKind varKind; | ||
| 671 | output String unit = ""; | ||
| 672 | output String displayUnit = ""; | ||
| 673 | output Option<Expression> min = NONE(); | ||
| 674 | output Option<Expression> max = NONE(); | ||
| 675 | output Option<Expression> start = NONE(); | ||
| 676 | output Option<Expression> nominal = NONE(); | ||
| 677 | output Boolean isFixed = false; | ||
| 678 | output Boolean isDiscrete; | ||
| 679 | output Boolean isProtected; | ||
| 680 | algorithm | ||
| 681 | () := match backendInfo | ||
| 682 | local | ||
| 683 | VariableAttributes varAttr; | ||
| 684 | |||
| 685 | case BackendInfo.BACKEND_INFO(varKind = varKind, attributes = varAttr as VariableAttributes.VAR_ATTR_REAL()) | ||
| 686 | algorithm | ||
| 687 | 20155 | unit := Util.applyOptionOrDefault(Util.applyOption(varAttr.unit, Binding.getTypedExp), Expression.stringValue, ""); | |
| 688 | 20155 | displayUnit := Util.applyOptionOrDefault(Util.applyOption(varAttr.displayUnit, Binding.getTypedExp), Expression.stringValue, ""); | |
| 689 | 20155 | min := Util.applyOption(varAttr.min, Binding.getTypedExp); | |
| 690 | 20155 | max := Util.applyOption(varAttr.max, Binding.getTypedExp); | |
| 691 | 20155 | start := Util.applyOption(varAttr.start, Binding.getTypedExp); | |
| 692 | 20155 | nominal := Util.applyOption(varAttr.nominal, Binding.getTypedExp); | |
| 693 | // FIXME parameters have default fixed = true | ||
| 694 |
2/2✓ Branch 2 taken 13694 times.
✓ Branch 3 taken 6461 times.
|
20155 | isFixed := Util.applyOptionOrDefault(Util.applyOption(varAttr.fixed, Binding.getTypedExp), Expression.isAllTrue, false); |
| 695 | isDiscrete := match varKind | ||
| 696 | case VariableKind.DISCRETE() then true; | ||
| 697 | case VariableKind.DISCRETE_STATE() then true; | ||
| 698 | case VariableKind.PREVIOUS() then true; | ||
| 699 | case VariableKind.PARAMETER() then true; | ||
| 700 | case VariableKind.CONSTANT() then true; | ||
| 701 | case VariableKind.START() then true; | ||
| 702 | else false; | ||
| 703 | end match; | ||
| 704 | 20155 | isProtected := Util.getOptionOrDefault(varAttr.isProtected, false); | |
| 705 | then (); | ||
| 706 | |||
| 707 | case BackendInfo.BACKEND_INFO(varKind = varKind, attributes = varAttr as VariableAttributes.VAR_ATTR_INT()) | ||
| 708 | algorithm | ||
| 709 | 409 | min := Util.applyOption(varAttr.min, Binding.getTypedExp); | |
| 710 | 409 | max := Util.applyOption(varAttr.max, Binding.getTypedExp); | |
| 711 | 409 | start := Util.applyOption(varAttr.start, Binding.getTypedExp); | |
| 712 | 409 | isFixed := Util.applyOptionOrDefault(Util.applyOption(varAttr.fixed, Binding.getTypedExp), Expression.isAllTrue, false); | |
| 713 | isDiscrete := true; | ||
| 714 | 409 | isProtected := Util.getOptionOrDefault(varAttr.isProtected, false); | |
| 715 | then (); | ||
| 716 | |||
| 717 | case BackendInfo.BACKEND_INFO(varKind = varKind, attributes = varAttr as VariableAttributes.VAR_ATTR_BOOL()) | ||
| 718 | algorithm | ||
| 719 | 772 | start := Util.applyOption(varAttr.start, Binding.getTypedExp); | |
| 720 | 772 | isFixed := Util.applyOptionOrDefault(Util.applyOption(varAttr.fixed, Binding.getTypedExp), Expression.isAllTrue, false); | |
| 721 | isDiscrete := true; | ||
| 722 | 772 | isProtected := Util.getOptionOrDefault(varAttr.isProtected, false); | |
| 723 | then (); | ||
| 724 | |||
| 725 | case BackendInfo.BACKEND_INFO(varKind = varKind, attributes = varAttr as VariableAttributes.VAR_ATTR_CLOCK()) | ||
| 726 | algorithm | ||
| 727 | isDiscrete := true; | ||
| 728 | ✗ | isProtected := Util.getOptionOrDefault(varAttr.isProtected, false); | |
| 729 | then (); | ||
| 730 | |||
| 731 | case BackendInfo.BACKEND_INFO(varKind = varKind, attributes = varAttr as VariableAttributes.VAR_ATTR_STRING()) | ||
| 732 | algorithm | ||
| 733 | 30 | start := Util.applyOption(varAttr.start, Binding.getTypedExp); | |
| 734 | 30 | isFixed := Util.applyOptionOrDefault(Util.applyOption(varAttr.fixed, Binding.getTypedExp), Expression.isAllTrue, false); | |
| 735 | isDiscrete := true; | ||
| 736 | 30 | isProtected := Util.getOptionOrDefault(varAttr.isProtected, false); | |
| 737 | then (); | ||
| 738 | |||
| 739 | case BackendInfo.BACKEND_INFO(varKind = varKind, attributes = varAttr as VariableAttributes.VAR_ATTR_ENUMERATION()) | ||
| 740 | algorithm | ||
| 741 | 68 | min := Util.applyOption(varAttr.min, Binding.getTypedExp); | |
| 742 | 68 | max := Util.applyOption(varAttr.max, Binding.getTypedExp); | |
| 743 | 68 | start := Util.applyOption(varAttr.start, Binding.getTypedExp); | |
| 744 | 68 | isFixed := Util.applyOptionOrDefault(Util.applyOption(varAttr.fixed, Binding.getTypedExp), Expression.isAllTrue, false); | |
| 745 | isDiscrete := true; | ||
| 746 | 68 | isProtected := Util.getOptionOrDefault(varAttr.isProtected, false); | |
| 747 | then (); | ||
| 748 | |||
| 749 | else algorithm | ||
| 750 | ✗ | Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed because the BackendInfo could not be parsed:\n" | |
| 751 | + BackendInfo.toString(backendInfo)}); | ||
| 752 | ✗ | then fail(); | |
| 753 | end match; | ||
| 754 | end parseAttributes; | ||
| 755 | |||
| 756 | function parseComment | ||
| 757 | input SCode.Comment absynComment; | ||
| 758 | output String commentStr; | ||
| 759 | algorithm | ||
| 760 | commentStr := match absynComment | ||
| 761 | case SCode.COMMENT(comment = SOME(commentStr)) then commentStr; | ||
| 762 | else ""; | ||
| 763 | end match; | ||
| 764 | end parseComment; | ||
| 765 | |||
| 766 | function parseBinding | ||
| 767 | "returns the binding expression if the variable is a parameter and the binding is constant | ||
| 768 | returns the original start expression otherwise. Only if the binding is constant and used | ||
| 769 | as initial" | ||
| 770 | input output Option<Expression> start; | ||
| 771 | output Boolean isValueChangeable; | ||
| 772 | output Causality causality; | ||
| 773 | input Variable var; | ||
| 774 | algorithm | ||
| 775 | (start, isValueChangeable, causality) := match var | ||
| 776 | local | ||
| 777 | Expression bindingExp; | ||
| 778 | |||
| 779 | // 1. parameter with constant binding -> start value is updated to the binding value. Value can be changed after sim | ||
| 780 | case Variable.VARIABLE(binding = Binding.TYPED_BINDING(variability = NFPrefixes.Variability.CONSTANT, bindingExp = bindingExp), | ||
| 781 | backendinfo = BackendInfo.BACKEND_INFO(varKind = VariableKind.PARAMETER())) | ||
| 782 | then (SOME(bindingExp), true, Causality.PARAMETER); | ||
| 783 | |||
| 784 | // 2. just like 1. - FLAT_BINDING gets introduced by expanding/scalarizing | ||
| 785 | case Variable.VARIABLE(binding = Binding.FLAT_BINDING(variability = NFPrefixes.Variability.CONSTANT, bindingExp = bindingExp), | ||
| 786 | backendinfo = BackendInfo.BACKEND_INFO(varKind = VariableKind.PARAMETER())) | ||
| 787 | then (SOME(bindingExp), true, Causality.PARAMETER); | ||
| 788 | |||
| 789 | // 3. parameter with non constant binding -> normal start value. Value cannot be changed after simulation | ||
| 790 | case Variable.VARIABLE(backendinfo = BackendInfo.BACKEND_INFO(varKind = VariableKind.PARAMETER())) | ||
| 791 | then (start, false, Causality.CALCULATED_PARAMETER); | ||
| 792 | |||
| 793 | // 4. top level input / output variables -> FMI input/output causality (the | ||
| 794 | // flat-model direction; mirrors the old backend so modelDescription.xml | ||
| 795 | // gets causality="input"/"output" and FMI 3.0 terminals get a direction) | ||
| 796 | case _ guard Variable.isInput(var) then (start, true, Causality.INPUT); | ||
| 797 | case _ guard Variable.isOutput(var) then (start, false, Causality.OUTPUT); | ||
| 798 | |||
| 799 | // 0. other variables -> regular start value and it can be changed after simulation | ||
| 800 | else (start, false, Causality.LOCAL); | ||
| 801 | |||
| 802 | // ToDo: more cases! | ||
| 803 | |||
| 804 | // FIXME: variables that are fixed and are not CALCULATED should have isValueChangeable=true | ||
| 805 | end match; | ||
| 806 | end parseBinding; | ||
| 807 | |||
| 808 | function convertVarKind | ||
| 809 | "Usually this function would belong to NFBackendExtension, but we want to | ||
| 810 | avoid Frontend -> Backend dependency." | ||
| 811 | input VariableKind varKind; | ||
| 812 | output OldBackendDAE.VarKind oldVarKind; | ||
| 813 | algorithm | ||
| 814 | oldVarKind := match varKind | ||
| 815 | local | ||
| 816 | Variable var; | ||
| 817 | Option<DAE.ComponentRef> oldCrefOpt; | ||
| 818 | |||
| 819 | case VariableKind.ALGEBRAIC() then OldBackendDAE.VARIABLE(); | ||
| 820 | case VariableKind.STATE() | ||
| 821 | algorithm | ||
| 822 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 605 times.
✓ Branch 2 taken 605 times.
✗ Branch 3 not taken.
|
605 | if isSome(varKind.derivative) then |
| 823 | 605 | var := Pointer.access(PointerWeak.upgrade(Util.getOption(varKind.derivative))); | |
| 824 | 605 | oldCrefOpt := SOME(ComponentRef.toDAE(var.name)); | |
| 825 | else | ||
| 826 | oldCrefOpt := NONE(); | ||
| 827 | end if; | ||
| 828 | 605 | then OldBackendDAE.STATE(varKind.index, oldCrefOpt, varKind.natural); | |
| 829 | case VariableKind.STATE_DER() then OldBackendDAE.STATE_DER(); | ||
| 830 | case VariableKind.DUMMY_DER() then OldBackendDAE.DUMMY_DER(); | ||
| 831 | case VariableKind.DUMMY_STATE() then OldBackendDAE.DUMMY_STATE(); | ||
| 832 | case VariableKind.DISCRETE() then OldBackendDAE.DISCRETE(); | ||
| 833 | case VariableKind.DISCRETE_STATE() then OldBackendDAE.DISCRETE(); // we don't distinguish between clocked, discrete states and discretes in the old backend. is this correct? | ||
| 834 | case VariableKind.CLOCKED() then OldBackendDAE.DISCRETE(); // we don't distinguish between clocked, discrete states and discretes in the old backend. is this correct? | ||
| 835 | case VariableKind.PREVIOUS() then OldBackendDAE.DISCRETE(); | ||
| 836 | case VariableKind.PARAMETER() then OldBackendDAE.PARAM(); | ||
| 837 | case VariableKind.CONSTANT() then OldBackendDAE.CONST(); | ||
| 838 | //ToDo: check this! is this correct? need typechecking? | ||
| 839 | case VariableKind.START() then OldBackendDAE.VARIABLE(); | ||
| 840 | 6 | case VariableKind.EXTOBJ() then OldBackendDAE.EXTOBJ(varKind.fullClassName); | |
| 841 | case VariableKind.JAC_VAR() then OldBackendDAE.JAC_VAR(); | ||
| 842 | case VariableKind.JAC_TMP_VAR() then OldBackendDAE.JAC_TMP_VAR(); | ||
| 843 | case VariableKind.SEED_VAR() then OldBackendDAE.SEED_VAR(); | ||
| 844 | case VariableKind.OPT_CONSTR() then OldBackendDAE.OPT_CONSTR(); | ||
| 845 | case VariableKind.OPT_FCONSTR() then OldBackendDAE.OPT_FCONSTR(); | ||
| 846 | case VariableKind.OPT_INPUT_WITH_DER() then OldBackendDAE.OPT_INPUT_WITH_DER(); | ||
| 847 | case VariableKind.OPT_INPUT_DER() then OldBackendDAE.OPT_INPUT_DER(); | ||
| 848 | case VariableKind.OPT_TGRID() then OldBackendDAE.OPT_TGRID(); | ||
| 849 | ✗ | case VariableKind.OPT_LOOP_INPUT() then OldBackendDAE.OPT_LOOP_INPUT(ComponentRef.toDAE(varKind.replaceCref)); | |
| 850 | // ToDo maybe deprecated: | ||
| 851 | case VariableKind.ALG_STATE() then OldBackendDAE.ALG_STATE(); | ||
| 852 | case VariableKind.ALG_STATE_OLD() then OldBackendDAE.ALG_STATE_OLD(); | ||
| 853 | case VariableKind.RESIDUAL_VAR() then OldBackendDAE.DAE_RESIDUAL_VAR(); | ||
| 854 | case VariableKind.DAE_AUX_VAR() then OldBackendDAE.DAE_AUX_VAR(); | ||
| 855 | case VariableKind.LOOP_ITERATION() then OldBackendDAE.LOOP_ITERATION(); | ||
| 856 | case VariableKind.LOOP_SOLVED() then OldBackendDAE.LOOP_SOLVED(); | ||
| 857 | case VariableKind.FRONTEND_DUMMY() | ||
| 858 | algorithm | ||
| 859 | ✗ | Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed because of wrong VariableKind FRONTEND_DUMMY(). This should not exist after frontend."}); | |
| 860 | ✗ | then fail(); | |
| 861 | else | ||
| 862 | algorithm | ||
| 863 | ✗ | Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed because of unhandled VariableKind " + VariableKind.toString(varKind) + "."}); | |
| 864 | ✗ | then fail(); | |
| 865 | end match; | ||
| 866 | end convertVarKind; | ||
| 867 | end SimVar; | ||
| 868 | |||
| 869 | uniontype Alias | ||
| 870 | record NO_ALIAS end NO_ALIAS; | ||
| 871 | |||
| 872 | record ALIAS | ||
| 873 | "General alias expression with a coefficent. | ||
| 874 | var := gain * alias + offset" | ||
| 875 | ComponentRef alias "The name of the alias variable."; | ||
| 876 | Real gain " = 1 for regular alias."; | ||
| 877 | Real offset " = 0 for regular alias."; | ||
| 878 | end ALIAS; | ||
| 879 | |||
| 880 | function fromBinding | ||
| 881 | input Binding binding; | ||
| 882 | output Alias alias; | ||
| 883 | algorithm | ||
| 884 | alias := match binding | ||
| 885 | 1171 | case Binding.TYPED_BINDING() then getAlias(binding.bindingExp); | |
| 886 | 317 | case Binding.FLAT_BINDING() then getAlias(binding.bindingExp); | |
| 887 | else NO_ALIAS(); | ||
| 888 | end match; | ||
| 889 | end fromBinding; | ||
| 890 | |||
| 891 | function toString | ||
| 892 | input Alias alias; | ||
| 893 | output String str; | ||
| 894 | algorithm | ||
| 895 | str := match alias | ||
| 896 | local | ||
| 897 | String gainStr, offsetStr; | ||
| 898 | case NO_ALIAS() then "(no alias)"; | ||
| 899 | case ALIAS() algorithm | ||
| 900 | ✗ | gainStr := if alias.gain == 1.0 then "" else realString(alias.gain) + "*"; | |
| 901 | ✗ | offsetStr := if alias.offset == 0.0 then "" else "+" + realString(alias.offset); | |
| 902 | ✗ | then "(bound alias: " + gainStr + ComponentRef.toString(alias.alias) + offsetStr + ")"; | |
| 903 | end match; | ||
| 904 | end toString; | ||
| 905 | |||
| 906 | function convert | ||
| 907 | input Alias alias; | ||
| 908 | output OldSimCodeVar.AliasVariable oldAlias; | ||
| 909 | algorithm | ||
| 910 | oldAlias := match alias | ||
| 911 | case NO_ALIAS() then OldSimCodeVar.NOALIAS(); | ||
| 912 | |||
| 913 | case ALIAS() guard(realEq(alias.gain, 1.0) and realEq(alias.offset, 0.0)) | ||
| 914 | 1244 | then OldSimCodeVar.ALIAS(ComponentRef.toDAE(alias.alias)); | |
| 915 | |||
| 916 | case ALIAS() guard(realEq(alias.gain, -1.0) and realEq(alias.offset, 0.0)) | ||
| 917 | 243 | then OldSimCodeVar.NEGATEDALIAS(ComponentRef.toDAE(alias.alias)); | |
| 918 | |||
| 919 | /* unfortunately not possible in old sim code | ||
| 920 | case ALIAS() | ||
| 921 | then OldSimCodeVar.ALIAS_FUNC(ComponentRef.toDAE(alias.alias), alias.gain, alias.offset); | ||
| 922 | */ | ||
| 923 | else | ||
| 924 | algorithm | ||
| 925 | ✗ | Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed because of unknown Alias type."}); | |
| 926 | ✗ | then fail(); | |
| 927 | end match; | ||
| 928 | end convert; | ||
| 929 | |||
| 930 | protected | ||
| 931 | function getAlias | ||
| 932 | input Expression exp; | ||
| 933 | output Alias alias; | ||
| 934 | algorithm | ||
| 935 | |||
| 936 | alias := match SimplifyExp.simplify(exp) | ||
| 937 | local | ||
| 938 | Expression e; | ||
| 939 | ComponentRef cref; | ||
| 940 | |||
| 941 | // equality alias | ||
| 942 | 1245 | case e as Expression.CREF() then ALIAS(e.cref, 1.0, 0.0); | |
| 943 | |||
| 944 | // negated alias | ||
| 945 | 228 | case Expression.UNARY(exp = e as Expression.CREF()) then ALIAS(e.cref, -1.0, 0.0); | |
| 946 | |||
| 947 | // negated logical alias | ||
| 948 | 15 | case Expression.LUNARY(exp = e as Expression.CREF()) then ALIAS(e.cref, -1.0, 0.0); | |
| 949 | /* | ||
| 950 | // gain alias | ||
| 951 | case e as Expression.MULTARY(arguments = {e1, e2}, inv_arguments = {}) | ||
| 952 | guard(Operator.getMathClassification(e.operator) == NFOperator.MathClassification.MULTIPLICATION) | ||
| 953 | algorithm | ||
| 954 | (cref, gain) := getGainAlias(e1, e2); | ||
| 955 | then ALIAS(cref, gain, 0.0); | ||
| 956 | |||
| 957 | // offset alias (possibly also gain alias) | ||
| 958 | // constant should always be simplified to the arguments list even if it is negative | ||
| 959 | case e as Expression.MULTARY(arguments = {e1, e2}, inv_arguments = {}) | ||
| 960 | guard(Operator.getMathClassification(e.operator) == NFOperator.MathClassification.ADDITION) | ||
| 961 | algorithm | ||
| 962 | (cref, gain, offset) := getOffsetAlias(e1, e2); | ||
| 963 | then ALIAS(cref, gain, offset); | ||
| 964 | */ | ||
| 965 | else NO_ALIAS(); | ||
| 966 | end match; | ||
| 967 | end getAlias; | ||
| 968 | |||
| 969 | function getGainAlias | ||
| 970 | input Expression e1; | ||
| 971 | input Expression e2; | ||
| 972 | output ComponentRef cref; | ||
| 973 | output Real gain; | ||
| 974 | algorithm | ||
| 975 | (cref, gain) := match(e1, e2) | ||
| 976 | // first argument is the cref and second is const | ||
| 977 | ✗ | case (Expression.CREF(), _) guard(Expression.isConstNumber(e2)) then (e1.cref, Expression.realValue(e2)); | |
| 978 | // secoond argument is the cref and first is const | ||
| 979 | ✗ | case (_, Expression.CREF()) guard(Expression.isConstNumber(e1)) then (e2.cref, Expression.realValue(e1)); | |
| 980 | else algorithm | ||
| 981 | ✗ | Error.addInternalError(getInstanceName() + " cannot generate gain alias from Expressions: {" | |
| 982 | + Expression.toString(e1) + ", " + Expression.toString(e2) + "}", sourceInfo()); | ||
| 983 | ✗ | then fail(); | |
| 984 | end match; | ||
| 985 | end getGainAlias; | ||
| 986 | |||
| 987 | function getOffsetAlias | ||
| 988 | input Expression e1; | ||
| 989 | input Expression e2; | ||
| 990 | output ComponentRef cref; | ||
| 991 | output Real gain; | ||
| 992 | output Real offset; | ||
| 993 | algorithm | ||
| 994 | (cref, gain, offset) := match (e1, e2) | ||
| 995 | local | ||
| 996 | Expression arg1, arg2; | ||
| 997 | |||
| 998 | // first argument is the cref and second is const | ||
| 999 | ✗ | case (Expression.CREF(), _) guard(Expression.isConstNumber(e2)) then (e1.cref, 0.0, Expression.realValue(e2)); | |
| 1000 | |||
| 1001 | // second is the cref and first is const | ||
| 1002 | ✗ | case (_, Expression.CREF()) guard(Expression.isConstNumber(e1)) then (e2.cref, 0.0, Expression.realValue(e1)); | |
| 1003 | |||
| 1004 | // first argument is a multiplication with two arguments, second is constant | ||
| 1005 | // check if multiplication represents simple gain | ||
| 1006 | case (Expression.MULTARY(arguments = {arg1, arg2}, inv_arguments = {}), _) | ||
| 1007 | guard((Operator.getMathClassification(e1.operator) == NFOperator.MathClassification.MULTIPLICATION) | ||
| 1008 | and Expression.isConstNumber(e2)) | ||
| 1009 | algorithm | ||
| 1010 | ✗ | (cref, gain) := getGainAlias(arg1, arg2); | |
| 1011 | ✗ | then (cref, gain, Expression.realValue(e2)); | |
| 1012 | |||
| 1013 | // second argument is a multiplication with two arguments, first is constant | ||
| 1014 | // check if multiplication represents simple gain | ||
| 1015 | case (_, Expression.MULTARY(arguments = {arg1, arg2}, inv_arguments = {})) | ||
| 1016 | guard((Operator.getMathClassification(e2.operator) == NFOperator.MathClassification.MULTIPLICATION) | ||
| 1017 | and Expression.isConstNumber(e1)) | ||
| 1018 | algorithm | ||
| 1019 | ✗ | (cref, gain) := getGainAlias(arg1, arg2); | |
| 1020 | ✗ | then (cref, gain, Expression.realValue(e1)); | |
| 1021 | |||
| 1022 | else algorithm | ||
| 1023 | ✗ | Error.addInternalError(getInstanceName() + " cannot generate offset alias from Expressions: {" | |
| 1024 | + Expression.toString(e1) + ", " + Expression.toString(e2) + "}", sourceInfo()); | ||
| 1025 | ✗ | then fail(); | |
| 1026 | end match; | ||
| 1027 | end getOffsetAlias; | ||
| 1028 | end Alias; | ||
| 1029 | |||
| 1030 | // kabdelhak: i don't like "CALCULATED_PARAMETER", is there a better way to describe it? | ||
| 1031 | type Causality = enumeration(NONE, OUTPUT, INPUT, LOCAL, PARAMETER, CALCULATED_PARAMETER); | ||
| 1032 | // kabdelhak: where is the difference between approx and calculated? | ||
| 1033 | type Initial = enumeration(NONE, EXACT, APPROX, CALCULATED); | ||
| 1034 | // kabdelhak: i don't like "TUNABLE" -> just "VARIABLE"? | ||
| 1035 | type Variability = enumeration(CONSTANT, FIXED, TUNABLE, DISCRETE, CONTINUOUS); | ||
| 1036 | |||
| 1037 | uniontype SimVars "Container for metadata about variables in a Modelica model." | ||
| 1038 | record SIMVARS | ||
| 1039 | list<SimVar> stateVars; | ||
| 1040 | list<SimVar> derivativeVars; | ||
| 1041 | list<SimVar> algVars; | ||
| 1042 | list<SimVar> discreteAlgVars; | ||
| 1043 | list<SimVar> intAlgVars; | ||
| 1044 | list<SimVar> boolAlgVars; | ||
| 1045 | list<SimVar> stringAlgVars; | ||
| 1046 | list<SimVar> enumAlgVars; | ||
| 1047 | list<SimVar> inputVars; | ||
| 1048 | list<SimVar> outputVars; | ||
| 1049 | list<SimVar> aliasVars; | ||
| 1050 | list<SimVar> intAliasVars; | ||
| 1051 | list<SimVar> boolAliasVars; | ||
| 1052 | list<SimVar> stringAliasVars; | ||
| 1053 | list<SimVar> enumAliasVars; | ||
| 1054 | list<SimVar> paramVars; | ||
| 1055 | list<SimVar> intParamVars; | ||
| 1056 | list<SimVar> boolParamVars; | ||
| 1057 | list<SimVar> stringParamVars; | ||
| 1058 | list<SimVar> enumParamVars; | ||
| 1059 | list<SimVar> extObjVars; | ||
| 1060 | list<SimVar> constVars; | ||
| 1061 | list<SimVar> intConstVars; | ||
| 1062 | list<SimVar> boolConstVars; | ||
| 1063 | list<SimVar> stringConstVars; | ||
| 1064 | list<SimVar> enumConstVars; | ||
| 1065 | list<SimVar> residualVars; | ||
| 1066 | list<SimVar> jacobianVars; | ||
| 1067 | list<SimVar> seedVars; | ||
| 1068 | list<SimVar> realOptimizeConstraintsVars; | ||
| 1069 | list<SimVar> realOptimizeFinalConstraintsVars; | ||
| 1070 | list<SimVar> sensitivityVars "variable used to calculate sensitivities for parameters nSensitivitityParameters + nRealParam*nStates"; | ||
| 1071 | list<SimVar> dataReconSetcVars; | ||
| 1072 | list<SimVar> dataReconinputVars; | ||
| 1073 | list<SimVar> dataReconSetBVars; | ||
| 1074 | end SIMVARS; | ||
| 1075 | |||
| 1076 | function toString | ||
| 1077 | input SimVars vars; | ||
| 1078 | input output String str = ""; | ||
| 1079 | algorithm | ||
| 1080 | 6 | str := StringUtil.headline_2("SimVars " + str); | |
| 1081 | 6 | str := str + SimVar.listToString(vars.stateVars, "States"); | |
| 1082 | 6 | str := str + SimVar.listToString(vars.derivativeVars, "Derivatives"); | |
| 1083 | 6 | str := str + SimVar.listToString(vars.algVars, "Algebraic Variables"); | |
| 1084 | 6 | str := str + SimVar.listToString(vars.discreteAlgVars, "Discrete Algebraic Variables"); | |
| 1085 | 6 | str := str + SimVar.listToString(vars.intAlgVars, "Integer Algebraic Variables"); | |
| 1086 | 6 | str := str + SimVar.listToString(vars.boolAlgVars, "Boolean Algebraic Variables"); | |
| 1087 | 6 | str := str + SimVar.listToString(vars.paramVars, "Real Parameters"); | |
| 1088 | 6 | str := str + SimVar.listToString(vars.intParamVars, "Integer Parameters"); | |
| 1089 | 6 | str := str + SimVar.listToString(vars.boolParamVars, "Boolean Parameters"); | |
| 1090 | 6 | str := str + SimVar.listToString(vars.residualVars, "Residual Variables"); | |
| 1091 | 6 | str := str + SimVar.listToString(vars.aliasVars, "Real Alias", true); | |
| 1092 | // ToDo: all the other stuff | ||
| 1093 | end toString; | ||
| 1094 | |||
| 1095 | function create | ||
| 1096 | input BVariable.VarData varData; | ||
| 1097 | input VariablePointers residual_vars; | ||
| 1098 | output SimVars simVars; | ||
| 1099 | input output SimCode.SimCodeIndices simCodeIndices; | ||
| 1100 | protected | ||
| 1101 | list<SimVar> stateVars = {}, derivativeVars = {}, algVars = {}, nonTrivialAlias = {}; | ||
| 1102 | list<SimVar> discreteAlgVars = {}, intAlgVars = {}, boolAlgVars = {}, stringAlgVars = {}, enumAlgVars = {}; | ||
| 1103 | list<SimVar> discreteAlgVars2 = {}, intAlgVars2 = {}, boolAlgVars2 = {}, stringAlgVars2 = {}, enumAlgVars2 = {}; | ||
| 1104 | list<SimVar> discreteAlgVars3 = {}, intAlgVars3 = {}, boolAlgVars3 = {}, stringAlgVars3 = {}, enumAlgVars3 = {}; | ||
| 1105 | list<SimVar> inputVars = {}; | ||
| 1106 | list<SimVar> outputVars = {}; | ||
| 1107 | list<SimVar> aliasVars = {}, intAliasVars = {}, boolAliasVars = {}, stringAliasVars = {}, enumAliasVars = {}; | ||
| 1108 | list<SimVar> paramVars = {}, intParamVars = {}, boolParamVars = {}, stringParamVars = {}, enumParamVars = {}; | ||
| 1109 | list<SimVar> paramVarsR = {}, intParamVarsR = {}, boolParamVarsR = {}, stringParamVarsR = {}, enumParamVarsR = {}; | ||
| 1110 | list<SimVar> constVars = {}, intConstVars = {}, boolConstVars = {}, stringConstVars = {}, enumConstVars = {}; | ||
| 1111 | list<SimVar> extObjVars = {}; | ||
| 1112 | list<SimVar> residualVars = {}; | ||
| 1113 | list<SimVar> jacobianVars = {}; | ||
| 1114 | list<SimVar> seedVars = {}; | ||
| 1115 | list<SimVar> realOptimizeConstraintsVars = {}; | ||
| 1116 | list<SimVar> realOptimizeFinalConstraintsVars = {}; | ||
| 1117 | Integer enum_shift = 0; | ||
| 1118 | list<SimVar> sensitivityVars = {}; | ||
| 1119 | list<SimVar> dataReconSetcVars = {}; | ||
| 1120 | list<SimVar> dataReconinputVars = {}; | ||
| 1121 | list<SimVar> dataReconSetBVars = {}; | ||
| 1122 | algorithm | ||
| 1123 | () := match varData | ||
| 1124 | case BVariable.VAR_DATA_SIM() algorithm | ||
| 1125 |
2/4✗ Branch 1 not taken.
✓ Branch 2 taken 188 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 188 times.
|
188 | ({stateVars}, simCodeIndices) := createSimVarLists(varData.states, simCodeIndices, SplitType.NONE, VarType.SIMULATION); |
| 1126 |
2/4✗ Branch 1 not taken.
✓ Branch 2 taken 188 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 188 times.
|
188 | ({derivativeVars}, simCodeIndices) := createSimVarLists(varData.derivatives, simCodeIndices, SplitType.NONE, VarType.SIMULATION); |
| 1127 |
2/4✗ Branch 1 not taken.
✓ Branch 2 taken 188 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 188 times.
|
188 | ({algVars}, simCodeIndices) := createSimVarLists(varData.algebraics, simCodeIndices, SplitType.NONE, VarType.SIMULATION); |
| 1128 |
2/4✗ Branch 1 not taken.
✓ Branch 2 taken 188 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 188 times.
|
188 | ({inputVars}, simCodeIndices) := createSimVarLists(varData.top_level_inputs, simCodeIndices, SplitType.NONE, VarType.SIMULATION); |
| 1129 |
2/4✗ Branch 1 not taken.
✓ Branch 2 taken 188 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 188 times.
|
188 | ({nonTrivialAlias}, simCodeIndices) := createSimVarLists(varData.nonTrivialAlias, simCodeIndices, SplitType.NONE, VarType.SIMULATION); |
| 1130 |
6/12✗ Branch 1 not taken.
✓ Branch 2 taken 188 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 188 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 188 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 188 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 188 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 188 times.
|
188 | ({discreteAlgVars, intAlgVars, boolAlgVars, stringAlgVars, enumAlgVars}, simCodeIndices) := createSimVarLists(varData.discretes, simCodeIndices, SplitType.TYPE, VarType.SIMULATION); |
| 1131 |
6/12✗ Branch 1 not taken.
✓ Branch 2 taken 188 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 188 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 188 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 188 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 188 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 188 times.
|
188 | ({discreteAlgVars2, intAlgVars2, boolAlgVars2, stringAlgVars2, enumAlgVars2}, simCodeIndices) := createSimVarLists(varData.discrete_states, simCodeIndices, SplitType.TYPE, VarType.SIMULATION); |
| 1132 |
6/12✗ Branch 1 not taken.
✓ Branch 2 taken 188 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 188 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 188 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 188 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 188 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 188 times.
|
188 | ({discreteAlgVars3, intAlgVars3, boolAlgVars3, stringAlgVars3, enumAlgVars3}, simCodeIndices) := createSimVarLists(varData.clocked_states, simCodeIndices, SplitType.TYPE, VarType.SIMULATION); |
| 1133 |
6/12✗ Branch 1 not taken.
✓ Branch 2 taken 188 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 188 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 188 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 188 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 188 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 188 times.
|
188 | ({aliasVars, intAliasVars, boolAliasVars, stringAliasVars, enumAliasVars}, simCodeIndices) := createSimVarLists(varData.aliasVars, simCodeIndices, SplitType.TYPE, VarType.ALIAS); |
| 1134 | // enums are appended to the integer variables, constants do not take part in the shift | ||
| 1135 | 188 | enum_shift := simCodeIndices.integerVarIndex; | |
| 1136 |
6/12✗ Branch 1 not taken.
✓ Branch 2 taken 188 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 188 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 188 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 188 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 188 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 188 times.
|
188 | ({paramVars, intParamVars, boolParamVars, stringParamVars, enumParamVars}, simCodeIndices) := createSimVarLists(varData.parameters, simCodeIndices, SplitType.TYPE, VarType.PARAMETER); |
| 1137 |
6/12✗ Branch 1 not taken.
✓ Branch 2 taken 188 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 188 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 188 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 188 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 188 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 188 times.
|
188 | ({paramVarsR, intParamVarsR, boolParamVarsR, stringParamVarsR, enumParamVarsR}, simCodeIndices) := createSimVarLists(varData.resizables, simCodeIndices, SplitType.TYPE, VarType.PARAMETER); |
| 1138 |
6/12✗ Branch 1 not taken.
✓ Branch 2 taken 188 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 188 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 188 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 188 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 188 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 188 times.
|
188 | ({constVars, intConstVars, boolConstVars, stringConstVars, enumConstVars}, simCodeIndices) := createSimVarLists(varData.constants, simCodeIndices, SplitType.TYPE, VarType.SIMULATION); |
| 1139 |
2/4✗ Branch 1 not taken.
✓ Branch 2 taken 188 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 188 times.
|
188 | ({residualVars}, simCodeIndices) := createSimVarLists(residual_vars, simCodeIndices, SplitType.NONE, VarType.RESIDUAL); |
| 1140 | // The new backend has no separate top-level-output partition; outputs are | ||
| 1141 | // algebraic/state/discrete variables flagged OUTPUT by parseBinding. Collect | ||
| 1142 | // them across ALL base types (real, integer, boolean, string, enum) for the | ||
| 1143 | // FMI inputVars/outputVars interface (used e.g. by the FMI 3.0 terminal | ||
| 1144 | // export and ModelStructure). The variables stay in their original lists too. | ||
| 1145 | 188 | outputVars := List.filterOnTrue( | |
| 1146 | List.flatten({stateVars, algVars, | ||
| 1147 | discreteAlgVars, discreteAlgVars2, discreteAlgVars3, | ||
| 1148 | intAlgVars, intAlgVars2, intAlgVars3, | ||
| 1149 | boolAlgVars, boolAlgVars2, boolAlgVars3, | ||
| 1150 | stringAlgVars, stringAlgVars2, stringAlgVars3, | ||
| 1151 | enumAlgVars, enumAlgVars2, enumAlgVars3}), | ||
| 1152 | SimVar.isOutputSimVar); | ||
| 1153 | then (); | ||
| 1154 | case BVariable.VAR_DATA_JAC() then (); | ||
| 1155 | case BVariable.VAR_DATA_HES() then (); | ||
| 1156 | |||
| 1157 | else algorithm | ||
| 1158 | ✗ | Error.addMessage(Error.INTERNAL_ERROR, {getInstanceName() + " failed."}); | |
| 1159 | ✗ | then fail(); | |
| 1160 | end match; | ||
| 1161 | |||
| 1162 | 188 | simVars := SIMVARS( | |
| 1163 | stateVars = stateVars, | ||
| 1164 | derivativeVars = derivativeVars, | ||
| 1165 | algVars = List.flatten({algVars, inputVars, nonTrivialAlias}), | ||
| 1166 | discreteAlgVars = List.flatten({discreteAlgVars, discreteAlgVars2, discreteAlgVars3}), | ||
| 1167 | intAlgVars = List.flatten({intAlgVars, intAlgVars2, intAlgVars3}), | ||
| 1168 | boolAlgVars = List.flatten({boolAlgVars, boolAlgVars2, boolAlgVars3}), | ||
| 1169 | stringAlgVars = List.flatten({stringAlgVars, stringAlgVars2, stringAlgVars3}), | ||
| 1170 | enumAlgVars = List.flatten({enumAlgVars, enumAlgVars2, enumAlgVars3}), | ||
| 1171 | inputVars = inputVars, | ||
| 1172 | outputVars = outputVars, | ||
| 1173 | aliasVars = aliasVars, | ||
| 1174 | intAliasVars = intAliasVars, | ||
| 1175 | boolAliasVars = boolAliasVars, | ||
| 1176 | stringAliasVars = stringAliasVars, | ||
| 1177 | enumAliasVars = enumAliasVars, | ||
| 1178 | paramVars = List.flatten({paramVars, paramVarsR}), | ||
| 1179 | intParamVars = List.flatten({intParamVars, intParamVarsR}), | ||
| 1180 | boolParamVars = List.flatten({boolParamVars, boolParamVarsR}), | ||
| 1181 | stringParamVars = List.flatten({stringParamVars, stringParamVarsR}), | ||
| 1182 | enumParamVars = List.flatten({enumParamVars, enumParamVarsR}), | ||
| 1183 | extObjVars = extObjVars, | ||
| 1184 | constVars = constVars, | ||
| 1185 | intConstVars = intConstVars, | ||
| 1186 | boolConstVars = boolConstVars, | ||
| 1187 | stringConstVars = stringConstVars, | ||
| 1188 | enumConstVars = enumConstVars, | ||
| 1189 | residualVars = residualVars, | ||
| 1190 | jacobianVars = jacobianVars, | ||
| 1191 | seedVars = seedVars, | ||
| 1192 | realOptimizeConstraintsVars = realOptimizeConstraintsVars, | ||
| 1193 | realOptimizeFinalConstraintsVars = realOptimizeFinalConstraintsVars, | ||
| 1194 | sensitivityVars = sensitivityVars, | ||
| 1195 | dataReconSetcVars = dataReconSetcVars, | ||
| 1196 | dataReconinputVars = dataReconinputVars, | ||
| 1197 | dataReconSetBVars = dataReconSetBVars | ||
| 1198 | ); | ||
| 1199 | |||
| 1200 | // FIXME we currently handle enumerations as integers. | ||
| 1201 | // We append enums to ints so we have to shift the index accordingly. | ||
| 1202 |
12/16✓ Branch 0 taken 1 time.
✓ Branch 1 taken 188 times.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 188 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 188 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 188 times.
✓ Branch 12 taken 69 times.
✓ Branch 13 taken 188 times.
✓ Branch 14 taken 69 times.
✓ Branch 15 taken 188 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 188 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 188 times.
|
258 | simVars.intAlgVars := listAppend(simVars.intAlgVars, list(SimVar.shiftIndex(v, enum_shift) for v in simVars.enumAlgVars)); |
| 1203 | simVars.intAliasVars := listAppend(simVars.intAliasVars, list(SimVar.shiftIndex(v, simCodeIndices.integerAliasIndex) for v in simVars.enumAliasVars)); | ||
| 1204 | simVars.intParamVars := listAppend(simVars.intParamVars, list(SimVar.shiftIndex(v, simCodeIndices.integerParamIndex) for v in simVars.enumParamVars)); | ||
| 1205 | simVars.intConstVars := listAppend(simVars.intConstVars, list(SimVar.shiftIndex(v, simCodeIndices.integerVarIndex) for v in simVars.enumConstVars)); | ||
| 1206 | end create; | ||
| 1207 | |||
| 1208 | function addSeedAndJacobianVars | ||
| 1209 | input output SimVars vars; | ||
| 1210 | input list<tuple<ComponentRef, SimVar>> hash_tpl; | ||
| 1211 | protected | ||
| 1212 | ComponentRef cref; | ||
| 1213 | SimVar var; | ||
| 1214 | list<SimVar> seed_vars = {}; | ||
| 1215 | list<SimVar> jacobian_vars = {}; | ||
| 1216 | algorithm | ||
| 1217 |
2/2✓ Branch 0 taken 5380 times.
✓ Branch 1 taken 167 times.
|
5547 | for tpl in hash_tpl loop |
| 1218 | 5380 | (cref, var) := tpl; | |
| 1219 |
2/2✓ Branch 1 taken 1524 times.
✓ Branch 2 taken 3856 times.
|
5380 | if BVariable.checkCref(cref, BVariable.isSeed, sourceInfo()) then |
| 1220 | seed_vars := var :: seed_vars; | ||
| 1221 | else | ||
| 1222 | jacobian_vars := var :: jacobian_vars; | ||
| 1223 | end if; | ||
| 1224 | end for; | ||
| 1225 | 167 | vars.seedVars := listAppend(seed_vars, vars.seedVars); | |
| 1226 | vars.jacobianVars := listAppend(jacobian_vars, vars.jacobianVars); | ||
| 1227 | end addSeedAndJacobianVars; | ||
| 1228 | |||
| 1229 | function size | ||
| 1230 | input SimVars simVars; | ||
| 1231 | output Integer size = listLength(simVars.stateVars) | ||
| 1232 | + listLength(simVars.derivativeVars) | ||
| 1233 | + listLength(simVars.algVars) | ||
| 1234 | + listLength(simVars.discreteAlgVars) | ||
| 1235 | + listLength(simVars.intAlgVars) | ||
| 1236 | + listLength(simVars.boolAlgVars) | ||
| 1237 | + listLength(simVars.inputVars) | ||
| 1238 | + listLength(simVars.outputVars) | ||
| 1239 | + listLength(simVars.aliasVars) | ||
| 1240 | + listLength(simVars.intAliasVars) | ||
| 1241 | + listLength(simVars.boolAliasVars) | ||
| 1242 | + listLength(simVars.paramVars) | ||
| 1243 | + listLength(simVars.intParamVars) | ||
| 1244 | + listLength(simVars.boolParamVars) | ||
| 1245 | + listLength(simVars.stringAlgVars) | ||
| 1246 | + listLength(simVars.stringParamVars) | ||
| 1247 | + listLength(simVars.stringAliasVars) | ||
| 1248 | + listLength(simVars.extObjVars) | ||
| 1249 | + listLength(simVars.constVars) | ||
| 1250 | + listLength(simVars.intConstVars) | ||
| 1251 | + listLength(simVars.boolConstVars) | ||
| 1252 | + listLength(simVars.stringConstVars) | ||
| 1253 | + listLength(simVars.stringAlgVars) | ||
| 1254 | + listLength(simVars.jacobianVars) | ||
| 1255 | + listLength(simVars.seedVars) | ||
| 1256 | + listLength(simVars.realOptimizeConstraintsVars) | ||
| 1257 | + listLength(simVars.realOptimizeFinalConstraintsVars) | ||
| 1258 | + listLength(simVars.sensitivityVars) | ||
| 1259 | + listLength(simVars.dataReconSetcVars) | ||
| 1260 | + listLength(simVars.dataReconinputVars) | ||
| 1261 | + listLength(simVars.dataReconSetBVars); | ||
| 1262 | end size; | ||
| 1263 | |||
| 1264 | function convert | ||
| 1265 | input SimVars simVars; | ||
| 1266 | input ConvertMemo memo; | ||
| 1267 | output OldSimCodeVar.SimVars oldSimVars; | ||
| 1268 | algorithm | ||
| 1269 | 188 | oldSimVars := OldSimCodeVar.SIMVARS( | |
| 1270 | stateVars = SimVar.convertListMemo(simVars.stateVars, memo), | ||
| 1271 | derivativeVars = SimVar.convertListMemo(simVars.derivativeVars, memo), | ||
| 1272 | algVars = SimVar.convertListMemo(simVars.algVars, memo), | ||
| 1273 | discreteAlgVars = SimVar.convertListMemo(simVars.discreteAlgVars, memo), | ||
| 1274 | intAlgVars = SimVar.convertListMemo(simVars.intAlgVars, memo), | ||
| 1275 | boolAlgVars = SimVar.convertListMemo(simVars.boolAlgVars, memo), | ||
| 1276 | inputVars = SimVar.convertListMemo(simVars.inputVars, memo), | ||
| 1277 | outputVars = SimVar.convertListMemo(simVars.outputVars, memo), | ||
| 1278 | aliasVars = SimVar.convertListMemo(simVars.aliasVars, memo), | ||
| 1279 | intAliasVars = SimVar.convertListMemo(simVars.intAliasVars, memo), | ||
| 1280 | boolAliasVars = SimVar.convertListMemo(simVars.boolAliasVars, memo), | ||
| 1281 | paramVars = SimVar.convertListMemo(simVars.paramVars, memo), | ||
| 1282 | intParamVars = SimVar.convertListMemo(simVars.intParamVars, memo), | ||
| 1283 | boolParamVars = SimVar.convertListMemo(simVars.boolParamVars, memo), | ||
| 1284 | stringAlgVars = SimVar.convertListMemo(simVars.stringAlgVars, memo), | ||
| 1285 | stringParamVars = SimVar.convertListMemo(simVars.stringParamVars, memo), | ||
| 1286 | stringAliasVars = SimVar.convertListMemo(simVars.stringAliasVars, memo), | ||
| 1287 | extObjVars = SimVar.convertListMemo(simVars.extObjVars, memo), | ||
| 1288 | constVars = SimVar.convertListMemo(simVars.constVars, memo), | ||
| 1289 | intConstVars = SimVar.convertListMemo(simVars.intConstVars, memo), | ||
| 1290 | boolConstVars = SimVar.convertListMemo(simVars.boolConstVars, memo), | ||
| 1291 | stringConstVars = SimVar.convertListMemo(simVars.stringConstVars, memo), | ||
| 1292 | jacobianVars = SimVar.convertListMemo(simVars.jacobianVars, memo), | ||
| 1293 | seedVars = SimVar.convertListMemo(simVars.seedVars, memo), | ||
| 1294 | realOptimizeConstraintsVars = SimVar.convertListMemo(simVars.realOptimizeConstraintsVars, memo), | ||
| 1295 | realOptimizeFinalConstraintsVars = SimVar.convertListMemo(simVars.realOptimizeFinalConstraintsVars, memo), | ||
| 1296 | sensitivityVars = SimVar.convertListMemo(simVars.sensitivityVars, memo), | ||
| 1297 | dataReconSetcVars = SimVar.convertListMemo(simVars.dataReconSetcVars, memo), | ||
| 1298 | dataReconinputVars = SimVar.convertListMemo(simVars.dataReconinputVars, memo), | ||
| 1299 | dataReconSetBVars = SimVar.convertListMemo(simVars.dataReconSetBVars, memo)); | ||
| 1300 | end convert; | ||
| 1301 | |||
| 1302 | function createSimVarLists | ||
| 1303 | "creates a list of simvar lists. SplitType.NONE always returns a list with only | ||
| 1304 | one list as its element and SplitType.TYPE returns a list with four lists." | ||
| 1305 | input VariablePointers vars; | ||
| 1306 | output list<list<SimVar>> simVars = {}; | ||
| 1307 | input output SimCode.SimCodeIndices simCodeIndices; | ||
| 1308 | input SplitType splitType; | ||
| 1309 | input VarType varType; | ||
| 1310 | protected | ||
| 1311 | // scalarize goes through fromList, whose cref dedupe a record and its elements rely on | ||
| 1312 | list<Pointer<Variable>> sim_vars = VariablePointers.toList(if Flags.getConfigBool(Flags.SIM_CODE_SCALARIZE) then VariablePointers.scalarize(vars) else vars); | ||
| 1313 | list<SimVar> lst; | ||
| 1314 | algorithm | ||
| 1315 | |||
| 1316 |
2/2✓ Branch 0 taken 1128 times.
✓ Branch 1 taken 1316 times.
|
2444 | if splitType == SplitType.NONE then |
| 1317 | 1128 | (lst, simCodeIndices) := SimVar.createList(sim_vars, varType, simCodeIndices); | |
| 1318 | simVars := {lst}; | ||
| 1319 | elseif splitType == SplitType.TYPE then | ||
| 1320 | 1316 | (simVars, simCodeIndices) := SimVar.createListsByType(sim_vars, varType, simCodeIndices); | |
| 1321 | else | ||
| 1322 | ✗ | Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed because of invalid splitType."}); | |
| 1323 | end if; | ||
| 1324 | end createSimVarLists; | ||
| 1325 | |||
| 1326 | function getPartitionVars | ||
| 1327 | input Partition partition; | ||
| 1328 | input UnorderedMap<ComponentRef, SimVar> simcode_map; | ||
| 1329 | output list<SimVar> part_vars; | ||
| 1330 | algorithm | ||
| 1331 | part_vars := match partition.strongComponents | ||
| 1332 | local | ||
| 1333 | array<StrongComponent> comps; | ||
| 1334 | list<list<SimVar>> result = {}; | ||
| 1335 | |||
| 1336 | case SOME(comps) algorithm | ||
| 1337 |
1/2✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
|
42 | for i in 1:arrayLength(comps) loop |
| 1338 | 24 | result := getStrongComponentVars(comps[i], simcode_map) :: result; | |
| 1339 | end for; | ||
| 1340 | 18 | then List.flatten(result); | |
| 1341 | |||
| 1342 | else algorithm | ||
| 1343 | ✗ | Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed for\n" + Partition.Partition.toString(partition)}); | |
| 1344 | ✗ | then fail(); | |
| 1345 | end match; | ||
| 1346 | end getPartitionVars; | ||
| 1347 | |||
| 1348 | function getStrongComponentVars | ||
| 1349 | input StrongComponent comp; | ||
| 1350 | input UnorderedMap<ComponentRef, SimVar> simcode_map; | ||
| 1351 | output list<SimVar> part_vars = {}; | ||
| 1352 | algorithm | ||
| 1353 | part_vars := match comp | ||
| 1354 | 24 | case StrongComponent.SINGLE_COMPONENT() then getVars(comp.var, simcode_map); | |
| 1355 | ✗ | case StrongComponent.MULTI_COMPONENT() then List.flatten(list(getVars(Slice.getT(v), simcode_map) for v in comp.vars)); | |
| 1356 | ✗ | case StrongComponent.SLICED_COMPONENT() then getVars(Slice.getT(comp.var), simcode_map); | |
| 1357 | ✗ | case StrongComponent.RESIZABLE_COMPONENT() then getVars(Slice.getT(comp.var), simcode_map); | |
| 1358 | ✗ | case StrongComponent.GENERIC_COMPONENT() then getVars(BVariable.getVarPointer(comp.var_cref, sourceInfo()), simcode_map); | |
| 1359 | ✗ | case StrongComponent.ENTWINED_COMPONENT() then List.flatten(list(getStrongComponentVars(c, simcode_map) for c in comp.entwined_slices)); | |
| 1360 | ✗ | case StrongComponent.ALGEBRAIC_LOOP() then List.flatten(list(getVars(Slice.getT(v), simcode_map) for v in comp.strict.iteration_vars)); | |
| 1361 | ✗ | case StrongComponent.ALIAS() then getStrongComponentVars(comp.original, simcode_map); | |
| 1362 | else algorithm | ||
| 1363 | ✗ | Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed with unknown reason for\n" + StrongComponent.toString(comp)}); | |
| 1364 | ✗ | then fail(); | |
| 1365 | end match; | ||
| 1366 | end getStrongComponentVars; | ||
| 1367 | |||
| 1368 | public | ||
| 1369 | function numScalarElems | ||
| 1370 | "Total scalar element count across a list of SimVars, independent of the | ||
| 1371 | codegen target. Unlike listScalarSize, always returns the product of | ||
| 1372 | dimension sizes (not listLength). Used by NBackEnd Jacobian generation | ||
| 1373 | to compute the correct number of columns/rows when --simCodeScalarize=false | ||
| 1374 | yields array SimVars (e.g. x[100] is one SimVar with numArrayElement=[100])." | ||
| 1375 | input list<SimVar> vars; | ||
| 1376 | output Integer n; | ||
| 1377 | algorithm | ||
| 1378 |
8/8✓ Branch 0 taken 2910 times.
✓ Branch 1 taken 334 times.
✓ Branch 2 taken 2910 times.
✓ Branch 3 taken 334 times.
✓ Branch 4 taken 68 times.
✓ Branch 5 taken 2910 times.
✓ Branch 6 taken 68 times.
✓ Branch 7 taken 2910 times.
|
3312 | n := sum(product(Expression.integerValueOrDefault(e, 1) for e in v.numArrayElement) for v in vars); |
| 1379 | end numScalarElems; | ||
| 1380 | |||
| 1381 | protected | ||
| 1382 | function getVars | ||
| 1383 | input Pointer<Variable> var; | ||
| 1384 | input UnorderedMap<ComponentRef, SimVar> simcode_map; | ||
| 1385 | output list<SimVar> vars = {}; | ||
| 1386 | algorithm | ||
| 1387 |
1/2✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
|
24 | if Flags.getConfigBool(Flags.SIM_CODE_SCALARIZE) then |
| 1388 |
4/4✓ Branch 1 taken 24 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 24 times.
|
48 | vars := list(UnorderedMap.getSafe(BVariable.getVarName(v), simcode_map, sourceInfo()) for v in VariablePointers.scalarizeList({var})); |
| 1389 | else | ||
| 1390 | ✗ | vars := {UnorderedMap.getSafe(BVariable.getVarName(var), simcode_map, sourceInfo())}; | |
| 1391 | end if; | ||
| 1392 | end getVars; | ||
| 1393 | |||
| 1394 | end SimVars; | ||
| 1395 | |||
| 1396 | constant SimVars emptySimVars = SIMVARS( | ||
| 1397 | {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, | ||
| 1398 | {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}); | ||
| 1399 | |||
| 1400 | type SplitType = enumeration(NONE, TYPE); | ||
| 1401 | type VarType = enumeration(SIMULATION, PARAMETER, ALIAS, RESIDUAL, EXTERNAL_OBJECT); // ToDo: PRE, OLD, RELATIONS... | ||
| 1402 | |||
| 1403 | uniontype VarInfo | ||
| 1404 | record VAR_INFO | ||
| 1405 | Integer numZeroCrossings; | ||
| 1406 | Integer numTimeEvents; | ||
| 1407 | Integer numRelations; | ||
| 1408 | Integer numMathEventFunctions; | ||
| 1409 | Integer numStateVars; | ||
| 1410 | Integer numAlgVars; | ||
| 1411 | Integer numDiscreteReal; | ||
| 1412 | Integer numIntAlgVars; | ||
| 1413 | Integer numBoolAlgVars; | ||
| 1414 | Integer numAlgAliasVars; | ||
| 1415 | Integer numIntAliasVars; | ||
| 1416 | Integer numBoolAliasVars; | ||
| 1417 | Integer numParams; | ||
| 1418 | Integer numIntParams; | ||
| 1419 | Integer numBoolParams; | ||
| 1420 | Integer numOutVars; | ||
| 1421 | Integer numInVars; | ||
| 1422 | Integer numExternalObjects; | ||
| 1423 | Integer numStringAlgVars; | ||
| 1424 | Integer numStringParamVars; | ||
| 1425 | Integer numStringAliasVars; | ||
| 1426 | Integer numEquations; | ||
| 1427 | Integer numLinearSystems; | ||
| 1428 | Integer numNonLinearSystems; | ||
| 1429 | Integer numMixedSystems; | ||
| 1430 | Integer numStateSets; | ||
| 1431 | Integer numJacobians; | ||
| 1432 | Integer numOptimizeConstraints; | ||
| 1433 | Integer numOptimizeFinalConstraints; | ||
| 1434 | Integer numSensitivityParameters; | ||
| 1435 | Integer numSetcVars; | ||
| 1436 | Integer numDataReconVars; | ||
| 1437 | Integer numRealIntputVars; | ||
| 1438 | Integer numSetbVars; | ||
| 1439 | Integer numRelatedBoundaryConditions; | ||
| 1440 | end VAR_INFO; | ||
| 1441 | |||
| 1442 | function listScalarSize | ||
| 1443 | "Var-vector size for a simvar list. The C++ target keeps arrays un-expanded | ||
| 1444 | but sizes its var vectors and value references per scalar element, so the | ||
| 1445 | array sizes are summed. Every other target (notably the C runtime, which | ||
| 1446 | also supports simCodeScalarize=false) keeps one slot per simvar." | ||
| 1447 | input list<SimVar> vars; | ||
| 1448 | output Integer sz; | ||
| 1449 | algorithm | ||
| 1450 |
3/4✓ Branch 1 taken 14 times.
✓ Branch 2 taken 2618 times.
✓ Branch 5 taken 14 times.
✗ Branch 6 not taken.
|
2632 | if stringEqual(Config.simCodeTarget(), "Cpp") then |
| 1451 |
8/8✓ Branch 0 taken 4 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 14 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 4 times.
|
21 | sz := sum(product(Expression.integerValueOrDefault(e, 1) for e in v.numArrayElement) for v in vars); |
| 1452 | else | ||
| 1453 | 2618 | sz := listLength(vars); | |
| 1454 | end if; | ||
| 1455 | end listScalarSize; | ||
| 1456 | |||
| 1457 | function create | ||
| 1458 | input SimVars vars; | ||
| 1459 | input EventInfo eventInfo; | ||
| 1460 | input SimCodeIndices simCodeIndices; | ||
| 1461 | output VarInfo varInfo; | ||
| 1462 | algorithm | ||
| 1463 |
17/22✓ Branch 1 taken 82 times.
✓ Branch 2 taken 188 times.
✓ Branch 3 taken 82 times.
✓ Branch 4 taken 188 times.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 188 times.
✓ Branch 8 taken 5 times.
✓ Branch 9 taken 188 times.
✓ Branch 12 taken 82 times.
✓ Branch 13 taken 188 times.
✓ Branch 14 taken 82 times.
✓ Branch 15 taken 188 times.
✓ Branch 17 taken 11 times.
✓ Branch 18 taken 188 times.
✓ Branch 19 taken 11 times.
✓ Branch 20 taken 188 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 11 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
|
368 | varInfo := VAR_INFO( |
| 1464 | numZeroCrossings = sum(Condition.size(cond) for cond in UnorderedMap.keyList(eventInfo.state_map)) + sum(MathEvent.numZeroCrossings(mev) for mev in eventInfo.math_lst), | ||
| 1465 | numTimeEvents = UnorderedSet.size(eventInfo.time_set), | ||
| 1466 | numRelations = sum(Condition.numRelations(cond) for cond in UnorderedMap.keyList(eventInfo.state_map)), | ||
| 1467 | numMathEventFunctions = eventInfo.numberMathEvents, | ||
| 1468 | numStateVars = listScalarSize(vars.stateVars), | ||
| 1469 | numAlgVars = listScalarSize(vars.algVars), | ||
| 1470 | numDiscreteReal = listScalarSize(vars.discreteAlgVars), | ||
| 1471 | numIntAlgVars = listScalarSize(vars.intAlgVars), | ||
| 1472 | numBoolAlgVars = listScalarSize(vars.boolAlgVars), | ||
| 1473 | numAlgAliasVars = listScalarSize(vars.aliasVars), | ||
| 1474 | numIntAliasVars = listScalarSize(vars.intAliasVars), | ||
| 1475 | numBoolAliasVars = listScalarSize(vars.boolAliasVars), | ||
| 1476 | numParams = listScalarSize(vars.paramVars), | ||
| 1477 | numIntParams = listScalarSize(vars.intParamVars), | ||
| 1478 | numBoolParams = listScalarSize(vars.boolParamVars), | ||
| 1479 | numOutVars = listLength(vars.outputVars), | ||
| 1480 | // one value per scalar input in simulationInfo->inputVars, also for the C target | ||
| 1481 | numInVars = sum(if Type.isArray(v.type_) then product(Expression.integerValueOrDefault(e, 1) for e in v.numArrayElement) else 1 for v in vars.inputVars), | ||
| 1482 | numExternalObjects = listLength(vars.extObjVars), | ||
| 1483 | numStringAlgVars = listScalarSize(vars.stringAlgVars), | ||
| 1484 | numStringParamVars = listScalarSize(vars.stringParamVars), | ||
| 1485 | numStringAliasVars = listScalarSize(vars.stringAliasVars), | ||
| 1486 | numEquations = simCodeIndices.equationIndex, | ||
| 1487 | numLinearSystems = simCodeIndices.linearSystemIndex, | ||
| 1488 | numNonLinearSystems = simCodeIndices.nonlinearSystemIndex, | ||
| 1489 | numMixedSystems = 0, | ||
| 1490 | numStateSets = 0, | ||
| 1491 | numJacobians = simCodeIndices.nonlinearSystemIndex + simCodeIndices.linearSystemIndex + 5, // #nonlinSystems + #linSystems (torn linear systems with a symbolic Jacobian consume a jacobianIndex slot from the same analyticJacobians array too) + 5 simulation jacs (add state sets later!) | ||
| 1492 | numOptimizeConstraints = 0, | ||
| 1493 | numOptimizeFinalConstraints = 0, | ||
| 1494 | numSensitivityParameters = 0, | ||
| 1495 | numSetcVars = 0, | ||
| 1496 | numDataReconVars = 0, | ||
| 1497 | numRealIntputVars = 0, | ||
| 1498 | numSetbVars = 0, | ||
| 1499 | numRelatedBoundaryConditions = 0); | ||
| 1500 | end create; | ||
| 1501 | |||
| 1502 | function convert | ||
| 1503 | input VarInfo varInfo; | ||
| 1504 | output OldSimCode.VarInfo oldVarInfo; | ||
| 1505 | algorithm | ||
| 1506 | 376 | oldVarInfo := OldSimCode.VARINFO( | |
| 1507 | numZeroCrossings = varInfo.numZeroCrossings, | ||
| 1508 | numTimeEvents = varInfo.numTimeEvents, | ||
| 1509 | numRelations = varInfo.numRelations, | ||
| 1510 | numMathEventFunctions = varInfo.numMathEventFunctions, | ||
| 1511 | numStateVars = varInfo.numStateVars, | ||
| 1512 | numAlgVars = varInfo.numAlgVars, | ||
| 1513 | numDiscreteReal = varInfo.numDiscreteReal, | ||
| 1514 | numIntAlgVars = varInfo.numIntAlgVars, | ||
| 1515 | numBoolAlgVars = varInfo.numBoolAlgVars, | ||
| 1516 | numAlgAliasVars = varInfo.numAlgAliasVars, | ||
| 1517 | numIntAliasVars = varInfo.numIntAliasVars, | ||
| 1518 | numBoolAliasVars = varInfo.numBoolAliasVars, | ||
| 1519 | numParams = varInfo.numParams, | ||
| 1520 | numIntParams = varInfo.numIntParams, | ||
| 1521 | numBoolParams = varInfo.numBoolParams, | ||
| 1522 | numOutVars = varInfo.numOutVars, | ||
| 1523 | numInVars = varInfo.numInVars, | ||
| 1524 | numExternalObjects = varInfo.numExternalObjects, | ||
| 1525 | numStringAlgVars = varInfo.numStringAlgVars, | ||
| 1526 | numStringParamVars = varInfo.numStringParamVars, | ||
| 1527 | numStringAliasVars = varInfo.numStringAliasVars, | ||
| 1528 | numEquations = varInfo.numEquations, | ||
| 1529 | numLinearSystems = varInfo.numLinearSystems, | ||
| 1530 | numNonLinearSystems = varInfo.numNonLinearSystems, | ||
| 1531 | numMixedSystems = varInfo.numMixedSystems, | ||
| 1532 | numStateSets = varInfo.numStateSets, | ||
| 1533 | numJacobians = varInfo.numJacobians, | ||
| 1534 | numOptimizeConstraints = varInfo.numOptimizeConstraints, | ||
| 1535 | numOptimizeFinalConstraints = varInfo.numOptimizeFinalConstraints, | ||
| 1536 | numSensitivityParameters = varInfo.numSensitivityParameters, | ||
| 1537 | numSetcVars = varInfo.numSetcVars, | ||
| 1538 | numDataReconVars = varInfo.numDataReconVars, | ||
| 1539 | numRealInputVars = varInfo.numRealIntputVars, | ||
| 1540 | numSetbVars = varInfo.numSetbVars, | ||
| 1541 | numRelatedBoundaryConditions = varInfo.numRelatedBoundaryConditions); | ||
| 1542 | end convert; | ||
| 1543 | end VarInfo; | ||
| 1544 | |||
| 1545 | uniontype ExtObjInfo | ||
| 1546 | record EXT_OBJ_INFO | ||
| 1547 | list<SimVar> objects; | ||
| 1548 | list<tuple<ComponentRef, ComponentRef>> aliases; | ||
| 1549 | end EXT_OBJ_INFO; | ||
| 1550 | |||
| 1551 | |||
| 1552 | function toString | ||
| 1553 | input ExtObjInfo info; | ||
| 1554 | output String str = SimVar.listToString(info.objects, "External Objects"); | ||
| 1555 | end toString; | ||
| 1556 | |||
| 1557 | function create | ||
| 1558 | input VariablePointers external_objects; | ||
| 1559 | output ExtObjInfo info; | ||
| 1560 | input output SimVars vars; | ||
| 1561 | input output SimCodeIndices simCodeIndices; | ||
| 1562 | protected | ||
| 1563 | list<SimVar> var_lst; | ||
| 1564 | algorithm | ||
| 1565 | 188 | (var_lst, simCodeIndices) := SimVar.createList(VariablePointers.toList(external_objects), VarType.EXTERNAL_OBJECT, simCodeIndices); | |
| 1566 | 188 | vars.extObjVars := var_lst; | |
| 1567 | // todo: alias | ||
| 1568 | 188 | info := EXT_OBJ_INFO(var_lst, {}); | |
| 1569 | end create; | ||
| 1570 | |||
| 1571 | function convert | ||
| 1572 | input ExtObjInfo info; | ||
| 1573 | output OldSimCode.ExtObjInfo oldInfo; | ||
| 1574 | algorithm | ||
| 1575 | 188 | oldInfo := OldSimCode.EXTOBJINFO(SimVar.convertList(info.objects), {}); | |
| 1576 | end convert; | ||
| 1577 | end ExtObjInfo; | ||
| 1578 | |||
| 1579 | annotation(__OpenModelica_Interface="nbackend"); | ||
| 1580 | end NSimVar; | ||
| 1581 |