OMCompiler/Compiler/SimCode/SimCodeUtilShared.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 SimCodeUtilShared "Simulation-related SimCode generator helpers shared by the old and new backends. | ||
| 37 | |||
| 38 | This package holds the SimCode generator functions that both SimCodeUtil (old | ||
| 39 | backend) and NSimCode (new backend) need but that are *not* bootstrap-safe: they | ||
| 40 | pull in the full simulation datatypes (SimCode.ModelInfo) and the inliner, so they | ||
| 41 | must stay out of SimCodeFunctionUtil. SimCodeFunctionUtil is part of the bootstrap | ||
| 42 | set, where SimCode is only a stub and nothing simulation-related is available. | ||
| 43 | |||
| 44 | Keeping these here lets the new backend reuse them without depending on the entire | ||
| 45 | 16k-line SimCodeUtil (interface 'backend'); this module is tagged 'simcode_util' | ||
| 46 | like SimCodeFunctionUtil, so both backends already depend on it." | ||
| 47 | |||
| 48 | import Absyn; | ||
| 49 | import AvlTreePathFunction; | ||
| 50 | import DAE; | ||
| 51 | import HashTableCrIListArray; | ||
| 52 | import HashTableCrILst; | ||
| 53 | import UnorderedMap; | ||
| 54 | import Inline; | ||
| 55 | import SimCode; | ||
| 56 | import SimCodeFunction; | ||
| 57 | import SimCodeFunctionUtil; | ||
| 58 | import SimCodeVar; | ||
| 59 | import Util; | ||
| 60 | |||
| 61 | protected | ||
| 62 | |||
| 63 | import BaseHashTable; | ||
| 64 | import ComponentReference; | ||
| 65 | import ComponentReferenceBasics; | ||
| 66 | import Config; | ||
| 67 | import DAEUtil; | ||
| 68 | import Error; | ||
| 69 | import Flags; | ||
| 70 | import List; | ||
| 71 | |||
| 72 | public | ||
| 73 | |||
| 74 | protected function simulationFindLiterals | ||
| 75 | "Finds all literal expressions in functionsa" | ||
| 76 | input list<DAE.Function> fns; | ||
| 77 | output list<DAE.Function> ofns; | ||
| 78 | output tuple<Integer, UnorderedMap<DAE.Exp, Integer>, list<DAE.Exp>> literals; | ||
| 79 | algorithm | ||
| 80 | 1257 | (ofns, literals) := DAEUtil.traverseDAEFunctions( | |
| 81 | fns, SimCodeFunctionUtil.findLiteralsHelper, | ||
| 82 | (0, SimCodeFunctionUtil.newExpIndexMap(), {})); | ||
| 83 | // Broke things :( | ||
| 84 | // ((i, ht, literals)) := BackendDAEUtil.traverseBackendDAEExpsNoCopyWithUpdate(dae, findLiteralsHelper, (i, ht, literals)); | ||
| 85 | end simulationFindLiterals; | ||
| 86 | |||
| 87 | public function createFunctions | ||
| 88 | input Absyn.Program inProgram; | ||
| 89 | input AvlTreePathFunction.Tree functionTree; | ||
| 90 | output list<String> outLibs; | ||
| 91 | output list<String> outLibPaths; | ||
| 92 | output list<String> outIncludes; | ||
| 93 | output list<String> outIncludeDirs; | ||
| 94 | output list<SimCodeFunction.RecordDeclaration> outRecordDecls; | ||
| 95 | output list<SimCodeFunction.Function> outFunctions; | ||
| 96 | output tuple<Integer, UnorderedMap<DAE.Exp, Integer>, list<DAE.Exp>> outLiterals; | ||
| 97 | protected | ||
| 98 | list<DAE.Function> funcelems; | ||
| 99 | list<DAE.Exp> lits; | ||
| 100 | algorithm | ||
| 101 | try | ||
| 102 | // get all the used functions from the function tree | ||
| 103 | 1257 | funcelems := DAEUtil.getFunctionList(functionTree); | |
| 104 | 1257 | funcelems := Inline.inlineCallsInFunctions(funcelems, (NONE(), {DAE.NORM_INLINE(), DAE.AFTER_INDEX_RED_INLINE()})); | |
| 105 | 1257 | (funcelems, outLiterals as (_, _, lits)) := simulationFindLiterals(funcelems); | |
| 106 | 1257 | (outFunctions, outRecordDecls, outIncludes, outIncludeDirs, outLibs, outLibPaths) := SimCodeFunctionUtil.elaborateFunctions(inProgram, funcelems, {}, lits, {}); // Do we need metarecords here as well? | |
| 107 | else | ||
| 108 | ✗ | Error.addInternalError("Creation of Modelica functions failed.", sourceInfo()); | |
| 109 | ✗ | fail(); | |
| 110 | end try; | ||
| 111 | end createFunctions; | ||
| 112 | |||
| 113 | public function createVarToArrayIndexMapping | ||
| 114 | "Creates a mapping for each array-cref to the array dimensions (int list) and to the indices (for the code generation) used to store the array content. | ||
| 115 | Only the Cpp templates and HpcOm read the mappings, other targets get empty tables." | ||
| 116 | input SimCode.ModelInfo iModelInfo; | ||
| 117 | output HashTableCrIListArray.HashTable oVarToArrayIndexMapping; | ||
| 118 | output HashTableCrILst.HashTable oVarToIndexMapping; //same as oVarToArrayIndexMapping, but does not merge array variables into one list | ||
| 119 | protected | ||
| 120 | SimCodeVar.SimVars sim_vars; | ||
| 121 | list<tuple<list<SimCodeVar.SimVar>, Integer>> vars; | ||
| 122 | Integer table_size = 0; | ||
| 123 | list<SimCodeVar.SimVar> var_lst; | ||
| 124 | Integer var_type; | ||
| 125 | array<Integer> currentVarIndices; //current variable index real,int,bool,string | ||
| 126 | algorithm | ||
| 127 |
6/6✓ Branch 1 taken 1242 times.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 52 times.
✓ Branch 5 taken 1190 times.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 48 times.
|
1250 | if not (Flags.isSet(Flags.HPCOM) or Config.simCodeTarget() == "Cpp") then |
| 128 | 1194 | oVarToArrayIndexMapping := HashTableCrIListArray.emptyHashTableSized(1); | |
| 129 | 1194 | oVarToIndexMapping := HashTableCrILst.emptyHashTableSized(1); | |
| 130 | 1194 | return; | |
| 131 | end if; | ||
| 132 | |||
| 133 | // Collect the variable lists into a list for easier handling. | ||
| 134 | 56 | sim_vars := iModelInfo.vars; | |
| 135 | 56 | vars := { | |
| 136 | (sim_vars.stateVars, 1), | ||
| 137 | (sim_vars.derivativeVars, 1), | ||
| 138 | (sim_vars.algVars, 1), | ||
| 139 | (sim_vars.discreteAlgVars, 1), | ||
| 140 | (sim_vars.intAlgVars, 2), | ||
| 141 | (sim_vars.boolAlgVars, 3), | ||
| 142 | (sim_vars.stringAlgVars, 4), | ||
| 143 | (sim_vars.paramVars, 1), | ||
| 144 | (sim_vars.intParamVars, 2), | ||
| 145 | (sim_vars.boolParamVars, 3), | ||
| 146 | (sim_vars.stringParamVars, 4), | ||
| 147 | //(sim_vars.inputVars, 1), | ||
| 148 | //(sim_vars.utputVars, 1), | ||
| 149 | (sim_vars.constVars, 1), | ||
| 150 | (sim_vars.intConstVars, 2), | ||
| 151 | (sim_vars.boolConstVars, 3), | ||
| 152 | (sim_vars.stringConstVars, 4), | ||
| 153 | (sim_vars.realOptimizeConstraintsVars, 1), | ||
| 154 | (sim_vars.realOptimizeFinalConstraintsVars, 1), | ||
| 155 | (sim_vars.aliasVars, 1), | ||
| 156 | (sim_vars.intAliasVars, 2), | ||
| 157 | (sim_vars.boolAliasVars, 3), | ||
| 158 | (sim_vars.stringAliasVars, 4) | ||
| 159 | }; | ||
| 160 | |||
| 161 | // Count the number of variables to determine an appropriate size for the hash tables. | ||
| 162 |
2/2✓ Branch 0 taken 1176 times.
✓ Branch 1 taken 56 times.
|
1232 | for vl in vars loop |
| 163 | 1176 | (var_lst, _) := vl; | |
| 164 | 1176 | table_size := table_size + listLength(var_lst); | |
| 165 | end for; | ||
| 166 | 56 | table_size := Util.nextPrime(realInt(table_size * 1.4)); | |
| 167 | |||
| 168 | 56 | oVarToArrayIndexMapping := HashTableCrIListArray.emptyHashTableSized(table_size); | |
| 169 | 56 | oVarToIndexMapping := HashTableCrILst.emptyHashTableSized(table_size); | |
| 170 | 56 | currentVarIndices := arrayCreate(4, 1); //0 is reserved for unused variables | |
| 171 | |||
| 172 | // Add the variables to the tables. | ||
| 173 |
2/2✓ Branch 0 taken 1176 times.
✓ Branch 1 taken 56 times.
|
1232 | for vl in vars loop |
| 174 | 1176 | (var_lst, var_type) := vl; | |
| 175 | 1176 | (currentVarIndices, oVarToArrayIndexMapping, oVarToIndexMapping) := | |
| 176 | addVarToArrayIndexMappings(var_lst, var_type, currentVarIndices, oVarToArrayIndexMapping, oVarToIndexMapping); | ||
| 177 | end for; | ||
| 178 | end createVarToArrayIndexMapping; | ||
| 179 | |||
| 180 | public function addVarToArrayIndexMappings | ||
| 181 | input list<SimCodeVar.SimVar> vars; | ||
| 182 | input Integer iVarType; //1 = real ; 2 = int ; 3 = bool ; 4 = string | ||
| 183 | input output array<Integer> currentVarIndices; | ||
| 184 | input output HashTableCrIListArray.HashTable varToArrayIndexMapping; | ||
| 185 | input output HashTableCrILst.HashTable varToIndexMapping; | ||
| 186 | algorithm | ||
| 187 |
2/2✓ Branch 0 taken 17336 times.
✓ Branch 1 taken 1186 times.
|
18522 | for v in vars loop |
| 188 | 17336 | (currentVarIndices, varToArrayIndexMapping, varToIndexMapping) := | |
| 189 | addVarToArrayIndexMapping(v, iVarType, currentVarIndices, varToArrayIndexMapping, varToIndexMapping); | ||
| 190 | end for; | ||
| 191 | end addVarToArrayIndexMappings; | ||
| 192 | |||
| 193 | public function addVarToArrayIndexMapping "author: marcusw | ||
| 194 | Adds the given variable to the array-mapping and to the var-mapping. If the variable is part of an array 'a' which is not already part of the | ||
| 195 | given hash table, a new hash table element with size 'a.length' is allocated. The allocated arrays are row-major based." | ||
| 196 | input SimCodeVar.SimVar iVar; | ||
| 197 | input Integer iVarType; //1 = real ; 2 = int ; 3 = bool ; 4 = string | ||
| 198 | input output array<Integer> currentVarIndices; | ||
| 199 | input output HashTableCrIListArray.HashTable varToArrayIndexMapping; | ||
| 200 | input output HashTableCrILst.HashTable varToIndexMapping; | ||
| 201 | protected | ||
| 202 | DAE.ComponentRef name, arrayName; | ||
| 203 | Integer varIdx, arrayIndex; | ||
| 204 | array<Integer> varIndices; | ||
| 205 | list<Integer> arrayDimensions; | ||
| 206 | list<String> numArrayElement; | ||
| 207 | list<DAE.Subscript> arraySubscripts; | ||
| 208 | algorithm | ||
| 209 | () := match iVar | ||
| 210 | case SimCodeVar.SIMVAR(name=name, numArrayElement=numArrayElement) | ||
| 211 | algorithm | ||
| 212 | 17622 | (currentVarIndices,varIdx) := getArrayIdxByVar(iVar, iVarType, varToIndexMapping, currentVarIndices); | |
| 213 | //print("Adding variable " + ComponentReferenceBasics.printComponentRefStr(name) + " with type " + intString(iVarType) + " to map with index " + intString(varIdx) + "\n"); | ||
| 214 | 17622 | varToIndexMapping := BaseHashTable.add((name, {varIdx}), varToIndexMapping); | |
| 215 | 17622 | arraySubscripts := ComponentReference.crefLastSubs(name); | |
| 216 |
3/4✓ Branch 0 taken 9593 times.
✓ Branch 1 taken 8029 times.
✓ Branch 3 taken 9593 times.
✗ Branch 4 not taken.
|
17622 | if listEmpty(numArrayElement) or checkIfSubscriptsContainsUnhandlableIndices(arraySubscripts) then |
| 217 | arrayName := name; | ||
| 218 | else | ||
| 219 | 9593 | arrayName := ComponentReferenceBasics.crefStripLastSubs(name); | |
| 220 | end if; | ||
| 221 | |||
| 222 |
2/2✓ Branch 1 taken 38 times.
✓ Branch 2 taken 17584 times.
|
17622 | if isArrayVar(iVar) then |
| 223 | // store array dimensions and index of first element to indicate a contiguous array | ||
| 224 |
4/4✓ Branch 2 taken 44 times.
✓ Branch 3 taken 38 times.
✓ Branch 4 taken 44 times.
✓ Branch 5 taken 38 times.
|
82 | arrayDimensions := list(stringInt(e) for e in List.lastN(numArrayElement, listLength(numArrayElement))); |
| 225 | 38 | varIndices := arrayCreate(1, varIdx); | |
| 226 | 38 | varToArrayIndexMapping := BaseHashTable.add((arrayName, (arrayDimensions, varIndices)), varToArrayIndexMapping); | |
| 227 | elseif ComponentReferenceBasics.crefEqual(arrayName, name) then | ||
| 228 | // scalar variable | ||
| 229 | 10756 | varIndices := arrayCreate(1, varIdx); | |
| 230 | 10756 | varToArrayIndexMapping := BaseHashTable.add((arrayName, ({1},varIndices)), varToArrayIndexMapping); | |
| 231 | else | ||
| 232 | // store array dimensions and build up list of indices for elements | ||
| 233 |
2/2✓ Branch 1 taken 5013 times.
✓ Branch 2 taken 1815 times.
|
6828 | if BaseHashTable.hasKey(arrayName, varToArrayIndexMapping) then |
| 234 | 5013 | (arrayDimensions,varIndices) := BaseHashTable.get(arrayName, varToArrayIndexMapping); | |
| 235 | else | ||
| 236 | //print("Try to calculate array dimensions out of " + intString(listLength(numArrayElement)) + " array elements " + "\n"); | ||
| 237 |
4/4✓ Branch 2 taken 1980 times.
✓ Branch 3 taken 1815 times.
✓ Branch 4 taken 1980 times.
✓ Branch 5 taken 1815 times.
|
3795 | arrayDimensions := list(stringInt(e) for e in List.lastN(numArrayElement, listLength(arraySubscripts))); |
| 238 | //print("Allocating new array with " + intString(List.fold(arrayDimensions, intMul, 1)) + " elements.\n"); | ||
| 239 | 1815 | varIndices := arrayCreate(List.fold(arrayDimensions, intMul, 1), 0); | |
| 240 | end if; | ||
| 241 | //print("Num of array elements {" + stringDelimitList(List.map(arrayDimensions, intString), ",") + "} : " + intString(listLength(arraySubscripts)) + " arraySubs "+ExpressionDump.printSubscriptLstStr(arraySubscripts) + " arrayDimensions[ "+stringDelimitList(List.map(arrayDimensions,intString),",")+"]\n"); | ||
| 242 | 6828 | arrayIndex := getScalarElementIndex(arraySubscripts, arrayDimensions); | |
| 243 | //print("VarIndices: " + intString(arrayLength(varIndices)) + " arrayIndex: " + intString(arrayIndex) + " varIndex: " + intString(varIdx) + "\n"); | ||
| 244 | 6828 | varIndices := arrayUpdate(varIndices, arrayIndex, varIdx); | |
| 245 | 6828 | varToArrayIndexMapping := BaseHashTable.add((arrayName, (arrayDimensions,varIndices)), varToArrayIndexMapping); | |
| 246 | end if; | ||
| 247 | then | ||
| 248 | (); | ||
| 249 | |||
| 250 | else | ||
| 251 | algorithm | ||
| 252 | ✗ | Error.addMessage(Error.INTERNAL_ERROR, {"Unknown case for addVarToArrayIndexMapping.\n"}); | |
| 253 | then | ||
| 254 | (); | ||
| 255 | end match; | ||
| 256 | end addVarToArrayIndexMapping; | ||
| 257 | |||
| 258 | protected function checkIfSubscriptsContainsUnhandlableIndices "author: marcusw | ||
| 259 | Returns false if at least one subscript can not be handled as constant index." | ||
| 260 | input list<DAE.Subscript> iSubscripts; | ||
| 261 | output Boolean oContainsUnhandledSubscripts = false; | ||
| 262 | protected | ||
| 263 | DAE.Subscript subscript; | ||
| 264 | algorithm | ||
| 265 |
2/2✓ Branch 0 taken 8084 times.
✓ Branch 1 taken 9593 times.
|
17677 | for subscript in iSubscripts loop |
| 266 |
1/2✓ Branch 1 taken 8084 times.
✗ Branch 2 not taken.
|
8084 | if DAEUtil.getSubscriptIndex(subscript) < 0 then |
| 267 | oContainsUnhandledSubscripts := true; | ||
| 268 | break; | ||
| 269 | end if; | ||
| 270 | end for; | ||
| 271 | end checkIfSubscriptsContainsUnhandlableIndices; | ||
| 272 | |||
| 273 | protected function getArrayIdxByVar "author: marcusw | ||
| 274 | Get the storage-index of the given variable. If the variable is an alias, the storage position of the alias variable is returned. | ||
| 275 | If the variable is a negated alias, then the negated storage position of the alias variable is returned." | ||
| 276 | input SimCodeVar.SimVar iVar; | ||
| 277 | input Integer iVarType; | ||
| 278 | input HashTableCrILst.HashTable iVarToIndexMapping; | ||
| 279 | input output array<Integer> iCurrentVarIndices; | ||
| 280 | output Integer oVarIndex; | ||
| 281 | protected | ||
| 282 | DAE.ComponentRef varName, name; | ||
| 283 | Integer varIdx; | ||
| 284 | array<Integer> tmpCurrentVarIndices; | ||
| 285 | algorithm | ||
| 286 | oVarIndex := match(iVar, iCurrentVarIndices) | ||
| 287 | case(SimCodeVar.SIMVAR(name=name, aliasvar=SimCodeVar.NOALIAS()), tmpCurrentVarIndices) | ||
| 288 | algorithm | ||
| 289 | //print("getArrayIdxByVar: Handling common variable\n"); | ||
| 290 | 11828 | (varIdx,tmpCurrentVarIndices) := getVarToArrayIndexByType(iVar, iVarType, tmpCurrentVarIndices); | |
| 291 | then varIdx; | ||
| 292 | case(SimCodeVar.SIMVAR(name=name, aliasvar=SimCodeVar.NEGATEDALIAS(varName)), _) | ||
| 293 | algorithm | ||
| 294 | //print("getArrayIdxByVar: Handling negated alias variable pointing to " + ComponentReferenceBasics.printComponentRefStr(varName) + "\n"); | ||
| 295 |
1/2✓ Branch 1 taken 817 times.
✗ Branch 2 not taken.
|
817 | if(BaseHashTable.hasKey(varName, iVarToIndexMapping)) then |
| 296 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 817 times.
|
817 | varIdx::_ := BaseHashTable.get(varName, iVarToIndexMapping); |
| 297 | 817 | varIdx := intMul(varIdx,-1); | |
| 298 | elseif ComponentReference.isTime(varName) then | ||
| 299 | varIdx := 0; | ||
| 300 | else | ||
| 301 | ✗ | Error.addMessage(Error.INTERNAL_ERROR, {"Negated alias to unknown variable given."}); | |
| 302 | ✗ | fail(); | |
| 303 | end if; | ||
| 304 | then varIdx; | ||
| 305 | case(SimCodeVar.SIMVAR(name=name, aliasvar=SimCodeVar.ALIAS(varName)), _) | ||
| 306 | algorithm | ||
| 307 | //print("getArrayIdxByVar: Handling alias variable pointing to " + ComponentReferenceBasics.printComponentRefStr(varName) + "\n"); | ||
| 308 |
1/2✓ Branch 1 taken 4977 times.
✗ Branch 2 not taken.
|
4977 | if(BaseHashTable.hasKey(varName, iVarToIndexMapping)) then |
| 309 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4977 times.
|
4977 | varIdx::_ := BaseHashTable.get(varName, iVarToIndexMapping); |
| 310 | elseif ComponentReference.isTime(varName) then | ||
| 311 | varIdx := 0; | ||
| 312 | else | ||
| 313 | ✗ | Error.addMessage(Error.INTERNAL_ERROR, {"Alias to unknown variable given."}); | |
| 314 | ✗ | fail(); | |
| 315 | end if; | ||
| 316 | then varIdx; | ||
| 317 | end match; | ||
| 318 | end getArrayIdxByVar; | ||
| 319 | |||
| 320 | protected function getVarToArrayIndexByType "author: marcusw | ||
| 321 | Return the the current variable index of the given tuple, regarding the given type. The index-tuple is incremented and returned." | ||
| 322 | input SimCodeVar.SimVar iVar; | ||
| 323 | input Integer iVarType; //1 = real ; 2 = int ; 3 = bool ; 4 = string | ||
| 324 | output Integer oVarIdx; | ||
| 325 | input output array<Integer> iCurrentVarIndices; | ||
| 326 | algorithm | ||
| 327 | try | ||
| 328 | 11828 | oVarIdx := arrayGet(iCurrentVarIndices, iVarType); | |
| 329 | 11828 | arrayUpdate(iCurrentVarIndices, iVarType, oVarIdx + getNumElems(iVar)); | |
| 330 | else | ||
| 331 | ✗ | Error.addMessage(Error.INTERNAL_ERROR, {"GetVarToArrayIndexByType with unknown type called."}); | |
| 332 | oVarIdx := -1; | ||
| 333 | end try; | ||
| 334 | end getVarToArrayIndexByType; | ||
| 335 | |||
| 336 | public function getScalarElementIndex | ||
| 337 | "Calculate the one based memory offset for consecutive row major storage, | ||
| 338 | author: rfranke" | ||
| 339 | input list<DAE.Subscript> arraySubscripts; | ||
| 340 | input list<Integer> arrayDimensions; | ||
| 341 | output Integer arrayIndex; | ||
| 342 | protected | ||
| 343 | Integer idx, fac; | ||
| 344 | algorithm | ||
| 345 | arrayIndex := 1; // one based | ||
| 346 | fac := 1; | ||
| 347 |
2/2✓ Branch 1 taken 13499 times.
✓ Branch 2 taken 15113 times.
|
28612 | for i in listLength(arraySubscripts):-1:1 loop |
| 348 | 18332 | idx := DAEUtil.getSubscriptIndex(listGet(arraySubscripts, i)); | |
| 349 | 18332 | arrayIndex := arrayIndex + (idx - 1) * fac; | |
| 350 | 18332 | fac := fac * listGet(arrayDimensions, i); | |
| 351 | end for; | ||
| 352 | end getScalarElementIndex; | ||
| 353 | |||
| 354 | public function getNumElems | ||
| 355 | "Get number of scalar elements of a variable, rolling out arrays. | ||
| 356 | author: rfranke" | ||
| 357 | input SimCodeVar.SimVar var; | ||
| 358 | output Integer numElems; | ||
| 359 | algorithm | ||
| 360 | numElems := match var | ||
| 361 | case SimCodeVar.SIMVAR(type_ = DAE.T_ARRAY()) algorithm | ||
| 362 | numElems := 1; | ||
| 363 |
2/2✓ Branch 0 taken 1325 times.
✓ Branch 1 taken 1185 times.
|
2510 | for d in var.numArrayElement loop |
| 364 | 1325 | numElems := numElems * stringInt(d); | |
| 365 | end for; | ||
| 366 | then numElems; | ||
| 367 | else 1; | ||
| 368 | end match; | ||
| 369 | end getNumElems; | ||
| 370 | |||
| 371 | function isArrayVar | ||
| 372 | input SimCodeVar.SimVar var; | ||
| 373 | output Boolean isArray; | ||
| 374 | algorithm | ||
| 375 | isArray := match var | ||
| 376 | case SimCodeVar.SIMVAR(type_ = DAE.T_ARRAY()) then true; | ||
| 377 | else false; | ||
| 378 | end match; | ||
| 379 | end isArrayVar; | ||
| 380 | |||
| 381 | annotation(__OpenModelica_Interface="simcode_util"); | ||
| 382 | end SimCodeUtilShared; | ||
| 383 |