Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 34.3% 244 / 0 / 712
Functions: 50.0% 13 / 0 / 26
Branches: 20.4% 168 / 0 / 824

OMCompiler/SimulationRuntime/c/simulation/simulation_runtime.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 #include "util/omc_msvc.h"
29
30 #include <setjmp.h>
31 #include <string>
32 #include <iostream>
33 #include <sstream>
34 #include <limits>
35 #include <list>
36 #include <cmath>
37 #include <iomanip>
38 #include <ctime>
39 #include <cstdio>
40 #include <cstring>
41 #include <cassert>
42 #include <signal.h>
43 #include <fstream>
44 #include <stdarg.h>
45
46 #ifndef _MSC_VER
47 #include <regex.h>
48 #endif
49
50 /* For CommandLineToArgvW. */
51 #if defined(__MINGW32__) || defined(_MSC_VER)
52 #include <windows.h>
53 #include <shellapi.h>
54 #endif
55
56 /* ppriv - NO_INTERACTIVE_DEPENDENCY - for simpler debugging in Visual Studio
57 *
58 */
59 #ifndef NO_INTERACTIVE_DEPENDENCY
60 #include "socket.h"
61 extern Socket sim_communication_port;
62 #endif
63
64 #include "util/omc_error.h"
65 #include "util/omc_file.h"
66 #include "util/omc_numbers.h"
67 #include "util/omc_strdup.h"
68 #include "simulation_data.h"
69 #include "openmodelica_func.h"
70
71 #include "linearization/linearize.h"
72 #include "options.h"
73 #include "simulation_runtime.h"
74 #include "simulation_input_xml.h"
75 #include "arrayIndex.h"
76 #include "simulation/results/simulation_result_ia.h"
77 #include "simulation/results/simulation_result_rust.h"
78 #include "simulation/solver/solver_main.h"
79 #include "simulation/solver/gbode_util.h"
80 #include "simulation_info_json.h"
81 #include "modelinfo.h"
82 #include "simulation/solver/events.h"
83 #include "simulation/solver/model_help.h"
84 #include "simulation/solver/mixedSystem.h"
85 #include "simulation/solver/linearSystem.h"
86 #include "simulation/solver/nonlinearSystem.h"
87 #include "util/rtclock.h"
88 #include "omc_config.h"
89 #include "simulation/solver/initialization/initialization.h"
90 #include "simulation/solver/dae_mode.h"
91 #include "dataReconciliation/dataReconciliation.h"
92
93 #ifdef _OMC_QSS_LIB
94 #include "solver_qss/solver_qss.h"
95 #endif
96
97 using namespace std;
98
99 #ifndef NO_INTERACTIVE_DEPENDENCY
100 Socket sim_communication_port;
101 static int sim_communication_port_open = 0;
102 static int isXMLTCP=0;
103 #endif
104
105 extern "C" {
106
107 int sim_noemit = 0; /* Flag for not emitting data */
108
109 const std::string *init_method = NULL; /* method for initialization. */
110
111 static int callSolver(DATA* simData, threadData_t *threadData, string init_initMethod, string init_file,
112 double init_time, string outputVariablesAtEnd, int cpuTime, const char *argv_0);
113
114 /*! \fn void setGlobalVerboseLevel(int argc, char**argv)
115 *
116 * \brief determine verboselevel by investigating flag -lv flags
117 *
118 * Valid flags: see OMC_LOG_STREAM_NAME in omc_error.c
119 */
120 1 void setGlobalVerboseLevel(int argc, char**argv)
121 {
122 1 const char *cflags = omc_flagValue[FLAG_LV];
123
2/3
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 4 taken 1 time.
1 const string *flags = cflags ? new string(cflags) : NULL;
124 int i;
125
126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_W])
127 ✗ omc_showAllWarnings = 1;
128
129
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(!flags)
130 {
131 /* default activated */
132 ✗ omc_useStream[OMC_LOG_STDOUT] = 1;
133 ✗ omc_useStream[OMC_LOG_ASSERT] = 1;
134 ✗ omc_useStream[OMC_LOG_SUCCESS] = 1;
135 ✗ return; // no lv flag given.
136 }
137
138 /* default activated, but it can be disabled with -LOG_STDOUT or -LOG_ASSERT */
139 1 omc_useStream[OMC_LOG_STDOUT] = 1;
140 1 omc_useStream[OMC_LOG_ASSERT] = 1;
141
142
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(flags->find("LOG_ALL", 0) != string::npos)
143 {
144 ✗ for(i=1; i<OMC_SIM_LOG_MAX; ++i)
145 ✗ omc_useStream[i] = 1;
146 }
147 else
148 {
149 string flagList = *flags;
150 string flag;
151 mmc_uint_t pos;
152
153 do
154 {
155 int error = 1;
156 pos = flagList.find(",", 0);
157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(pos != string::npos)
158 {
159 ✗ flag = flagList.substr(0, pos);
160 ✗ flagList = flagList.substr(pos+1);
161 }
162 else
163 {
164 flag = flagList;
165 }
166
167
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 for(i=firstOMCErrorStream; i<OMC_SIM_LOG_MAX; ++i)
168 {
169
5/5
✓ Branch 1 taken 48 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 39 times.
✓ Branch 5 taken 1 time.
✓ Branch 6 taken 47 times.
57 if(flag == string(OMC_LOG_STREAM_NAME[i]))
170 {
171 1 omc_useStream[i] = 1;
172 error = 0;
173 break;
174 }
175
9/15
✓ Branch 1 taken 47 times.
✓ Branch 4 taken 47 times.
✓ Branch 7 taken 47 times.
✓ Branch 9 taken 12 times.
✓ Branch 10 taken 35 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 47 times.
✓ Branch 13 taken 9 times.
✓ Branch 14 taken 38 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 47 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
68 else if(flag == string("-") + string(OMC_LOG_STREAM_NAME[i]))
176 {
177 ✗ omc_useStream[i] = 0;
178 error = 0;
179 break;
180 }
181 }
182
183 if(error)
184 {
185 ✗ warningStreamPrint(OMC_LOG_STDOUT, 1, "current options are:");
186 ✗ for(i=firstOMCErrorStream; i<OMC_SIM_LOG_MAX; ++i)
187 ✗ warningStreamPrint(OMC_LOG_STDOUT, 0, "%-18s [%s]", OMC_LOG_STREAM_NAME[i], OMC_LOG_STREAM_DESC[i]);
188 ✗ messageCloseWarning(OMC_LOG_STDOUT);
189 ✗ throwStreamPrint(NULL,"unrecognized option -lv %s", flags->c_str());
190 }
191
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 }while(pos != string::npos);
192 }
193
194 /* print OMC_LOG_GBODE if OMC_LOG_GBODE_V if active */
195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_useStream[OMC_LOG_GBODE_V] == 1)
196 ✗ omc_useStream[OMC_LOG_GBODE] = 1;
197
198 /* print OMC_LOG_GBODE_NLS if OMC_LOG_GBODE_NLS_V if active */
199
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_useStream[OMC_LOG_GBODE_NLS_V] == 1)
200 ✗ omc_useStream[OMC_LOG_GBODE_NLS] = 1;
201
202 /* print OMC_LOG_INIT and OMC_LOG_SOTI if OMC_LOG_INIT_V is active */
203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_useStream[OMC_LOG_INIT_V] == 1)
204 {
205 ✗ omc_useStream[OMC_LOG_INIT] = 1;
206 ✗ omc_useStream[OMC_LOG_SOTI] = 1;
207 }
208
209 /* print OMC_LOG_INIT_HOMOTOPY if OMC_LOG_INIT is active */
210
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_useStream[OMC_LOG_INIT] == 1)
211 ✗ omc_useStream[OMC_LOG_INIT_HOMOTOPY] = 1;
212
213 /* print OMC_LOG_STATS if OMC_LOG_SOLVER if active */
214
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 if(omc_useStream[OMC_LOG_SOLVER_V] == 1)
215 1 omc_useStream[OMC_LOG_SOLVER] = 1;
216
217 /* print OMC_LOG_STATS if OMC_LOG_SOLVER if active */
218
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 if(omc_useStream[OMC_LOG_SOLVER] == 1)
219 1 omc_useStream[OMC_LOG_STATS] = 1;
220
221 /* print OMC_LOG_STATS if OMC_LOG_STATS_V if active */
222
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_useStream[OMC_LOG_STATS_V] == 1)
223 ✗ omc_useStream[OMC_LOG_STATS] = 1;
224
225 /* print OMC_LOG_NLS if OMC_LOG_NLS_V if active */
226
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_useStream[OMC_LOG_NLS_V])
227 ✗ omc_useStream[OMC_LOG_NLS] = 1;
228
229 /* print OMC_LOG_NLS if OMC_LOG_NLS_RES if active */
230
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_useStream[OMC_LOG_NLS_RES])
231 ✗ omc_useStream[OMC_LOG_NLS] = 1;
232
233 /* print OMC_LOG_EVENTS if OMC_LOG_EVENTS_V if active */
234
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_useStream[OMC_LOG_EVENTS_V]) {
235 ✗ omc_useStream[OMC_LOG_EVENTS] = 1;
236 }
237
238 /* print OMC_LOG_NLS if OMC_LOG_NLS_JAC if active */
239
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_useStream[OMC_LOG_NLS_JAC])
240 ✗ omc_useStream[OMC_LOG_NLS] = 1;
241
242 /* print OMC_LOG_DSS if OMC_LOG_DSS_JAC if active */
243
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_useStream[OMC_LOG_DSS_JAC])
244 ✗ omc_useStream[OMC_LOG_DSS] = 1;
245
246 1 delete flags;
247 }
248
249
250 /**
251 * @brief Read value of flag lv_time to set time interval in which logging is active.
252 *
253 * @param simulationInfo Simulation info struct
254 */
255 1 void setGlobalLoggingTime(SIMULATION_INFO *simulationInfo)
256 {
257 1 const char *flagStr = omc_flagValue[FLAG_LV_TIME];
258
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1 const string *flags = flagStr ? new string(flagStr) : NULL;
259 char *endptr;
260 const char *secondPart;
261 double loggingStartTime, loggingStopTime;
262
263 /* Check if lv_time flag is given */
264
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if (flagStr==NULL || *flagStr=='\0')
265 {
266 /* default activated --> Log everything */
267 1 simulationInfo->useLoggingTime = 0;
268 1 return;
269 }
270
271 /* Parse flagStr */
272 ✗ loggingStartTime = om_strtod(flagStr, &endptr);
273 ✗ endptr = endptr+1;
274 secondPart = endptr;
275 ✗ loggingStopTime = om_strtod(secondPart, &endptr);
276 ✗ if (*endptr)
277 {
278 ✗ throwStreamPrint(NULL, "Simulation flag %s expects two real numbers, separated by a commas. Got: %s", FLAG_NAME[FLAG_LV_TIME], flagStr);
279 }
280
281 /* Check flag input */
282 ✗ if (loggingStartTime > loggingStopTime)
283 {
284 ✗ throwStreamPrint(NULL, "Simulation flag %s expects first number to be smaller then second number. Got: %s", FLAG_NAME[FLAG_LV_TIME], flagStr);
285 }
286
287 /* Save logging time */
288 ✗ simulationInfo->useLoggingTime = 1;
289 ✗ simulationInfo->loggingTimeRecord[0] = loggingStartTime;
290 ✗ simulationInfo->loggingTimeRecord[1] = loggingStopTime;
291 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "Time dependent logging enabled. Activate logging in interval [%f, %f]", simulationInfo->loggingTimeRecord[0], simulationInfo->loggingTimeRecord[1]);
292
293 /* Deactivate Logging */
294 ✗ deactivateLogging();
295 }
296
297
298 6 static void readFlag(int *flag, int max, const char *value, const char *flagName, const char **names, const char **desc)
299 {
300 int i;
301
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!value) {
302 return; /* keep the default value */
303 }
304
305 ✗ for (i=1; i<max; ++i) {
306 ✗ if (names[i] != NULL && 0 == strcmp(value, names[i])) {
307 ✗ *flag = i;
308 ✗ return;
309 }
310 }
311
312 ✗ warningStreamPrint(OMC_LOG_STDOUT, 1, "unrecognized option %s=%s, current options are:", flagName, value);
313 ✗ for (i=1; i<max; ++i) {
314 ✗ if (names[i] != NULL) {
315 ✗ warningStreamPrint(OMC_LOG_STDOUT, 0, "%-19s [%s]", names[i], desc[i] != NULL ? desc[i] : "");
316 }
317 }
318 ✗ messageCloseWarning(OMC_LOG_STDOUT);
319 ✗ throwStreamPrint(NULL,"see last warning");
320 }
321
322 1 static double getFlagReal(enum _FLAG flag, double res)
323 {
324 1 const char *flagStr = omc_flagValue[flag];
325 char *endptr;
326
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if (flagStr==NULL || *flagStr=='\0') {
327 return res;
328 }
329 ✗ res = om_strtod(flagStr, &endptr);
330 ✗ if (*endptr) {
331 ✗ throwStreamPrint(NULL, "Simulation flag %s expects a real number, got: %s", FLAG_NAME[flag], flagStr);
332 }
333 return res;
334 }
335
336 /**
337 * @brief Mark variables that should be filterd from result file.
338 *
339 * Read the variable filter and mark variables that should not be part of the
340 * result file. This phase is skipped for interactive simulations
341 *
342 * @param modelData Model data containing filter property.
343 * @param variableFilter Regex to filter variables.
344 * @param resultFormatHasCheapAliasesAndParameters
345 */
346 1 void initializeOutputFilter(MODEL_DATA *modelData, const char *variableFilter, int resultFormatHasCheapAliasesAndParameters)
347 {
348 #ifndef _MSC_VER
349 regex_t myregex;
350 int flags = REG_EXTENDED;
351 int rc;
352
4/8
✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 time.
✓ Branch 9 taken 1 time.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
2 string tmp = ("^(" + string(variableFilter) + ")$");
353 const char *filter = tmp.c_str(); // C++ strings are horrible to work with...
354
355
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 if(0 == strcmp(filter, ".*")) { // This matches all variables, so we don't need to do anything
356 return;
357 }
358
359
1/1
✓ Branch 1 taken 1 time.
1 rc = regcomp(&myregex, filter, flags);
360
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(rc) {
361 ✗ char err_buf[2048] = {0};
362 ✗ regerror(rc, &myregex, err_buf, 2048);
363 ✗ std::cerr << "Failed to compile regular expression: " << filter << " with error: " << err_buf << ". Defaulting to outputting all variables." << std::endl;
364 return;
365 }
366
367
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 time.
3 for(mmc_sint_t i=0; i<modelData->nVariablesRealArray; i++) {
368
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if(!modelData->realVarsData[i].filterOutput) {
369
1/1
✓ Branch 1 taken 2 times.
2 modelData->realVarsData[i].filterOutput = regexec(&myregex, modelData->realVarsData[i].info.name, 0, NULL, 0) != 0;
370 }
371 }
372
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 for(mmc_sint_t i=0; i<modelData->nAliasRealArray; i++) {
373 ✗ if(!modelData->realAlias[i].filterOutput) {
374 ✗ if(modelData->realAlias[i].aliasType == ALIAS_TYPE_VARIABLE) {
375 ✗ modelData->realAlias[i].filterOutput = regexec(&myregex, modelData->realAlias[i].info.name, 0, NULL, 0) != 0;
376 ✗ if (0 == modelData->realAlias[i].filterOutput) {
377 ✗ modelData->realVarsData[modelData->realAlias[i].nameID].filterOutput = 0;
378 }
379 ✗ } else if(modelData->realAlias[i].aliasType == ALIAS_TYPE_PARAMETER) {
380 ✗ modelData->realAlias[i].filterOutput = regexec(&myregex, modelData->realAlias[i].info.name, 0, NULL, 0) != 0;
381 ✗ if (0 == modelData->realAlias[i].filterOutput && resultFormatHasCheapAliasesAndParameters) {
382 ✗ modelData->realParameterData[modelData->realAlias[i].nameID].filterOutput = 0;
383 }
384 }
385 }
386 }
387
388
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
2 for (mmc_sint_t i=0; i<modelData->nVariablesIntegerArray; i++) {
389
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 if(!modelData->integerVarsData[i].filterOutput) {
390
1/1
✓ Branch 1 taken 1 time.
1 modelData->integerVarsData[i].filterOutput = regexec(&myregex, modelData->integerVarsData[i].info.name, 0, NULL, 0) != 0;
391 }
392 }
393
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 for (mmc_sint_t i=0; i<modelData->nAliasIntegerArray; i++) {
394 ✗ if(!modelData->integerAlias[i].filterOutput) {
395 ✗ if(modelData->integerAlias[i].aliasType == ALIAS_TYPE_VARIABLE) {
396 ✗ modelData->integerAlias[i].filterOutput = regexec(&myregex, modelData->integerAlias[i].info.name, 0, NULL, 0) != 0;
397 ✗ if (0 == modelData->integerAlias[i].filterOutput) {
398 ✗ modelData->integerVarsData[modelData->integerAlias[i].nameID].filterOutput = 0;
399 }
400 ✗ } else if(modelData->integerAlias[i].aliasType == ALIAS_TYPE_PARAMETER) {
401 ✗ modelData->integerAlias[i].filterOutput = regexec(&myregex, modelData->integerAlias[i].info.name, 0, NULL, 0) != 0;
402 ✗ if (0 == modelData->integerAlias[i].filterOutput && resultFormatHasCheapAliasesAndParameters) {
403 ✗ modelData->integerParameterData[modelData->integerAlias[i].nameID].filterOutput = 0;
404 }
405 }
406 }
407 }
408
409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 for (mmc_sint_t i=0; i<modelData->nVariablesBooleanArray; i++) {
410 ✗ if(!modelData->booleanVarsData[i].filterOutput) {
411 ✗ modelData->booleanVarsData[i].filterOutput = regexec(&myregex, modelData->booleanVarsData[i].info.name, 0, NULL, 0) != 0;
412 }
413 }
414
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 for (mmc_sint_t i=0; i<modelData->nAliasBooleanArray; i++) {
415 ✗ if(!modelData->booleanAlias[i].filterOutput) {
416 ✗ if(modelData->booleanAlias[i].aliasType == ALIAS_TYPE_VARIABLE) {
417 ✗ modelData->booleanAlias[i].filterOutput = regexec(&myregex, modelData->booleanAlias[i].info.name, 0, NULL, 0) != 0;
418 ✗ if (0 == modelData->booleanAlias[i].filterOutput) {
419 ✗ modelData->booleanVarsData[modelData->booleanAlias[i].nameID].filterOutput = 0;
420 }
421 ✗ } else if(modelData->booleanAlias[i].aliasType == ALIAS_TYPE_PARAMETER) {
422 ✗ modelData->booleanAlias[i].filterOutput = regexec(&myregex, modelData->booleanAlias[i].info.name, 0, NULL, 0) != 0;
423 ✗ if (0 == modelData->booleanAlias[i].filterOutput && resultFormatHasCheapAliasesAndParameters) {
424 ✗ modelData->booleanParameterData[modelData->booleanAlias[i].nameID].filterOutput = 0;
425 }
426 }
427 }
428 }
429
430
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 for (mmc_sint_t i=0; i<modelData->nVariablesStringArray; i++) {
431 ✗ if(!modelData->stringVarsData[i].filterOutput) {
432 ✗ modelData->stringVarsData[i].filterOutput = regexec(&myregex, modelData->stringVarsData[i].info.name, 0, NULL, 0) != 0;
433 }
434 }
435
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 for (mmc_sint_t i=0; i<modelData->nAliasStringArray; i++) {
436 ✗ if(!modelData->stringAlias[i].filterOutput) {
437 ✗ if(modelData->stringAlias[i].aliasType == ALIAS_TYPE_VARIABLE) {
438 ✗ modelData->stringAlias[i].filterOutput = regexec(&myregex, modelData->stringAlias[i].info.name, 0, NULL, 0) != 0;
439 ✗ if (0 == modelData->stringAlias[i].filterOutput) {
440 ✗ modelData->stringVarsData[modelData->stringAlias[i].nameID].filterOutput = 0;
441 }
442 ✗ } else if(modelData->stringAlias[i].aliasType == ALIAS_TYPE_PARAMETER) {
443 ✗ modelData->stringAlias[i].filterOutput = regexec(&myregex, modelData->stringAlias[i].info.name, 0, NULL, 0) != 0;
444 ✗ if (0 == modelData->stringAlias[i].filterOutput && resultFormatHasCheapAliasesAndParameters) {
445 ✗ modelData->stringParameterData[modelData->stringAlias[i].nameID].filterOutput = 0;
446 }
447 }
448 }
449 }
450
1/1
✓ Branch 1 taken 1 time.
1 regfree(&myregex);
451 #endif
452 return;
453 }
454
455 /**
456 * Starts a non-interactive simulation
457 */
458 1 int startNonInteractiveSimulation(int argc, char**argv, DATA* data, threadData_t *threadData)
459 {
460 int retVal = -1;
461
462 /* linear model option is set : <-l lintime> */
463 1 int create_linearmodel = omc_flag[FLAG_L];
464 1 data->modelData->create_linearmodel = create_linearmodel;
465 1 const char* lintime = omc_flagValue[FLAG_L];
466
467 /* activated measure time option with OMC_LOG_STATS */
468 1 int measure_time_flag_previous = measure_time_flag;
469
2/6
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1 if (!measure_time_flag && (OMC_ACTIVE_STREAM(OMC_LOG_STATS) || omc_flag[FLAG_CPU]))
470 {
471 1 measure_time_flag = 1;
472 }
473 1 errno = 0;
474
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if (omc_flag[FLAG_ALARM]) {
475 char *endptr;
476 ✗ mmc_sint_t alarmVal = strtol(omc_flagValue[FLAG_ALARM],&endptr,10);
477 ✗ if (errno || *endptr != 0) {
478 ✗ throwStreamPrint(threadData, "-alarm takes an integer argument (got '%s')", omc_flagValue[FLAG_ALARM]);
479 }
480 ✗ alarm(alarmVal);
481 }
482
483 /* calc numStep */
484 1 data->simulationInfo->numSteps = static_cast<modelica_integer>(round((data->simulationInfo->stopTime - data->simulationInfo->startTime)/data->simulationInfo->stepSize));
485 1 infoStreamPrint(OMC_LOG_SOLVER, 0, "numberOfIntervals = %ld", (long) data->simulationInfo->numSteps);
486
487 { /* Setup the clock */
488 enum omc_rt_clock_t clock = OMC_CLOCK_REALTIME;
489 const char *clockName;
490
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if((clockName = omc_flagValue[FLAG_CLOCK]) != NULL) {
491 ✗ if(0 == strcmp(clockName, "CPU")) {
492 clock = OMC_CLOCK_CPUTIME;
493 ✗ } else if(0 == strcmp(clockName, "RT")) {
494 clock = OMC_CLOCK_REALTIME;
495 ✗ } else if(0 == strcmp(clockName, "CYC")) {
496 clock = OMC_CPU_CYCLES;
497 } else {
498 ✗ warningStreamPrint(OMC_LOG_STDOUT, 0, "[unknown clock-type] got %s, expected CPU|RT|CYC. Defaulting to RT.", clockName);
499 }
500 }
501
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 if(rt_set_clock(clock)) {
502 ✗ warningStreamPrint(OMC_LOG_STDOUT, 0, "Chosen clock-type: %s not available for the current platform. Defaulting to real-time.", clockName);
503 }
504 }
505
506
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 if(measure_time_flag) {
507 1 rt_tick(SIM_TIMER_INFO_XML);
508 1 modelInfoInit(&data->modelData->modelDataXml);
509 1 rt_accumulate(SIM_TIMER_INFO_XML);
510 //std::cerr << "ModelData with " << data->modelData->modelDataXml.nFunctions << " functions and " << data->modelData->modelDataXml.nEquations << " equations and " << data->modelData->modelDataXml.nProfileBlocks << " profileBlocks\n" << std::endl;
511 1 rt_init(SIM_TIMER_FIRST_FUNCTION + data->modelData->modelDataXml.nFunctions + data->modelData->modelDataXml.nEquations + data->modelData->modelDataXml.nProfileBlocks + 4 /* sentinel */);
512 1 rt_measure_overhead(SIM_TIMER_TOTAL);
513 1 rt_clear(SIM_TIMER_TOTAL);
514 1 rt_tick(SIM_TIMER_TOTAL);
515 1 rt_clear(SIM_TIMER_PREINIT);
516 1 rt_tick(SIM_TIMER_PREINIT);
517 1 rt_clear(SIM_TIMER_OUTPUT);
518 1 rt_clear(SIM_TIMER_EVENT);
519 1 rt_clear(SIM_TIMER_INIT);
520 }
521
522
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(create_linearmodel)
523 {
524 ✗ if(lintime == NULL) {
525 ✗ data->simulationInfo->stopTime = data->simulationInfo->startTime;
526 } else {
527 ✗ data->simulationInfo->stopTime = atof(lintime);
528 }
529 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "Linearization will be performed at point of time: %f", data->simulationInfo->stopTime);
530 }
531
532 /* set delta x for linearization */
533
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_DELTA_X_LINEARIZE]) {
534 ✗ numericalDifferentiationDeltaXlinearize = atof(omc_flagValue[FLAG_DELTA_X_LINEARIZE]);
535 ✗ infoStreamPrint(OMC_LOG_SOLVER, 0, "Set delta x for numerical differentiation of the linearization to %f", numericalDifferentiationDeltaXlinearize);
536 }else{
537 1 numericalDifferentiationDeltaXlinearize = sqrt(DBL_EPSILON*2e1);
538 }
539
540 /* set delta x for integration methods dassl, ida */
541
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_DELTA_X_SOLVER]) {
542 ✗ numericalDifferentiationDeltaXsolver = atof(omc_flagValue[FLAG_DELTA_X_SOLVER]);
543 ✗ infoStreamPrint(OMC_LOG_SOLVER, 0, "Set delta x for numerical differentiation of the integrator to %f", numericalDifferentiationDeltaXsolver);
544 }else{
545 1 numericalDifferentiationDeltaXsolver = sqrt(DBL_EPSILON);
546 }
547
548
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_S]) {
549 ✗ if (omc_flagValue[FLAG_S]) {
550 ✗ omc_rc_release((void*) data->simulationInfo->solverMethod);
551 ✗ data->simulationInfo->solverMethod = GC_strdup(omc_flagValue[FLAG_S]);
552 ✗ infoStreamPrint(OMC_LOG_SOLVER, 0, "overwrite solver method: %s [from command line]", data->simulationInfo->solverMethod);
553 }
554 }
555 /* if the model is compiled in daeMode then we have to use ida solver */
556
3/8
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 time.
1 if (compiledInDAEMode && std::string("ida") != data->simulationInfo->solverMethod) {
557 ✗ omc_rc_release((void*) data->simulationInfo->solverMethod);
558 ✗ data->simulationInfo->solverMethod = GC_strdup(std::string("ida").c_str());
559 ✗ infoStreamPrint(OMC_LOG_SIMULATION, 0, "overwrite solver method: %s [DAEmode works only with IDA solver]", data->simulationInfo->solverMethod);
560 }
561
562 // Create a result file
563
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 const char *result_file = omc_flagValue[FLAG_R];
564 string result_file_cstr;
565
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if (result_file) {
566 ✗ data->modelData->resultFileName = GC_strdup(result_file);
567
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 } else if (omc_flag[FLAG_OUTPUT_PATH]) { /* read the output path from the command line (if any) */
568 ✗ if (0 > GC_asprintf(&result_file, "%s/%s_res.%s", omc_flagValue[FLAG_OUTPUT_PATH], data->modelData->modelFilePrefix, data->simulationInfo->outputFormat)) {
569 ✗ throwStreamPrint(NULL, "simulation_runtime.c: Error: can not allocate memory.");
570 }
571 ✗ data->modelData->resultFileName = GC_strdup(result_file);
572 ✗ omc_rc_release((void*) result_file);
573 } else {
574
7/14
✓ Branch 1 taken 1 time.
✓ Branch 4 taken 1 time.
✓ Branch 7 taken 1 time.
✓ Branch 10 taken 1 time.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 time.
✗ Branch 15 not taken.
✓ Branch 16 taken 1 time.
✗ Branch 17 not taken.
✓ Branch 18 taken 1 time.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
2 result_file_cstr = string(data->modelData->modelFilePrefix) + string("_res.") + data->simulationInfo->outputFormat;
575
1/1
✓ Branch 1 taken 1 time.
1 data->modelData->resultFileName = GC_strdup(result_file_cstr.c_str());
576 }
577
578 1 data->modelData->resourcesDir = NULL;
579
580
1/3
✓ Branch 1 taken 1 time.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 string init_initMethod = "";
581
1/3
✓ Branch 1 taken 1 time.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 string init_file = "";
582
1/3
✓ Branch 1 taken 1 time.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 string init_time_string = "";
583 double init_time = 0.0;
584
1/3
✓ Branch 1 taken 1 time.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 string outputVariablesAtEnd = "";
585 1 int cpuTime = omc_flag[FLAG_CPU];
586
587
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_IIM]) {
588 ✗ init_initMethod = omc_flagValue[FLAG_IIM];
589 }
590
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_IIF]) {
591 ✗ if (omc_flag[FLAG_INPUT_PATH]) {
592 const char *tmp_filename;
593
594 ✗ if (omc_file_exists(omc_flagValue[FLAG_IIF])) {
595 ✗ if (0 > GC_asprintf(&tmp_filename, "%s", omc_flagValue[FLAG_IIF] )) {
596 ✗ throwStreamPrint(NULL, "simulation_runtime.cpp: Error: can not allocate memory.");
597 }
598 }
599 else {
600 ✗ if (0 > GC_asprintf(&tmp_filename, "%s/%s", omc_flagValue[FLAG_INPUT_PATH], omc_flagValue[FLAG_IIF])) {
601 ✗ throwStreamPrint(NULL, "simulation_runtime.cpp: Error: can not allocate memory.");
602 }
603 }
604 ✗ init_file = tmp_filename;
605 }
606 else {
607 ✗ init_file = omc_flagValue[FLAG_IIF];
608 }
609 ✗ if (!omc_file_exists(init_file.c_str())) {
610 ✗ throwStreamPrint(NULL, "Initialization file \"%s\" doesn't exist.", init_file.c_str());
611 }
612 }
613
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_IIT]) {
614 ✗ init_time_string = omc_flagValue[FLAG_IIT];
615 init_time = atof(init_time_string.c_str());
616 }
617
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_ILS]) {
618 ✗ init_lambda_steps = atoi(omc_flagValue[FLAG_ILS]);
619 ✗ if(init_lambda_steps <= 0) {
620 ✗ init_lambda_steps = 0;
621 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "Number of lambda steps set to 0. Homotopy is disabled.");
622 }
623 else {
624 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "Number of lambda steps for homotopy approach changed to %d", init_lambda_steps);
625 }
626 }
627
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_MAX_BISECTION_ITERATIONS]) {
628 ✗ maxBisectionIterations = atoi(omc_flagValue[FLAG_MAX_BISECTION_ITERATIONS]);
629 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "Maximum number of bisection iterations changed to %d", maxBisectionIterations);
630 }
631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_MAX_EVENT_ITERATIONS]) {
632 ✗ maxEventIterations = atoi(omc_flagValue[FLAG_MAX_EVENT_ITERATIONS]);
633 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "Maximum number of event iterations changed to %d", maxEventIterations);
634 }
635
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_OUTPUT]) {
636 ✗ outputVariablesAtEnd = omc_flagValue[FLAG_OUTPUT];
637 }
638
639 /* Check if logging should be enabled */
640
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if ((data->simulationInfo->useLoggingTime == 1) && (data->simulationInfo->startTime >= data->simulationInfo->loggingTimeRecord[0])) {
641 ✗ reactivateLogging();
642 }
643
644
4/10
✓ Branch 1 taken 1 time.
✓ Branch 4 taken 1 time.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
3 retVal = callSolver(data, threadData, init_initMethod, init_file, init_time, outputVariablesAtEnd, cpuTime, argv[0]);
645
646 /* Check if logging should be disabled */
647
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if (data->simulationInfo->useLoggingTime == 1) {
648 ✗ deactivateLogging();
649 }
650
651
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if (omc_flag[FLAG_ALARM]) {
652 ✗ alarm(0);
653 }
654
655
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if (omc_flag[FLAG_DATA_RECONCILE])
656 {
657 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "DataReconciliation Starting!");
658 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "%s", data->modelData->modelName);
659 ✗ retVal = dataReconciliation(data, threadData, retVal);
660 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "DataReconciliation Completed!");
661 }
662
663
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if (omc_flag[FLAG_DATA_RECONCILE_BOUNDARY])
664 {
665 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "Reconcile Boundary Conditions Starting!");
666 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "%s", data->modelData->modelName);
667 ✗ retVal = boundaryConditions(data, threadData, retVal);
668 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "Reconcile Boundary Conditions Completed!");
669 }
670
671
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if (omc_flag[FLAG_DATA_RECONCILE_STATE])
672 {
673 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "Reconcile State Estimation Starting!");
674 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "%s", data->modelData->modelName);
675 ✗ retVal = dataReconciliation(data, threadData, retVal);
676 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "Reconcile State Estimation Completed!");
677 }
678
679
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(0 == retVal && create_linearmodel) {
680 ✗ rt_tick(SIM_TIMER_JACOBIAN);
681 ✗ retVal = linearize(data, threadData);
682 ✗ rt_accumulate(SIM_TIMER_JACOBIAN);
683 }
684
685 /* Use the saved state of measure_time_flag.
686 * measure_time_flag is set to active when OMC_LOG_STATS is ON.
687 * So before doing the profiling reset the measure_time_flag to measure_time_flag_previous state.
688 */
689 1 measure_time_flag = measure_time_flag_previous;
690
1/3
✓ Branch 1 taken 1 time.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 string output_path = "";
691
2/4
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
1 if (0 == retVal && measure_time_flag) {
692 ✗ if (omc_flag[FLAG_OUTPUT_PATH]) { /* read the output path from the command line (if any) */
693 ✗ output_path = string(omc_flagValue[FLAG_INPUT_PATH]) + string("/");
694 }
695 ✗ const string jsonInfo = string(data->modelData->modelFilePrefix) + "_prof.json";
696 ✗ const string modelInfo = string(data->modelData->modelFilePrefix) + "_prof.xml";
697 ✗ const string plotFile = string(data->modelData->modelFilePrefix) + "_prof.plt";
698 ✗ rt_accumulate(SIM_TIMER_TOTAL);
699 ✗ const char* plotFormat = omc_flagValue[FLAG_MEASURETIMEPLOTFORMAT];
700 ✗ retVal = printModelInfo(data, threadData, output_path.c_str(), modelInfo.c_str(), plotFile.c_str(), plotFormat ? plotFormat : "svg",
701 ✗ data->simulationInfo->solverMethod, data->simulationInfo->outputFormat, data->modelData->resultFileName) && retVal;
702 ✗ retVal = printModelInfoJSON(data, threadData, output_path.c_str(), jsonInfo.c_str(), data->modelData->resultFileName) && retVal;
703 }
704
705 1 return retVal;
706 }
707
708 /*! \fn initializeResultData(DATA* simData, int cpuTime)
709 *
710 * \param [ref] [simData]
711 * \param [int] [cpuTime]
712 *
713 * This function initializes result object to emit data.
714 */
715 1 int initializeResultData(DATA* simData, threadData_t *threadData, int cpuTime)
716 {
717 int resultFormatHasCheapAliasesAndParameters = 0;
718 int retVal = 0;
719 1 mmc_sint_t maxSteps = 4 * simData->simulationInfo->numSteps;
720 1 free((void*) sim_result.filename);
721 1 sim_result.filename = omc_strdup(simData->modelData->resultFileName);
722 1 sim_result.numpoints = maxSteps;
723 1 sim_result.cpuTime = cpuTime;
724
2/4
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
1 if (sim_noemit || 0 == strcmp("empty", simData->simulationInfo->outputFormat)) {
725 /* Default is set to noemit */
726
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 } else if(0 == strcmp("csv", simData->simulationInfo->outputFormat)
727
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 || 0 == strcmp("mat", simData->simulationInfo->outputFormat)
728 ✗ || 0 == strcmp("plt", simData->simulationInfo->outputFormat)
729 ✗ || 0 == strcmp("arrow", simData->simulationInfo->outputFormat)) {
730 1 sim_result.init = rust_result_init;
731 1 sim_result.emit = rust_result_emit;
732 1 sim_result.writeParameterData = rust_result_writeParameterData;
733 1 sim_result.free = rust_result_free;
734 1 resultFormatHasCheapAliasesAndParameters = 1;
735 #if !defined(OMC_MINIMAL_RUNTIME)
736 ✗ } else if(0 == strcmp("ia", simData->simulationInfo->outputFormat)) {
737 ✗ sim_result.init = ia_init;
738 ✗ sim_result.emit = ia_emit;
739 //sim_result.writeParameterData = ia_writeParameterData;
740 ✗ sim_result.free = ia_free;
741 #endif
742 } else {
743 ✗ cerr << "Unknown output format: " << simData->simulationInfo->outputFormat << endl;
744 ✗ return 1;
745 }
746 1 initializeOutputFilter(simData->modelData, simData->simulationInfo->variableFilter, resultFormatHasCheapAliasesAndParameters);
747 1 sim_result.init(&sim_result, simData, threadData);
748 1 infoStreamPrint(OMC_LOG_SOLVER, 0, "Allocated simulation result data storage for method '%s' and file='%s'", (char*) simData->simulationInfo->outputFormat, sim_result.filename);
749 1 return 0;
750 }
751
752 /**
753 * Calls the solver which is selected in the parameter string "method"
754 * This function is used for interactive and non-interactive simulation
755 * Parameter method:
756 * "" & "dassl" calls a DASSL Solver
757 * "euler" calls an Euler solver
758 * "rungekutta" calls a fourth-order Runge-Kutta Solver
759 */
760 1 static int callSolver(DATA* simData, threadData_t *threadData, string init_initMethod, string init_file,
761 double init_time, string outputVariablesAtEnd, int cpuTime, const char *argv_0)
762 {
763 1 int retVal = -1;
764 mmc_sint_t i;
765
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 enum SOLVER_METHOD solverID = S_UNKNOWN;
766
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 const char* outVars = (outputVariablesAtEnd.size() == 0) ? NULL : outputVariablesAtEnd.c_str();
767
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 OMC_TRY_INTERNAL(mmc_jumper)
768
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 OMC_TRY_INTERNAL(globalJumpBuffer)
769
770
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 if (initializeResultData(simData, threadData, cpuTime)) {
771 ✗ return -1;
772 }
773 1 simData->real_time_sync.scaling = getFlagReal(FLAG_RT, 0.0);
774
775
1/2
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
2 if(std::string("") == simData->simulationInfo->solverMethod) {
776 #if defined(WITH_DASSL)
777 solverID = S_DASSL;
778 #else
779 solverID = S_RUNGEKUTTA;
780 #endif
781 } else {
782
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 time.
11 for(i=1; i<S_MAX; ++i) {
783
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 9 times.
20 if(std::string(SOLVER_METHOD_NAME[i]) == simData->simulationInfo->solverMethod) {
784 1 solverID = (enum SOLVER_METHOD) i;
785 }
786 }
787 }
788
789 /* Deprecation warnings */
790 1 deprecationWarningGBODE(solverID);
791
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 switch (solverID)
792 {
793 ✗ case S_SYM_SOLVER:
794 case S_SYM_SOLVER_SSC:
795 case S_QSS:
796 ✗ warningStreamPrint(OMC_LOG_STDOUT, 0, "Integration method '%s' is deprecated and will be removed in a future version of OpenModelica.",
797 SOLVER_METHOD_NAME[solverID]);
798 break;
799 default:
800 break;
801 }
802
803 /* if no states are present, then we can
804 * use euler method, since it does nothing.
805 */
806
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if ( (simData->modelData->nStates < 1 &&
807 ✗ solverID != S_OPTIMIZATION &&
808 ✗ solverID != S_SYM_SOLVER &&
809 ✗ !compiledInDAEMode) ||
810
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 (compiledInDAEMode && (simData->simulationInfo->daeModeData->nResidualVars +
811 ✗ simData->simulationInfo->daeModeData->nAlgebraicDAEVars < 1))
812 )
813 {
814 ✗ solverID = S_EULER;
815 ✗ infoStreamPrint(OMC_LOG_SOLVER, 0, "No states present, continuing without ODE solver.");
816 ✗ if (compiledInDAEMode)
817 {
818 ✗ simData->callback->functionDAE = evaluateDAEResiduals_wrapperEventUpdate;
819 ✗ simData->callback->function_ZeroCrossingsEquations = evaluateDAEResiduals_wrapperZeroCrossingsEquations;
820 }
821 }
822
823
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(S_UNKNOWN == solverID) {
824 ✗ warningStreamPrint(OMC_LOG_STDOUT, 0, "unrecognized option -s %s", (char*) simData->simulationInfo->solverMethod);
825 ✗ warningStreamPrint(OMC_LOG_STDOUT, 0, "current options are:");
826 ✗ for(i=1; i<S_MAX; ++i) {
827 ✗ warningStreamPrint(OMC_LOG_STDOUT, 0, "%-18s [%s]", SOLVER_METHOD_NAME[i], SOLVER_METHOD_DESC[i]);
828 }
829 ✗ throwStreamPrint(threadData,"see last warning");
830 retVal = 1;
831 } else {
832 1 infoStreamPrint(OMC_LOG_SOLVER, 0, "recognized solver: %s", SOLVER_METHOD_NAME[solverID]);
833 /* special solvers */
834 #ifdef _OMC_QSS_LIB
835 if(S_QSS == solverID) {
836 retVal = qss_main(argc, argv, simData->simulationInfo->startTime,
837 simData->simulationInfo->stopTime, simData->simulationInfo->stepSize,
838 simData->simulationInfo->numSteps, simData->simulationInfo->tolerance, 3);
839 } else /* standard solver interface */
840 #endif
841 1 retVal = solver_main(simData, threadData, init_initMethod.c_str(), init_file.c_str(), init_time, solverID, outVars, argv_0);
842 }
843
844 1 OMC_CATCH_INTERNAL(mmc_jumper)
845 1 OMC_CATCH_INTERNAL(globalJumpBuffer)
846
847 1 deinitializeResultData(simData, threadData);
848
849 1 return retVal;
850 }
851
852 /**
853 * @brief Set log activation from equationIndex and list from lv_system.
854 *
855 * Requires `nonlinsys[i].equationIndex` to be set already!
856 *
857 * @param data Data object
858 */
859 1 static void setLVSystems(DATA *data, threadData_t *threadData)
860 {
861 int i;
862 int N = 0; /* largest equationIndex */
863 modelica_boolean* isSystemActive = NULL;
864 const char* p;
865 char* endptr;
866
867 1 MIXED_SYSTEM_DATA *mixedsys = data->simulationInfo->mixedSystemData;
868 1 LINEAR_SYSTEM_DATA *linsys = data->simulationInfo->linearSystemData;
869 1 NONLINEAR_SYSTEM_DATA *nonlinsys = data->simulationInfo->nonlinearSystemData;
870
871
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if (omc_flag[FLAG_LV_SYSTEM]) {
872 /* get largest equationIndex */
873 ✗ for (i = 0; i < data->modelData->nMixedSystems; ++i)
874 ✗ if (mixedsys[i].equationIndex > N)
875 ✗ N = mixedsys[i].equationIndex;
876 ✗ for (i = 0; i < data->modelData->nLinearSystems; ++i)
877 ✗ if (linsys[i].equationIndex > N)
878 ✗ N = linsys[i].equationIndex;
879 ✗ for (i = 0; i < data->modelData->nNonLinearSystems; ++i)
880 ✗ if (nonlinsys[i].equationIndex > N)
881 ✗ N = nonlinsys[i].equationIndex;
882
883 /* initialize isSystemActive with FALSE */
884 ✗ isSystemActive = (modelica_boolean*) calloc(N+1, sizeof(modelica_boolean));
885 ✗ assertStreamPrint(threadData, NULL != isSystemActive, "setLVSystems: Out of memory.");
886
887 /* set isSystemActive[i] to true for all i in lv_system */
888 ✗ p = omc_flagValue[FLAG_LV_SYSTEM];
889 do {
890 ✗ errno = 0;
891 ✗ i = strtol(p, &endptr, 10);
892 ✗ if (errno == ERANGE) {
893 ✗ throwStreamPrint(threadData,
894 "setLVSystems: %s takes equation indices (got '%s')",
895 endptr, omc_flagValue[FLAG_LV_SYSTEM]);
896 }
897 ✗ if (i > N) {
898 ✗ throwStreamPrint(threadData,
899 "setLVSystems: %d is not a valid equation index", i);
900 }
901 ✗ isSystemActive[i] = TRUE;
902 ✗ p = endptr;
903 ✗ } while(*(p++) == ',');
904
905 /* activate corresponding system */
906 ✗ for (i = 0; i < data->modelData->nMixedSystems; ++i) {
907 ✗ mixedsys[i].logActive = isSystemActive[mixedsys[i].equationIndex];
908 ✗ isSystemActive[mixedsys[i].equationIndex] = FALSE;
909 }
910 ✗ for (i = 0; i < data->modelData->nLinearSystems; ++i) {
911 ✗ linsys[i].logActive = isSystemActive[linsys[i].equationIndex];
912 ✗ isSystemActive[linsys[i].equationIndex] = FALSE;
913 }
914 ✗ for (i = 0; i < data->modelData->nNonLinearSystems; ++i) {
915 ✗ nonlinsys[i].logActive = isSystemActive[nonlinsys[i].equationIndex];
916 ✗ isSystemActive[nonlinsys[i].equationIndex] = FALSE;
917 }
918
919 ✗ for (i = 0; i <= N; ++i){
920 ✗ if (isSystemActive[i]) {
921 ✗ throwStreamPrint(threadData,
922 "setLVSystems: %d is not a valid equation index.", i);
923 }
924 }
925 /* done */
926 ✗ free(isSystemActive);
927 } else {
928 /* if no list is given then all systems are active */
929
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 for (i = 0; i < data->modelData->nMixedSystems; ++i)
930 ✗ mixedsys[i].logActive = TRUE;
931
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 for (i = 0; i < data->modelData->nLinearSystems; ++i)
932 ✗ linsys[i].logActive = TRUE;
933
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 for (i = 0; i < data->modelData->nNonLinearSystems; ++i)
934 ✗ nonlinsys[i].logActive = TRUE;
935 }
936 1 }
937
938 /**
939 * Initialization is the same for interactive or non-interactive simulation
940 */
941 1 int initRuntimeAndSimulation(int argc, char**argv, DATA *data, threadData_t *threadData)
942 {
943 int i;
944 1 initDumpSystem();
945
946 1 int checkArgumentsRes = checkCommandLineArguments(argc, argv);
947
948 #ifndef NO_INTERACTIVE_DEPENDENCY
949
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_PORT]) {
950 ✗ std::istringstream stream(omc_flagValue[FLAG_PORT]);
951 int port;
952 ✗ stream >> port;
953 ✗ sim_communication_port_open = 1;
954 ✗ sim_communication_port_open &= sim_communication_port.create();
955 ✗ sim_communication_port_open &= sim_communication_port.connect("127.0.0.1", port);
956 ✗ }
957 #endif
958
959 1 int logFormatResult = setLogFormat(argc, argv);
960
961 #ifndef NO_INTERACTIVE_DEPENDENCY
962
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if (isXMLTCP && !sim_communication_port_open) {
963 ✗ errorStreamPrint(OMC_LOG_STDOUT, 0, "xmltcp log format requires a TCP-port to be passed (and successfully open)");
964 ✗ EXIT(1);
965 }
966 #endif
967
968
3/6
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 time.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
1 if(logFormatResult || helpFlagSet(argc, argv) || checkArgumentsRes)
969 {
970 ✗ infoStreamPrint(OMC_LOG_STDOUT, 1, "usage: %s", argv[0]);
971
972 ✗ for(i=1; i<FLAG_MAX; ++i)
973 {
974 ✗ if(FLAG_TYPE[i] == FLAG_TYPE_FLAG) {
975 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "<-%s>\n %s", FLAG_NAME[i], FLAG_DESC[i]);
976 ✗ } else if(FLAG_TYPE[i] == FLAG_TYPE_OPTION) {
977 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "<-%s=value> or <-%s value>\n %s", FLAG_NAME[i], FLAG_NAME[i], FLAG_DESC[i]);
978 } else {
979 ✗ warningStreamPrint(OMC_LOG_STDOUT, 0, "[unknown flag-type] <-%s>", FLAG_NAME[i]);
980 }
981 }
982
983 ✗ messageClose(OMC_LOG_STDOUT);
984 ✗ EXIT(1);
985 }
986
987
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_HELP])
988 {
989 ✗ std::string option = omc_flagValue[FLAG_HELP];
990 ✗ for(i=1; i<FLAG_MAX; ++i)
991 {
992 ✗ if(option == std::string(FLAG_NAME[i]))
993 {
994 int j;
995
996 ✗ if(FLAG_TYPE[i] == FLAG_TYPE_FLAG)
997 ✗ infoStreamPrint(OMC_LOG_STDOUT, 1, "detailed flag-description for: <-%s>\n%s", FLAG_NAME[i], FLAG_DETAILED_DESC[i]);
998 ✗ else if(FLAG_TYPE[i] == FLAG_TYPE_OPTION)
999 ✗ infoStreamPrint(OMC_LOG_STDOUT, 1, "detailed flag-description for: <-%s=value> or <-%s value>\n%s", FLAG_NAME[i], FLAG_NAME[i], FLAG_DETAILED_DESC[i]);
1000 else
1001 ✗ warningStreamPrint(OMC_LOG_STDOUT, 1, "[unknown flag-type] <-%s>", FLAG_NAME[i]);
1002
1003 /* detailed information for some flags */
1004 ✗ switch(i)
1005 {
1006 case FLAG_IDA_LS:
1007 ✗ for(j=1; j<IDA_LS_MAX; ++j) {
1008 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "%-18s [%s]", IDA_LS_METHOD_NAME[j], IDA_LS_METHOD_DESC[j]);
1009 }
1010 break;
1011
1012 case FLAG_IIM:
1013 ✗ for(j=1; j<IIM_MAX; ++j) {
1014 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "%-18s [%s]", INIT_METHOD_NAME[j], INIT_METHOD_DESC[j]);
1015 }
1016 break;
1017
1018 case FLAG_JACOBIAN:
1019 ✗ for(j=1; j<JAC_MAX; ++j) {
1020 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "%-18s [%s]", JACOBIAN_METHOD_NAME[j], JACOBIAN_METHOD_DESC[j]);
1021 }
1022 break;
1023
1024 case FLAG_LS:
1025 ✗ for(j=1; j<LS_MAX; ++j) {
1026 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "%-18s [%s]", LS_NAME[j], LS_DESC[j]);
1027 }
1028 break;
1029
1030 case FLAG_LSS:
1031 ✗ for(j=1; j<LSS_MAX; ++j) {
1032 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "%-18s [%s]", LSS_NAME[j], LSS_DESC[j]);
1033 }
1034 break;
1035
1036 ✗ case FLAG_LV:
1037 ✗ for(j=firstOMCErrorStream; j<OMC_SIM_LOG_MAX; ++j) {
1038 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "%-18s [%s]", OMC_LOG_STREAM_NAME[j], OMC_LOG_STREAM_DESC[j]);
1039 }
1040 break;
1041
1042 case FLAG_NEWTON_STRATEGY:
1043 ✗ for(j=1; j<NEWTON_MAX; ++j) {
1044 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "%-18s [%s]", NEWTONSTRATEGY_NAME[j], NEWTONSTRATEGY_DESC[j]);
1045 }
1046 break;
1047
1048 case FLAG_NLS:
1049 ✗ for(j=1; j<NLS_MAX; ++j) {
1050 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "%-18s [%s]", NLS_NAME[j], NLS_DESC[j]);
1051 }
1052 break;
1053
1054 case FLAG_NLS_LS:
1055 ✗ for(j=1; j<NLS_LS_MAX; ++j) {
1056 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "%-18s [%s]", NLS_LS_METHOD_NAME[j], NLS_LS_METHOD_DESC[j]);
1057 }
1058 break;
1059
1060 case FLAG_S:
1061 ✗ for(j=1; j<S_MAX; ++j) {
1062 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "%-18s [%s]", SOLVER_METHOD_NAME[j], SOLVER_METHOD_DESC[j]);
1063 }
1064 break;
1065 }
1066 ✗ if(FLAG_TYPE[i] == FLAG_TYPE_FLAG || FLAG_TYPE[i] == FLAG_TYPE_OPTION) {
1067 ✗ messageClose(OMC_LOG_STDOUT);
1068 } else {
1069 ✗ messageCloseWarning(OMC_LOG_STDOUT);
1070 }
1071
1072 ✗ EXIT(0);
1073 }
1074 }
1075
1076 ✗ warningStreamPrint(OMC_LOG_STDOUT, 0, "invalid command line option: -help=%s", option.c_str());
1077 ✗ warningStreamPrint(OMC_LOG_STDOUT, 0, "use %s -help for a list of all command-line flags", argv[0]);
1078 ✗ EXIT(1);
1079 }
1080
1081 1 setGlobalVerboseLevel(argc, argv);
1082 1 setGlobalLoggingTime(data->simulationInfo);
1083
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_LV_MAX_WARN]) {
1084 ✗ data->simulationInfo->maxWarnDisplays = atoi(omc_flagValue[FLAG_LV_MAX_WARN]);
1085 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "Display limit for repeating warnings changed to %lu.", data->simulationInfo->maxWarnDisplays);
1086 } else {
1087 1 data->simulationInfo->maxWarnDisplays = DEFAULT_FLAG_LV_MAX_WARN;
1088 }
1089
1090 1 rt_tick(SIM_TIMER_INIT_XML);
1091 1 read_input_xml(data->modelData, data->simulationInfo, threadData);
1092 /* derived sizes of resizable arrays from the start values, then the sizes
1093 * again with them (read_input_xml computed them already without) */
1094
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if (data->callback->updateStructuralParameters) {
1095 ✗ data->callback->updateStructuralParameters(data, threadData);
1096 ✗ calculateAllScalarLength(data->modelData);
1097 }
1098 1 rt_accumulate(SIM_TIMER_INIT_XML);
1099 1 data->simulationInfo->minStepSize = 4.0 * DBL_EPSILON * fmax(fabs(data->simulationInfo->startTime),fabs(data->simulationInfo->stopTime));
1100
1101 1 initializeDataStruc(data, threadData);
1102 if(!data)
1103 {
1104 std::cerr << "Error: Could not initialize the global data structure file" << std::endl;
1105 EXIT(1);
1106 }
1107
1108 1 readFlag((int*)&data->simulationInfo->nlsMethod, NLS_MAX, omc_flagValue[FLAG_NLS], "-nls", NLS_NAME, NLS_DESC);
1109 1 readFlag((int*)&data->simulationInfo-> lsMethod, LS_MAX, omc_flagValue[FLAG_LS ], "-ls", LS_NAME, LS_DESC);
1110 1 readFlag((int*)&data->simulationInfo->lssMethod, LSS_MAX, omc_flagValue[FLAG_LSS], "-lss", LSS_NAME, LSS_DESC);
1111 1 readFlag((int*)&homBacktraceStrategy, HOM_BACK_STRAT_MAX, omc_flagValue[FLAG_HOMOTOPY_BACKTRACE_STRATEGY], "-homBacktraceStrategy", HOM_BACK_STRAT_NAME, HOM_BACK_STRAT_DESC);
1112 1 readFlag((int*)&data->simulationInfo->newtonStrategy, NEWTON_MAX, omc_flagValue[FLAG_NEWTON_STRATEGY], "-newton", NEWTONSTRATEGY_NAME, NEWTONSTRATEGY_DESC);
1113 1 data->simulationInfo->nlsCsvInfomation = omc_flag[FLAG_NLS_INFO];
1114 1 readFlag((int*)&data->simulationInfo->nlsLinearSolver, NLS_LS_MAX, omc_flagValue[FLAG_NLS_LS], "-nlsLS", NLS_LS_METHOD_NAME, NLS_LS_METHOD_DESC);
1115
1116
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_HOMOTOPY_ADAPT_BEND]) {
1117 ✗ homAdaptBend = atof(omc_flagValue[FLAG_HOMOTOPY_ADAPT_BEND]);
1118 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "homotopy parameter homAdaptBend changed to %f", homAdaptBend);
1119 }
1120
1121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_HOMOTOPY_H_EPS]) {
1122 ✗ homHEps = atof(omc_flagValue[FLAG_HOMOTOPY_H_EPS]);
1123 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "homotopy parameter homHEps changed to %f", homHEps);
1124 }
1125
1126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_HOMOTOPY_MAX_LAMBDA_STEPS]) {
1127 ✗ homMaxLambdaSteps = atoi(omc_flagValue[FLAG_HOMOTOPY_MAX_LAMBDA_STEPS]);
1128 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "homotopy parameter homMaxLambdaSteps changed to %d", homMaxLambdaSteps);
1129 }
1130
1131
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_HOMOTOPY_MAX_NEWTON_STEPS]) {
1132 ✗ homMaxNewtonSteps = atoi(omc_flagValue[FLAG_HOMOTOPY_MAX_NEWTON_STEPS]);
1133 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "homotopy parameter homMaxNewtonSteps changed to %d", homMaxNewtonSteps);
1134 }
1135
1136
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_HOMOTOPY_MAX_TRIES]) {
1137 ✗ homMaxTries = atoi(omc_flagValue[FLAG_HOMOTOPY_MAX_TRIES]);
1138 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "homotopy parameter homMaxTries changed to %d", homMaxTries);
1139 }
1140
1141
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_HOMOTOPY_TAU_DEC_FACTOR]) {
1142 ✗ homTauDecreasingFactor = atof(omc_flagValue[FLAG_HOMOTOPY_TAU_DEC_FACTOR]);
1143 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "homotopy parameter homTauDecreasingFactor changed to %f", homTauDecreasingFactor);
1144 }
1145
1146
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_HOMOTOPY_TAU_DEC_FACTOR_PRED]) {
1147 ✗ homTauDecreasingFactorPredictor = atof(omc_flagValue[FLAG_HOMOTOPY_TAU_DEC_FACTOR_PRED]);
1148 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "homotopy parameter homTauDecreasingFactorPredictor changed to %f", homTauDecreasingFactorPredictor);
1149 }
1150
1151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_HOMOTOPY_TAU_INC_FACTOR]) {
1152 ✗ homTauIncreasingFactor = atof(omc_flagValue[FLAG_HOMOTOPY_TAU_INC_FACTOR]);
1153 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "homotopy parameter homTauIncreasingFactor changed to %f", homTauIncreasingFactor);
1154 }
1155
1156
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_HOMOTOPY_TAU_INC_THRESHOLD]) {
1157 ✗ homTauIncreasingThreshold = atof(omc_flagValue[FLAG_HOMOTOPY_TAU_INC_THRESHOLD]);
1158 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "homotopy parameter homTauIncreasingThreshold changed to %f", homTauIncreasingThreshold);
1159 }
1160
1161
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_HOMOTOPY_TAU_MAX]) {
1162 ✗ homTauMax = atof(omc_flagValue[FLAG_HOMOTOPY_TAU_MAX]);
1163 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "homotopy parameter homTauMax changed to %f", homTauMax);
1164 }
1165
1166
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_HOMOTOPY_TAU_MIN]) {
1167 ✗ homTauMin = atof(omc_flagValue[FLAG_HOMOTOPY_TAU_MIN]);
1168 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "homotopy parameter homTauMin changed to %f", homTauMin);
1169 }
1170
1171
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_HOMOTOPY_TAU_START]) {
1172 ✗ homTauStart = atof(omc_flagValue[FLAG_HOMOTOPY_TAU_START]);
1173 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "homotopy parameter homTauStart changed to %f", homTauStart);
1174 }
1175
1176
2/4
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
1 if(omc_flag[FLAG_LSS_MAX_DENSITY] || omc_flag[FLAG_LSS_MIN_SIZE] ||
1177
2/4
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
1 omc_flag[FLAG_NLSS_MAX_DENSITY] || omc_flag[FLAG_NLSS_MIN_SIZE]) {
1178 ✗ warningStreamPrint(OMC_LOG_STDOUT, 0, "The flags -lssMaxDensity, -lssMinSize, -nlssMaxDensity and -nlssMinSize are\n"
1179 "deprecated and ignored: the compiler chooses dense or sparse per system.");
1180 }
1181
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_NEWTON_XTOL]) {
1182 ✗ newtonXTol = atof(omc_flagValue[FLAG_NEWTON_XTOL]);
1183 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "Tolerance for updating solution vector in Newton solver changed to %g", newtonXTol);
1184 }
1185
1186
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_NEWTON_FTOL]) {
1187 ✗ newtonFTol = atof(omc_flagValue[FLAG_NEWTON_FTOL]);
1188 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "Tolerance for accepting accuracy in Newton solver changed to %g", newtonFTol);
1189 }
1190
1191
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_NEWTON_MAX_STEPS]) {
1192 ✗ newtonMaxSteps = atoi(omc_flagValue[FLAG_NEWTON_MAX_STEPS]);
1193 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "Maximum number of Newton steps for GBODE changed to %d", newtonMaxSteps);
1194 }
1195
1196
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_NEWTON_MAX_STEP_FACTOR]) {
1197 ✗ maxStepFactor = atof(omc_flagValue[FLAG_NEWTON_MAX_STEP_FACTOR]);
1198 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "Maximum step size factor for a Newton step changed to %g", newtonFTol);
1199 }
1200
1201
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_NEWTON_JAC_UPDATES]) {
1202 int i = 0, j = 0;
1203 ✗ const char* p = omc_flagValue[FLAG_NEWTON_JAC_UPDATES];
1204 char* endptr;
1205 do {
1206 ✗ errno = 0;
1207 ✗ i = strtol(p, &endptr, 10);
1208 ✗ if (errno == ERANGE) {
1209 ✗ throwStreamPrint(threadData,
1210 "newtonJacUpdates: takes non-negative integers (got '%s')", omc_flagValue[FLAG_NEWTON_JAC_UPDATES]);
1211 }
1212 ✗ assertStreamPrint(threadData, i >= 0, "jac update must be non-negative, got %d", i);
1213 ✗ maxJacUpdate[j++] = i;
1214 ✗ p = endptr;
1215 ✗ } while(*(p++) == ',' && i < 4);
1216 }
1217
1218
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_STEADY_STATE_TOL]) {
1219 ✗ steadyStateTol = atof(omc_flagValue[FLAG_STEADY_STATE_TOL]);
1220 ✗ infoStreamPrint(OMC_LOG_STDOUT, 0, "Tolerance for steady state detection changed to %g", steadyStateTol);
1221 }
1222
1223
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_DAE_MODE]) {
1224 ✗ warningStreamPrint(OMC_LOG_STDOUT, 0, "The daeMode flag is *deprecated*, because it is not needed any more.\n"
1225 "If a model is compiled in \"DAEmode\" with compiler flag --daeMode, then it simulates automatically in DAE mode.");
1226 }
1227
1228 /* set log activation from equationIndex and lv_system */
1229 1 setLVSystems(data, threadData);
1230
1231 /* initialize static data of mixed/linear/non-linear system solvers */
1232 1 initializeMixedSystems(data, threadData);
1233 1 initializeLinearSystems(data, threadData);
1234 1 initializeNonlinearSystems(data, threadData);
1235
1236 1 sim_noemit = omc_flag[FLAG_NOEMIT];
1237
1238 #ifndef NO_INTERACTIVE_DEPENDENCY
1239
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(omc_flag[FLAG_PORT]) {
1240 ✗ if(0 != strcmp("ia", data->simulationInfo->outputFormat)) {
1241 ✗ communicateStatus("Starting", 0.0, data->simulationInfo->startTime, 0);
1242 }
1243 }
1244 #endif
1245 // ppriv - NO_INTERACTIVE_DEPENDENCY - for simpler debugging in Visual Studio
1246
1247 1 return 0;
1248 }
1249
1250 static DATA *SimulationRuntime_printStatus_data = NULL;
1251 ✗ void SimulationRuntime_printStatus(int sig)
1252 {
1253 ✗ DATA *data = SimulationRuntime_printStatus_data;
1254 printf("<status>\n");
1255 ✗ printf("<model>%s</model>\n", data->modelData->modelFilePrefix);
1256 printf("<phase>UNKNOWN</phase>\n");
1257 ✗ printf("<currentStepSize>%g</currentStepSize>\n", data->simulationInfo->stepSize);
1258 ✗ printf("<oldTime>%.12g</oldTime>\n", data->localData[1]->timeValue);
1259 ✗ printf("<oldTime2>%.12g</oldTime2>\n", data->localData[2]->timeValue);
1260 ✗ printf("<diffOldTime>%g</diffOldTime>\n", data->localData[1]->timeValue-data->localData[2]->timeValue);
1261 ✗ printf("<currentTime>%g</currentTime>\n", data->localData[0]->timeValue);
1262 ✗ printf("<diffCurrentTime>%g</diffCurrentTime>\n", data->localData[0]->timeValue-data->localData[1]->timeValue);
1263 printf("</status>\n");
1264 ✗ }
1265
1266 ✗ void communicateMsg(char id, unsigned int size, const char *data)
1267 {
1268 #ifndef NO_INTERACTIVE_DEPENDENCY
1269 ✗ if(sim_communication_port_open)
1270 {
1271 ✗ int msgSize = sizeof(char) + sizeof(unsigned int) + size;
1272 ✗ char* msg = new char[msgSize];
1273 memcpy(msg+0, &id, sizeof(char));
1274 ✗ memcpy(msg+sizeof(char), &size, sizeof(unsigned int));
1275 ✗ memcpy(msg+sizeof(char)+sizeof(unsigned int), data, size);
1276 ✗ sim_communication_port.sendBytes(msg, msgSize);
1277 ✗ delete[] msg;
1278 }
1279 #endif
1280 ✗ }
1281
1282 /**
1283 * @brief Parses the commandline (program options) and sets some
1284 * values. See initRuntimeAndSimulation for more info.
1285 * This allows generated simulation code to check-on/read options and flags before
1286 * it calls the main _main_SimulationRuntime function to do the simulation.
1287 *
1288 * @param argc
1289 * @param argv This gets overwritten on Windows!!
1290 * @param data
1291 * @param threadData
1292 * @return int Returns 0 on success. Returns 1 otherwise.
1293 *
1294 * Note: The function will overwrite argv to its wide character representation. Not sure
1295 * if this is a good idea. However, I am leaving it as it was for now.
1296 */
1297 1 int _main_initRuntimeAndSimulation(int argc, char**argv, DATA *data, threadData_t *threadData) {
1298
1299 // FIXME this looks like it's just a wrapper!
1300
1301
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 if (initRuntimeAndSimulation(argc, argv, data, threadData)) //initRuntimeAndSimulation returns 1 if an error occurs
1302 ✗ return 1;
1303
1304 return 0;
1305 }
1306
1307 /* \brief main function for simulator
1308 *
1309 * The arguments for the main function are:
1310 * -v verbose = debug
1311 * -vf = flags set verbosity flags
1312 * -f init_file.txt use input data from init file.
1313 * -r res.plt write result to file.
1314 */
1315
1316 1 int _main_SimulationRuntime(int argc, char**argv, DATA *data, threadData_t *threadData)
1317 {
1318 int retVal = -1;
1319
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 OMC_TRY_INTERNAL(globalJumpBuffer)
1320
1321 /* sighandler_t oldhandler = different type on all platforms... */
1322 #ifdef SIGUSR1
1323 1 SimulationRuntime_printStatus_data = data; /* Global, but at least we get something back; doesn't matter which simulation run */
1324 1 signal(SIGUSR1, SimulationRuntime_printStatus);
1325 #endif
1326
1327 1 retVal = startNonInteractiveSimulation(argc, argv, data, threadData);
1328
1329 1 freeMixedSystems(data, threadData); /* free mixed system data */
1330 1 freeLinearSystems(data, threadData); /* free linear system data */
1331 1 freeNonlinearSystems(data, threadData); /* free nonlinear system data */
1332
1333 1 data->callback->callExternalObjectDestructors(data, threadData);
1334 1 deInitializeDataStruc(data);
1335 1 fflush(NULL);
1336 1 OMC_CATCH_INTERNAL(globalJumpBuffer)
1337
1338 #ifndef NO_INTERACTIVE_DEPENDENCY
1339
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(sim_communication_port_open)
1340 {
1341 ✗ sim_communication_port.close();
1342 }
1343 #endif
1344
1345 1 return retVal;
1346 }
1347
1348 #ifndef OMC_HAVE_MOO
1349
1350 int _main_OptimizationRuntime(int argc, char**argv, DATA *data, threadData_t *threadData) {
1351 errorStreamPrint(OMC_LOG_STDOUT, 0, "MOO has not been built and can not be called: Set -DOM_OMC_ENABLE_MOO=ON to build MOO.");
1352 return -1;
1353 }
1354
1355 #endif // OMC_HAVE_MOO
1356
1357 #if !defined(OMC_MINIMAL_RUNTIME)
1358 ✗ const char* prettyPrintNanoSec(int64_t ns, int *v)
1359 {
1360 ✗ if (ns > 100000000000L || ns < -100000000000L) {
1361 ✗ *v = ns / 1000000000L;
1362 ✗ return "s";
1363 ✗ } if (ns > 100000000L || ns < -100000000L) {
1364 ✗ *v = ns / 1000000L;
1365 ✗ return "ms";
1366 ✗ } else if (ns > 100000L || ns < -100000L) {
1367 ✗ *v = ns / 1000L;
1368 ✗ return "µs";
1369 } else {
1370 ✗ *v = ns;
1371 ✗ return "ns";
1372 }
1373 }
1374 #endif
1375
1376 #ifndef NO_INTERACTIVE_DEPENDENCY
1377 static std::stringstream xmlTcpStream;
1378 static int numOpenTags=0;
1379
1380 ✗ static void printEscapedXMLTCP(std::stringstream *s, const char *msg)
1381 {
1382 ✗ while (*msg) {
1383 ✗ if (*msg == '&') {
1384 ✗ *s << "&amp;";
1385 ✗ } else if (*msg == '<') {
1386 ✗ *s << "&lt;";
1387 ✗ } else if (*msg == '>') {
1388 ✗ *s << "&gt;";
1389 ✗ } else if (*msg == '"') {
1390 ✗ *s << "&quot;";
1391 } else {
1392 ✗ *s << *msg;
1393 }
1394 ✗ msg++;
1395 }
1396 ✗ }
1397
1398 ✗ static inline void sendXMLTCPIfClosed()
1399 {
1400 ✗ if (numOpenTags==0) {
1401 ✗ sim_communication_port.send(xmlTcpStream.str());
1402 ✗ xmlTcpStream.str("");
1403 }
1404 ✗ }
1405
1406 ✗ static void messageXMLTCP(int type, int stream, FILE_INFO info, int indentNext, char *msg, int subline, const int *indexes)
1407 {
1408 ✗ numOpenTags++;
1409 ✗ xmlTcpStream << "<message stream=\"" << OMC_LOG_STREAM_NAME[stream] << "\" type=\"" << OMC_LOG_TYPE_DESC[type] << "\" text=\"";
1410 ✗ printEscapedXMLTCP(&xmlTcpStream, msg);
1411 ✗ if (indexes) {
1412 int i;
1413 ✗ xmlTcpStream << "\">\n";
1414 ✗ for (i=1; i<=*indexes; i++) {
1415 ✗ xmlTcpStream << "<used index=\"" << indexes[i] << "\" />\n";
1416 }
1417 ✗ if (!indentNext) {
1418 ✗ numOpenTags--;
1419 ✗ xmlTcpStream << "</message>\n";
1420 }
1421 } else {
1422 ✗ if (indentNext) {
1423 ✗ xmlTcpStream << "\">\n";
1424 } else {
1425 ✗ numOpenTags--;
1426 ✗ xmlTcpStream << "\" />\n";
1427 }
1428 }
1429 ✗ sendXMLTCPIfClosed();
1430 ✗ }
1431
1432 ✗ static void messageCloseXMLTCP(int stream)
1433 {
1434 ✗ if (OMC_ACTIVE_STREAM(stream)) {
1435 ✗ numOpenTags--;
1436 ✗ xmlTcpStream << "</message>\n";
1437 ✗ sendXMLTCPIfClosed();
1438 }
1439 ✗ }
1440
1441 ✗ static void messageCloseXMLTCPWarning(int stream)
1442 {
1443 ✗ if (OMC_ACTIVE_WARNING_STREAM(stream)) {
1444 ✗ numOpenTags--;
1445 ✗ xmlTcpStream << "</message>\n";
1446 ✗ sendXMLTCPIfClosed();
1447 }
1448 ✗ }
1449 #endif
1450
1451 ✗ static void printEscapedXML(const char *msg)
1452 {
1453 ✗ while (*msg) {
1454 ✗ if (*msg == '&') fputs("&amp;", stdout);
1455 ✗ else if (*msg == '<') fputs("&lt;", stdout);
1456 ✗ else if (*msg == '>') fputs("&gt;", stdout);
1457 ✗ else if (*msg == '"') fputs("&quot;", stdout);
1458 ✗ else fputc(*msg, stdout);
1459 ✗ msg++;
1460 }
1461 ✗ }
1462
1463 ✗ static void messageXML(int type, int stream, FILE_INFO info, int indentNext, char *msg, int subline, const int *indexes)
1464 {
1465 ✗ printf("<message stream=\"%s\" type=\"%s\" text=\"", OMC_LOG_STREAM_NAME[stream], OMC_LOG_TYPE_DESC[type]);
1466 ✗ printEscapedXML(msg);
1467 ✗ if (indexes) {
1468 int i;
1469 printf("\">\n");
1470 ✗ for (i=1; i<=*indexes; i++) {
1471 ✗ printf("<used index=\"%d\" />\n", indexes[i]);
1472 }
1473 ✗ if (!indentNext) {
1474 ✗ fputs("</message>\n",stdout);
1475 }
1476 } else {
1477 ✗ fputs(indentNext ? "\">\n" : "\" />\n", stdout);
1478 }
1479 ✗ fflush(stdout);
1480 ✗ }
1481
1482 ✗ static void messageCloseXML(int stream)
1483 {
1484 ✗ if (OMC_ACTIVE_STREAM(stream)) {
1485 ✗ fputs("</message>\n", stdout);
1486 ✗ fflush(stdout);
1487 }
1488 ✗ }
1489
1490 ✗ static void messageCloseXMLWarning(int stream)
1491 {
1492 ✗ if (OMC_ACTIVE_WARNING_STREAM(stream)) {
1493 ✗ fputs("</message>\n", stdout);
1494 ✗ fflush(stdout);
1495 }
1496 ✗ }
1497
1498 ✗ void setStreamPrintXML(int isXML)
1499 {
1500 ✗ if (isXML==1) {
1501 ✗ messageFunction = messageXML;
1502 ✗ messageClose = messageCloseXML;
1503 ✗ messageCloseWarning = messageCloseXMLWarning;
1504 #ifndef NO_INTERACTIVE_DEPENDENCY
1505 ✗ } else if (isXML==2) {
1506 ✗ messageFunction = messageXMLTCP;
1507 ✗ messageClose = messageCloseXMLTCP;
1508 ✗ messageCloseWarning = messageCloseXMLTCPWarning;
1509 ✗ isXMLTCP = 1;
1510 #endif
1511 } else {
1512 /* Already set... */
1513 }
1514 ✗ }
1515
1516 /**
1517 * @brief Send status via XMLTCP or TCP.
1518 *
1519 * @param phase Simulation phase.
1520 * @param completionPercent Percentage of simulation progress: 0.0 to 1.0
1521 * @param currentTime Current simulation time.
1522 * @param currentStepSize Current solver step size.
1523 */
1524 2 void communicateStatus(const char *phase, double completionPercent, double currentTime, double currentStepSize)
1525 {
1526 #ifndef NO_INTERACTIVE_DEPENDENCY
1527
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if (sim_communication_port_open && isXMLTCP) {
1528 ✗ std::stringstream s;
1529 ✗ s << "<status phase=\"" << phase << "\" currentStepSize=\"" << currentStepSize << "\" time=\"" << currentTime << "\" progress=\"" << (int)(completionPercent*10000) << "\" />" << std::endl;
1530 std::string str(s.str());
1531 ✗ sim_communication_port.send(str);
1532
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 } else if (sim_communication_port_open) {
1533 ✗ std::stringstream s;
1534 ✗ s << (int)(completionPercent*10000) << " " << phase << endl;
1535 std::string str(s.str());
1536 ✗ sim_communication_port.send(str);
1537 ✗ }
1538 #endif
1539 2 }
1540
1541 } // extern "C"
1542