OMCompiler/SimulationRuntime/cpp/Core/Solver/SystemStateSelection.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * This file belongs to the OpenModelica Run-Time System | ||
| 3 | * | ||
| 4 | * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC), c/o Linköpings | ||
| 5 | * universitet, Department of Computer and Information Science, SE-58183 Linköping, Sweden. All rights | ||
| 6 | * reserved. | ||
| 7 | * | ||
| 8 | * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THE BSD NEW LICENSE OR THE | ||
| 9 | * AGPL VERSION 3 LICENSE OR THE OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8. ANY | ||
| 10 | * USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES RECIPIENT'S | ||
| 11 | * ACCEPTANCE OF THE BSD NEW LICENSE OR THE OSMC PUBLIC LICENSE OR THE AGPL | ||
| 12 | * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. | ||
| 13 | * | ||
| 14 | * The OpenModelica software and the OSMC (Open Source Modelica Consortium) Public License | ||
| 15 | * (OSMC-PL) are obtained from OSMC, either from the above address, from the URLs: | ||
| 16 | * http://www.openmodelica.org or https://github.com/OpenModelica/ or | ||
| 17 | * http://www.ida.liu.se/projects/OpenModelica, and in the OpenModelica distribution. GNU | ||
| 18 | * AGPL version 3 is obtained from: https://www.gnu.org/licenses/licenses.html#GPL. The BSD NEW | ||
| 19 | * License is obtained from: http://www.opensource.org/licenses/BSD-3-Clause. | ||
| 20 | * | ||
| 21 | * This program is distributed WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY | ||
| 23 | * SET FORTH IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF | ||
| 24 | * OSMC-PL. | ||
| 25 | * | ||
| 26 | */ | ||
| 27 | |||
| 28 | /** @addtogroup coreSolver | ||
| 29 | * | ||
| 30 | * @{ | ||
| 31 | */ | ||
| 32 | #include <Core/ModelicaDefine.h> | ||
| 33 | #include <Core/Modelica.h> | ||
| 34 | #include <Core/Solver/FactoryExport.h> | ||
| 35 | #include <Core/Solver/SystemStateSelection.h> | ||
| 36 | #include <Core/Math/ArrayOperations.h> | ||
| 37 | #include <Core/Math/Functions.h> | ||
| 38 | #include <Core/Utils/extension/logger.hpp> | ||
| 39 | |||
| 40 | |||
| 41 | 40 | SystemStateSelection::SystemStateSelection(IMixedSystem* system) | |
| 42 | 40 | :_system(system) | |
| 43 | 40 | ,_colPivot() | |
| 44 |
1/2✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
|
40 | ,_rowPivot() |
| 45 | 40 | ,_initialized(false) | |
| 46 | 40 | ,_jac(NULL) | |
| 47 | { | ||
| 48 | |||
| 49 |
1/2✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
|
40 | _state_selection = dynamic_cast<IStateSelection*>(system); |
| 50 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
|
40 | if ( !_state_selection) |
| 51 | ✗ | throw ModelicaSimulationError(MATH_FUNCTION,"No state selection system"); | |
| 52 | |||
| 53 | 40 | } | |
| 54 | |||
| 55 | 40 | void SystemStateSelection::initialize() | |
| 56 | { | ||
| 57 | #if defined(__vxworks) | ||
| 58 | #else | ||
| 59 | 40 | _dimStateSets = _state_selection->getDimStateSets(); | |
| 60 | |||
| 61 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
|
40 | _dimStates.clear(); |
| 62 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
|
40 | _dimStateCanditates.clear(); |
| 63 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
|
40 | _dimDummyStates.clear(); |
| 64 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
|
40 | _rowPivot.clear(); |
| 65 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
|
40 | _colPivot.clear(); |
| 66 | 40 | unsigned int maxJacSize = 0; | |
| 67 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 40 times.
|
41 | for(int i=0; i<_dimStateSets; i++) |
| 68 | { | ||
| 69 | 1 | _dimStates.push_back(_state_selection->getDimStates(i)); | |
| 70 | 1 | _dimStateCanditates.push_back(_state_selection->getDimCanditates(i)); | |
| 71 | 1 | _dimDummyStates.push_back(_dimStateCanditates[i]-_dimStates[i]); | |
| 72 | |||
| 73 | 2 | _rowPivot.push_back(std::vector<int>(_dimDummyStates[i])); | |
| 74 | 1 | _colPivot.push_back(std::vector<int>(_dimStateCanditates[i])); | |
| 75 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
|
2 | for(int n=0; n<_dimDummyStates[i]; n++) |
| 76 | 1 | _rowPivot[i][n] = n; | |
| 77 | |||
| 78 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 time.
|
5 | for(int n=0; n<_dimStateCanditates[i]; n++) |
| 79 | 4 | _colPivot[i][n] = _dimStateCanditates[i]-n-1; | |
| 80 | |||
| 81 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
2 | maxJacSize = max(maxJacSize, _dimDummyStates[i]*_dimStateCanditates[i]); |
| 82 | } | ||
| 83 | 40 | _jac = new double[maxJacSize]; | |
| 84 | |||
| 85 | 40 | _initialized = true; | |
| 86 | #endif | ||
| 87 | 40 | } | |
| 88 | |||
| 89 | 40 | SystemStateSelection::~SystemStateSelection() | |
| 90 | { | ||
| 91 | #if defined(__vxworks) | ||
| 92 | #else | ||
| 93 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 39 times.
|
40 | _rowPivot.clear(); |
| 94 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 39 times.
|
40 | _colPivot.clear(); |
| 95 |
1/2✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
|
40 | if (_jac) |
| 96 | 40 | delete [] _jac; | |
| 97 | #endif | ||
| 98 | 40 | } | |
| 99 | |||
| 100 | 323648 | bool SystemStateSelection::stateSelection(int switchStates) | |
| 101 | { | ||
| 102 | #if defined(__vxworks) | ||
| 103 | return true; | ||
| 104 | #else | ||
| 105 |
2/2✓ Branch 0 taken 40 times.
✓ Branch 1 taken 323608 times.
|
323648 | if(!_initialized) |
| 106 | 40 | initialize(); | |
| 107 | int res=0; | ||
| 108 | int changed = false; | ||
| 109 |
2/2✓ Branch 0 taken 581 times.
✓ Branch 1 taken 323648 times.
|
324229 | for(int i=0; i<_dimStateSets; i++) |
| 110 | { | ||
| 111 |
1/2✓ Branch 2 taken 581 times.
✗ Branch 3 not taken.
|
581 | std::vector<int> oldColPivot(_dimStateCanditates[i]); |
| 112 |
1/4✓ Branch 1 taken 581 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
581 | std::vector<int> oldRowPivot(_dimDummyStates[i]); |
| 113 |
1/2✓ Branch 1 taken 581 times.
✗ Branch 2 not taken.
|
581 | const matrix_t& stateset_matrix = _system->getStateSetJacobian(i); |
| 114 | |||
| 115 | /* call pivoting function to select the states */ | ||
| 116 |
1/2✓ Branch 0 taken 581 times.
✗ Branch 1 not taken.
|
581 | memcpy(oldColPivot.data(), _colPivot[i].data(), _dimStateCanditates[i]*sizeof(int)); |
| 117 | 581 | memcpy(oldRowPivot.data(), _rowPivot[i].data(), _dimDummyStates[i]*sizeof(int)); | |
| 118 |
2/4✓ Branch 0 taken 581 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 581 times.
✗ Branch 4 not taken.
|
1162 | memcpy(_jac, stateset_matrix.data().begin(), _dimDummyStates[i]*_dimStateCanditates[i]*sizeof(double)); |
| 119 | |||
| 120 |
2/6✓ Branch 1 taken 581 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 581 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
581 | if(pivot(_jac, _dimDummyStates[i], _dimStateCanditates[i], _rowPivot[i].data(), _colPivot[i].data()) != 0) |
| 121 | { | ||
| 122 | ✗ | LOGGER_WRITE("Singular Jacobian for dynamic state selection in set " + to_string(i + 1), LC_SOLVER, LL_WARNING); | |
| 123 | continue; | ||
| 124 | } | ||
| 125 | /* if we have a new set throw event for reinitialization | ||
| 126 | and set the A matrix for set.x=A*(states) */ | ||
| 127 |
1/2✓ Branch 1 taken 581 times.
✗ Branch 2 not taken.
|
581 | res = comparePivot(oldColPivot.data(), _colPivot[i].data(), switchStates,i); |
| 128 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 581 times.
|
581 | if(!switchStates) |
| 129 | { | ||
| 130 | ✗ | memcpy(_colPivot[i].data(), oldColPivot.data(), _dimStateCanditates[i]*sizeof(int)); | |
| 131 | ✗ | memcpy(_rowPivot[i].data(), oldRowPivot.data(), _dimDummyStates[i]*sizeof(int)); | |
| 132 | } | ||
| 133 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 580 times.
|
581 | if(res) |
| 134 | { | ||
| 135 | ✗ | LOGGER_WRITE("Dynamic state selection changed set " + to_string(i + 1), LC_SOLVER, LL_DEBUG); | |
| 136 | changed = true; | ||
| 137 | } | ||
| 138 | } | ||
| 139 | 323648 | return changed; | |
| 140 | #endif | ||
| 141 | } | ||
| 142 | |||
| 143 | 1 | void SystemStateSelection::setAMatrix(int* newEnable, unsigned int index) | |
| 144 | { | ||
| 145 | #if defined(__vxworks) | ||
| 146 | #else | ||
| 147 | int col; | ||
| 148 | int row=0; | ||
| 149 | DynArrayDim2<int> A2; | ||
| 150 | DynArrayDim1<int> A1; | ||
| 151 | double* states;//states | ||
| 152 | double* states2;//state candidates | ||
| 153 |
1/2✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
|
1 | states = new double[_dimStates[index]]; |
| 154 |
1/2✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
|
1 | states2 = new double[_dimStateCanditates[index]]; |
| 155 |
1/2✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
|
1 | _state_selection->getStates(index,states); |
| 156 |
1/2✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
|
1 | _state_selection->getStateCanditates(index,states2); |
| 157 | |||
| 158 |
2/4✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
✗ Branch 4 not taken.
|
1 | if( _state_selection->getAMatrix(index,A2)) |
| 159 | { | ||
| 160 |
1/2✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
|
1 | fill_array<int>(A2,0); |
| 161 | |||
| 162 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 time.
|
5 | for(col=0; col<_dimStateCanditates[index]; col++) |
| 163 | { | ||
| 164 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 time.
|
4 | if(newEnable[col]==2) |
| 165 | { | ||
| 166 | /* set A[row, col] */ | ||
| 167 | 3 | A2(row+1,col+1) = 1; | |
| 168 | ///* reinit state */ | ||
| 169 | 3 | states[row] =states2[col]; | |
| 170 | row++; | ||
| 171 | } | ||
| 172 | } | ||
| 173 |
1/2✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
|
1 | _state_selection->setAMatrix(index,A2); |
| 174 | |||
| 175 | } | ||
| 176 | ✗ | else if( _state_selection->getAMatrix(index,A1)) | |
| 177 | { | ||
| 178 | ✗ | fill_array<int>(A1,0); | |
| 179 | |||
| 180 | ✗ | for(col=0; col<_dimStateCanditates[index]; col++) | |
| 181 | { | ||
| 182 | ✗ | if(newEnable[col]==2) | |
| 183 | { | ||
| 184 | /* set A[row, col] */ | ||
| 185 | ✗ | A1(row+col+1) = 1; | |
| 186 | ///* reinit state */ | ||
| 187 | ✗ | states[row] =states2[col]; | |
| 188 | ✗ | row++; | |
| 189 | } | ||
| 190 | } | ||
| 191 | ✗ | _state_selection->setAMatrix(index,A1); | |
| 192 | } | ||
| 193 | else | ||
| 194 | ✗ | throw ModelicaSimulationError(MATH_FUNCTION,"No A matrix availibale for state selection"); | |
| 195 |
1/2✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
|
1 | _state_selection->setStates(index,states); |
| 196 | 1 | delete [] states ; | |
| 197 | 1 | delete [] states2 ; | |
| 198 | #endif | ||
| 199 | 1 | } | |
| 200 | |||
| 201 | |||
| 202 | 581 | int SystemStateSelection::comparePivot(int *oldPivot, int *newPivot,int switchStates,unsigned int index) | |
| 203 | { | ||
| 204 | |||
| 205 | int ret = 0; | ||
| 206 | 581 | int* oldEnable = new int[_dimStateCanditates[index] ]; | |
| 207 | 581 | int* newEnable = new int[_dimStateCanditates[index] ]; | |
| 208 | |||
| 209 |
2/2✓ Branch 0 taken 2324 times.
✓ Branch 1 taken 581 times.
|
2905 | for(int i=0; i<_dimStateCanditates[index]; i++) |
| 210 | { | ||
| 211 |
2/2✓ Branch 0 taken 1743 times.
✓ Branch 1 taken 581 times.
|
2324 | int entry = (i < _dimDummyStates[index]) ? 1: 2; |
| 212 | 2324 | newEnable[ newPivot[i] ] = entry; | |
| 213 | 2324 | oldEnable[ oldPivot[i] ] = entry; | |
| 214 | } | ||
| 215 | |||
| 216 |
2/2✓ Branch 0 taken 2321 times.
✓ Branch 1 taken 580 times.
|
2901 | for(int i=0; i<_dimStateCanditates[index]; i++) |
| 217 | { | ||
| 218 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 2320 times.
|
2321 | if(newEnable[i] != oldEnable[i]) |
| 219 | { | ||
| 220 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if(switchStates) |
| 221 | { | ||
| 222 | |||
| 223 | 1 | setAMatrix(newEnable,index); | |
| 224 | |||
| 225 | } | ||
| 226 | ret = -1; | ||
| 227 | break; | ||
| 228 | } | ||
| 229 | } | ||
| 230 | |||
| 231 | 581 | delete [] oldEnable; | |
| 232 | 581 | delete [] newEnable; | |
| 233 | |||
| 234 | 581 | return ret; | |
| 235 | } | ||
| 236 | /** @} */ // end of coreSolver | ||
| 237 |