Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 0.0% 0 / 0 / 88
Functions: 0.0% 0 / 0 / 4
Branches: 0.0% 0 / 0 / 62

OMCompiler/SimulationRuntime/c/simulation/solver/mixedSearchSolver.c
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 /*! \file mixedSearchSolver.c
29 */
30
31 #include <math.h>
32 #include <stdlib.h>
33 #include <string.h> /* memcpy */
34
35 #include "../simulation_info_json.h"
36 #include "../../util/omc_error.h"
37 #include "../../util/varinfo.h"
38 #include "model_help.h"
39
40 #include "nonlinearSystem.h"
41 #include "nonlinearSolverHybrd.h"
42
43 typedef struct DATA_SEARCHMIXED_SOLVER
44 {
45 modelica_boolean* iterationVars;
46 modelica_boolean* iterationVars2;
47 modelica_boolean* iterationVarsPre;
48
49 long* iterationVarsIndex;
50
51 modelica_boolean* stateofSearch;
52
53 }DATA_SEARCHMIXED_SOLVER;
54
55
56 /*! \fn allocate memory for mixed systems search solver
57 *
58 */
59 ✗ int allocateMixedSearchData(int size, void** voiddata)
60 {
61 ✗ DATA_SEARCHMIXED_SOLVER* data = (DATA_SEARCHMIXED_SOLVER*) malloc(sizeof(DATA_SEARCHMIXED_SOLVER));
62 ✗ *voiddata = (void*)data;
63 ✗ assertStreamPrint(NULL, 0 != data, "allocationHybrdData() failed!");
64
65 ✗ data->iterationVars = (modelica_boolean*) malloc(size*sizeof(modelica_boolean));
66 ✗ data->iterationVars2 = (modelica_boolean*) malloc(size*sizeof(modelica_boolean));
67 ✗ data->iterationVarsPre = (modelica_boolean*) malloc(size*sizeof(modelica_boolean));
68
69 ✗ data->stateofSearch = (modelica_boolean*) malloc(size*sizeof(modelica_boolean));
70
71 assertStreamPrint(NULL, 0 != *voiddata, "allocateMixedSearchData() voiddata failed!");
72 ✗ return 0;
73 }
74
75 /*! \fn free memory for mixed systems search solver
76 *
77 */
78 ✗ int freeMixedSearchData(void **voiddata)
79 {
80 ✗ DATA_SEARCHMIXED_SOLVER* data = (DATA_SEARCHMIXED_SOLVER*) *voiddata;
81
82 ✗ free(data->iterationVars);
83 ✗ free(data->iterationVars2);
84 ✗ free(data->iterationVarsPre);
85
86 ✗ free(data->stateofSearch);
87
88 ✗ return 0;
89 }
90
91 /*! \fn nextVar
92 *
93 * function is used in generated code for mixed equation systems
94 * to generate next combination of boolean variables.
95 * Example: for n = 3
96 * generates sequence: 000, 100, 010, 001, 110, 101, 011, 111
97 *
98 * \param [ref] [data]
99 *
100 * \author Jan Silar
101 *
102 * \brief
103 */
104 ✗ modelica_boolean nextVar(modelica_boolean *b, int n) {
105 /*number of "1" */
106 int n1 = 0;
107 int i;
108 int last;
109 ✗ for(i = 0; i < n; i++){
110 ✗ if(b[i] == 1)
111 ✗ n1++;
112 }
113 /*index of last element with "1"*/
114 ✗ last = n - 1;
115 ✗ while(last >= 0 && !b[last])
116 ✗ last--;
117 ✗ if(n1 == n) /*exit - all combination were already generated*/
118 return 0;
119 ✗ else if(last == -1) { /* 0000 -> 1000 */
120 ✗ b[0] = 1;
121 ✗ return 1;
122 ✗ } else if(last < n - 1) { /* e.g. 1010 -> 1001 */
123 ✗ b[last] = 0;
124 ✗ b[last + 1] = 1;
125 ✗ return 1;
126 } else { /*at the end of the array is "1"*/
127 /*detect position of last ocurenc of sequence 10 */
128 ✗ int ip = n - 2; /*actual position in array*/
129 int nr1 = 1; /*count of "1"*/
130 ✗ while(ip >= 0) {
131 ✗ if(b[ip] && !b[ip + 1]) { /*we found*/
132 ✗ nr1++;
133 ✗ break;
134 ✗ } else if(b[ip]) { /*we didn't find, but 1 - increase nr1*/
135 ✗ nr1++;
136 ✗ ip--;
137 } else { /*we didnt't find, 0*/
138 ✗ ip--;
139 }
140 }
141 ✗ if(ip >= 0) { /*e.g. 1001 -> 0110*/
142 ✗ int pn = ip + nr1;
143 ✗ b[ip] = 0;
144 ✗ for(i = ip + 1; i <= pn; i++)
145 ✗ b[i] = 1;
146 ✗ for(i = pn + 1; i <= n - 1; i++)
147 ✗ b[i] = 0;
148 return 1;
149 } else {
150 ✗ for(i = 0; i <= n1; i++)
151 ✗ b[i] = 1;
152 ✗ for(i = n1 + 1; i <= n - 1; i++)
153 ✗ b[i] = 0;
154 return 1;
155 }
156 }
157 }
158
159 /*! \fn solve mixed system with extended search
160 *
161 * \param [in] [data]
162 * [sysNumber] index of the corresponing mixed system
163 *
164 * \author wbraun
165 */
166 ✗ int solveMixedSearch(DATA *data, int sysNumber)
167 {
168 ✗ MIXED_SYSTEM_DATA* systemData = &(data->simulationInfo->mixedSystemData[sysNumber]);
169 ✗ DATA_SEARCHMIXED_SOLVER* solverData = (DATA_SEARCHMIXED_SOLVER*)systemData->solverData;
170
171 ✗ int eqSystemNumber = systemData->equationIndex;
172
173 int found_solution = 0;
174 /*
175 * We are given the number of the non-linear system.
176 * We want to look it up among all equations.
177 */
178 int i, ix;
179
180 int mixedIterations = 0;
181 int success = 0;
182
183 // FIXME there is no messageCloseDebug so we use infoStreamPrint here
184 ✗ infoStreamPrint(OMC_LOG_MIXED, 1, "\n#### Start solver mixed equation system at time %f.", data->localData[0]->timeValue);
185
186 ✗ memset(solverData->stateofSearch, 0, systemData->size);
187
188 /* update pre iteration vars */
189 /* update iteration vars */
190 ✗ for(i=0;i<systemData->size;++i)
191 ✗ solverData->iterationVarsPre[i] = *(systemData->iterationVarsPtr[i]);
192
193 do
194 {
195 /* update pre iteration vars */
196 ✗ for(i=0;i<systemData->size;++i)
197 ✗ solverData->iterationVars[i] = *(systemData->iterationVarsPtr[i]);
198
199 /* solve continuous equation part
200 * and update iteration variables in model
201 */
202 ✗ systemData->solveContinuousPart(data);
203 ✗ systemData->updateIterationExps(data);
204
205 /* set new values of boolean variable */
206 ✗ for(i=0;i<systemData->size;++i) {
207 ✗ solverData->iterationVars2[i] = *(systemData->iterationVarsPtr[i]);
208 }
209
210 ✗ found_solution = systemData->continuous_solution;
211
212 /* restart if any relation has changed */
213 ✗ if(checkRelations(data))
214 {
215 ✗ updateRelationsPre(data);
216 ✗ systemData->updateIterationExps(data);
217 ✗ if(mixedIterations++ > 200)
218 found_solution = -4; /* mixedIterations++ > 200 */
219 }
220
221 ✗ if(found_solution == -1)
222 {
223 /* system of equations failed */
224 found_solution = -2;
225 }
226 else
227 {
228 found_solution = 1;
229 ✗ for(i = 0; i < systemData->size; i++)
230 {
231 ✗ if(solverData->iterationVars[i] != solverData->iterationVars2[i])
232 {
233 found_solution = 0;
234 break;
235 }
236 }
237 }
238
239 ✗ if(!found_solution )
240 {
241 /* try next set of values*/
242 ✗ if(nextVar(solverData->stateofSearch, systemData->size))
243 {
244 ✗ for(i = 0; i < systemData->size; i++)
245 ✗ *(systemData->iterationVarsPtr[i]) = *(systemData->iterationPreVarsPtr[i]) != solverData->stateofSearch[i];
246
247 /* debug output */
248 ✗ if(OMC_ACTIVE_STREAM(OMC_LOG_MIXED))
249 {
250 const char * __name;
251 for(i = 0; i < systemData->size; i++)
252 {
253 ix = (systemData->iterationVarsPtr[i]-data->localData[0]->booleanVars);
254 __name = data->modelData->booleanVarsData[ix].info.name;
255 }
256 }
257 }
258 else
259 {
260 /* while the initialization it's okay not a solution */
261 ✗ if(!data->simulationInfo->initial)
262 {
263 ✗ warningStreamPrint(OMC_LOG_STDOUT, 0,
264 "Error solving mixed equation system with index %d at time %e",
265 ✗ eqSystemNumber, data->localData[0]->timeValue);
266 }
267 ✗ data->simulationInfo->needToIterate = 1;
268 found_solution = -1;
269 /*TODO: "break simulation?"*/
270 }
271 }
272 /* we found a solution*/
273 ✗ if(found_solution == 1)
274 {
275 success = 1;
276 ✗ if(OMC_ACTIVE_STREAM(OMC_LOG_MIXED))
277 {
278 const char * __name;
279 for(i = 0; i < systemData->size; i++)
280 {
281 ix = (systemData->iterationVarsPtr[i]-data->localData[0]->booleanVars);
282 __name = data->modelData->booleanVarsData[ix].info.name;
283 }
284 }
285 }
286
287 ✗ mixedIterations++;
288
289 ✗ }while(!found_solution);
290
291 ✗ messageClose(OMC_LOG_MIXED);
292 ✗ return success;
293 }
294