Bug Summary

File:OMCompiler/SimulationRuntime/c/./simulation/simulation_runtime.cpp
Warning:line 243, column 3
Potential leak of memory pointed to by 'flags'

Annotated Source Code

[?] Use j/k keys for keyboard navigation

1/*
2 * This file is part of OpenModelica.
3 *
4 * Copyright (c) 1998-2010, Linköpings University,
5 * 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 THIS OSMC PUBLIC
11 * LICENSE (OSMC-PL). ANY USE, REPRODUCTION OR DISTRIBUTION OF
12 * THIS PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THE OSMC
13 * PUBLIC LICENSE.
14 *
15 * The OpenModelica software and the Open Source Modelica
16 * Consortium (OSMC) Public License (OSMC-PL) are obtained
17 * from Linköpings University, either from the above address,
18 * from the URL: http://www.ida.liu.se/projects/OpenModelica
19 * and in the OpenModelica distribution.
20 *
21 * This program is distributed WITHOUT ANY WARRANTY; without
22 * even the implied warranty of MERCHANTABILITY or FITNESS
23 * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
24 * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS
25 * OF OSMC-PL.
26 *
27 * See the full OSMC Public License conditions for more details.
28 *
29 */
30
31#include "util/omc_msvc.h"
32
33#include <setjmp.h>
34#include <string>
35#include <iostream>
36#include <sstream>
37#include <limits>
38#include <list>
39#include <cmath>
40#include <iomanip>
41#include <ctime>
42#include <cstdio>
43#include <cstring>
44#include <cassert>
45#include <signal.h>
46#include <fstream>
47#include <stdarg.h>
48
49#ifndef _MSC_VER
50 #include <regex.h>
51#endif
52
53/* ppriv - NO_INTERACTIVE_DEPENDENCY - for simpler debugging in Visual Studio
54 *
55 */
56#ifndef NO_INTERACTIVE_DEPENDENCY
57 #include "socket.h"
58 extern Socket sim_communication_port;
59#endif
60
61#include "util/omc_error.h"
62#include "util/omc_file.h"
63#include "simulation_data.h"
64#include "openmodelica_func.h"
65#include "meta/meta_modelica.h"
66
67#include "linearization/linearize.h"
68#include "options.h"
69#include "simulation_runtime.h"
70#include "simulation_input_xml.h"
71#include "simulation/results/simulation_result_plt.h"
72#include "simulation/results/simulation_result_csv.h"
73#include "simulation/results/simulation_result_mat4.h"
74#include "simulation/results/simulation_result_wall.h"
75#include "simulation/results/simulation_result_ia.h"
76#include "simulation/solver/solver_main.h"
77#include "simulation_info_json.h"
78#include "modelinfo.h"
79#include "simulation/solver/events.h"
80#include "simulation/solver/model_help.h"
81#include "simulation/solver/mixedSystem.h"
82#include "simulation/solver/linearSystem.h"
83#include "simulation/solver/nonlinearSystem.h"
84#include "util/rtclock.h"
85#include "omc_config.h"
86#include "simulation/solver/initialization/initialization.h"
87#include "simulation/solver/dae_mode.h"
88#include "dataReconciliation/dataReconciliation.h"
89#include "util/parallel_helper.h"
90
91#ifdef _OMC_QSS_LIB
92 #include "solver_qss/solver_qss.h"
93#endif
94
95using namespace std;
96
97#ifndef NO_INTERACTIVE_DEPENDENCY
98 Socket sim_communication_port;
99 static int sim_communication_port_open = 0;
100 static int isXMLTCP=0;
101#endif
102
103extern "C" {
104
105int sim_noemit = 0; /* Flag for not emitting data */
106
107const std::string *init_method = NULL__null; /* method for initialization. */
108
109static int callSolver(DATA* simData, threadData_t *threadData, string init_initMethod, string init_file,
110 double init_time, string outputVariablesAtEnd, int cpuTime, const char *argv_0);
111
112/*! \fn void setGlobalVerboseLevel(int argc, char**argv)
113 *
114 * \brief determine verboselevel by investigating flag -lv flags
115 *
116 * Valid flags: see LOG_STREAM_NAME in omc_error.c
117 */
118void setGlobalVerboseLevel(int argc, char**argv)
119{
120 const char *cflags = omc_flagValue[FLAG_LV];
121 const string *flags = cflags ? new string(cflags) : NULL__null;
122 int i;
123
124 if(omc_flag[FLAG_W])
125 showAllWarnings = 1;
126
127 if(!flags)
128 {
129 /* default activated */
130 useStream[LOG_STDOUT] = 1;
131 useStream[LOG_ASSERT] = 1;
132 useStream[LOG_SUCCESS] = 1;
133 return; // no lv flag given.
134 }
135
136 /* default activated, but it can be disabled with -stdout or -assert */
137 useStream[LOG_STDOUT] = 1;
138 useStream[LOG_ASSERT] = 1;
139
140 if(flags->find("LOG_ALL", 0) != string::npos)
141 {
142 for(i=1; i<SIM_LOG_MAX; ++i)
143 useStream[i] = 1;
144 }
145 else
146 {
147 string flagList = *flags;
148 string flag;
149 mmc_uint_t pos;
150
151 do
152 {
153 int error = 1;
154 pos = flagList.find(",", 0);
155 if(pos != string::npos)
156 {
157 flag = flagList.substr(0, pos);
158 flagList = flagList.substr(pos+1);
159 }
160 else
161 {
162 flag = flagList;
163 }
164
165 for(i=firstOMCErrorStream; i<SIM_LOG_MAX; ++i)
166 {
167 if(flag == string(LOG_STREAM_NAME[i]))
168 {
169 useStream[i] = 1;
170 error = 0;
171 }
172 else if(flag == string("-") + string(LOG_STREAM_NAME[i]))
173 {
174 useStream[i] = 0;
175 error = 0;
176 }
177 }
178
179 if(error)
180 {
181 warningStreamPrint(LOG_STDOUT, 1, "current options are:");
182 for(i=firstOMCErrorStream; i<SIM_LOG_MAX; ++i)
183 warningStreamPrint(LOG_STDOUT, 0, "%-18s [%s]", LOG_STREAM_NAME[i], LOG_STREAM_DESC[i]);
184 messageClose(LOG_STDOUT);
185 throwStreamPrint(NULL__null,"unrecognized option -lv %s", flags->c_str());
186 }
187 }while(pos != string::npos);
188 }
189
190 /* print LOG_INIT and LOG_SOTI if LOG_INIT_V is active */
191 if(useStream[LOG_INIT_V] == 1)
192 {
193 useStream[LOG_INIT] = 1;
194 useStream[LOG_SOTI] = 1;
195 }
196
197 /* print LOG_INIT_HOMOTOPY if LOG_INIT is active */
198 if(useStream[LOG_INIT] == 1)
199 useStream[LOG_INIT_HOMOTOPY] = 1;
200
201 /* print LOG_STATS if LOG_SOLVER if active */
202 if(useStream[LOG_SOLVER_V] == 1)
203 useStream[LOG_SOLVER] = 1;
204
205 /* print LOG_STATS if LOG_SOLVER if active */
206 if(useStream[LOG_SOLVER] == 1)
207 useStream[LOG_STATS] = 1;
208
209 /* print LOG_STATS if LOG_STATS_V if active */
210 if(useStream[LOG_STATS_V] == 1)
211 useStream[LOG_STATS] = 1;
212
213 /* print LOG_NLS if LOG_NLS_V if active */
214 if(useStream[LOG_NLS_V])
215 useStream[LOG_NLS] = 1;
216
217 /* print LOG_NLS if LOG_NLS_RES if active */
218 if(useStream[LOG_NLS_RES])
219 useStream[LOG_NLS] = 1;
220
221 /* print LOG_EVENTS if LOG_EVENTS_V if active */
222 if(useStream[LOG_EVENTS_V]) {
223 useStream[LOG_EVENTS] = 1;
224 }
225
226 /* print LOG_NLS if LOG_NLS_JAC if active */
227 if(useStream[LOG_NLS_JAC])
228 useStream[LOG_NLS] = 1;
229
230 /* print LOG_DSS if LOG_DSS_JAC if active */
231 if(useStream[LOG_DSS_JAC])
232 useStream[LOG_DSS] = 1;
233
234 delete flags;
235}
236
237
238/* Read value of flag lv_time to set time interval in which loggin is active */
239void setGlobalLoggingTime(int argc, char**argv, SIMULATION_INFO *simulationInfo)
240{
241 const char *flagStr = omc_flagValue[FLAG_LV_TIME];
242 const string *flags = flagStr ? new string(flagStr) : NULL__null;
8
Assuming 'flagStr' is non-null
9
'?' condition is true
10
Memory is allocated
243 char *endptr;
11
Potential leak of memory pointed to by 'flags'
244 const char *secondPart;
245 double loggingStartTime, loggingStopTime;
246
247 /* Check if lv_time flag is given */
248 if (flagStr==NULL__null || *flagStr=='\0')
249 {
250 /* default activated --> Log everything*/
251 simulationInfo->useLoggingTime = 0;
252 return;
253 }
254
255 /* Parse flagStr */
256 loggingStartTime = strtod(flagStr, &endptr);
257 endptr = endptr+1;
258 secondPart = endptr;
259 loggingStopTime = strtod(secondPart, &endptr);
260 if (*endptr)
261 {
262 throwStreamPrint(NULL__null, "Simulation flag %s expects two real numbers, seperated by a comata. Got: %s", FLAG_NAME[FLAG_LV_TIME], flagStr);
263 }
264
265 /* Check flag input */
266 if (loggingStartTime > loggingStopTime)
267 {
268 throwStreamPrint(NULL__null, "Simulation flag %s expects first number to be smaller then second number. Got: %s", FLAG_NAME[FLAG_LV_TIME], flagStr);
269 }
270
271 /* Save logging time */
272 simulationInfo->useLoggingTime = 1;
273 simulationInfo->loggingTimeRecord[0] = loggingStartTime;
274 simulationInfo->loggingTimeRecord[1] = loggingStopTime;
275 infoStreamPrint(LOG_STDOUT, 0, "Time dependent logging enabled. Activate loggin in intervall [%f, %f]", simulationInfo->loggingTimeRecord[0], simulationInfo->loggingTimeRecord[1]);
276
277 /* Deactivate Logging */
278 deactivateLogging();
279}
280
281
282static void readFlag(int *flag, int max, const char *value, const char *flagName, const char **names, const char **desc)
283{
284 int i;
285 if (!value) {
286 return; /* keep the default value */
287 }
288
289 for (i=1; i<max; ++i) {
290 if (0 == strcmp(value, names[i])) {
291 *flag = i;
292 return;
293 }
294 }
295
296 warningStreamPrint(LOG_STDOUT, 1, "unrecognized option %s=%s, current options are:", flagName, value);
297 for (i=1; i<max; ++i) {
298 warningStreamPrint(LOG_STDOUT, 0, "%-18s [%s]", names[i], desc[i]);
299 }
300 messageClose(LOG_STDOUT);
301 throwStreamPrint(NULL__null,"see last warning");
302}
303
304static double getFlagReal(enum _FLAG flag, double res)
305{
306 const char *flagStr = omc_flagValue[flag];
307 char *endptr;
308 if (flagStr==NULL__null || *flagStr=='\0') {
309 return res;
310 }
311 res = strtod(flagStr, &endptr);
312 if (*endptr) {
313 throwStreamPrint(NULL__null, "Simulation flag %s expects a real number, got: %s", FLAG_NAME[flag], flagStr);
314 }
315 return res;
316}
317
318/**
319 * Read the variable filter and mark variables that should not be part of the result file.
320 * This phase is skipped for interactive simulations
321 */
322void initializeOutputFilter(MODEL_DATA *modelData, const char *variableFilter, int resultFormatHasCheapAliasesAndParameters)
323{
324#ifndef _MSC_VER
325 regex_t myregex;
326 int flags = REG_EXTENDED1;
327 int rc;
328 string tmp = ("^(" + string(variableFilter) + ")$");
329 const char *filter = tmp.c_str(); // C++ strings are horrible to work with...
330
331 if(0 == strcmp(filter, ".*")) { // This matches all variables, so we don't need to do anything
332 return;
333 }
334
335 rc = regcomp(&myregex, filter, flags);
336 if(rc) {
337 char err_buf[2048] = {0};
338 regerror(rc, &myregex, err_buf, 2048);
339 std::cerr << "Failed to compile regular expression: " << filter << " with error: " << err_buf << ". Defaulting to outputting all variables." << std::endl;
340 return;
341 }
342
343 for(mmc_sint_t i=0; i<modelData->nVariablesReal; i++) if(!modelData->realVarsData[i].filterOutput) {
344 modelData->realVarsData[i].filterOutput = regexec(&myregex, modelData->realVarsData[i].info.name, 0, NULL__null, 0) != 0;
345 }
346 for(mmc_sint_t i=0; i<modelData->nAliasReal; i++) if(!modelData->realAlias[i].filterOutput) {
347 if(modelData->realAlias[i].aliasType == 0) /* variable */ {
348 modelData->realAlias[i].filterOutput = regexec(&myregex, modelData->realAlias[i].info.name, 0, NULL__null, 0) != 0;
349 if (0 == modelData->realAlias[i].filterOutput) {
350 modelData->realVarsData[modelData->realAlias[i].nameID].filterOutput = 0;
351 }
352 } else if(modelData->realAlias[i].aliasType == 1) /* parameter */ {
353 modelData->realAlias[i].filterOutput = regexec(&myregex, modelData->realAlias[i].info.name, 0, NULL__null, 0) != 0;
354 if (0 == modelData->realAlias[i].filterOutput && resultFormatHasCheapAliasesAndParameters) {
355 modelData->realParameterData[modelData->realAlias[i].nameID].filterOutput = 0;
356 }
357 }
358 }
359 for (mmc_sint_t i=0; i<modelData->nVariablesInteger; i++) if(!modelData->integerVarsData[i].filterOutput) {
360 modelData->integerVarsData[i].filterOutput = regexec(&myregex, modelData->integerVarsData[i].info.name, 0, NULL__null, 0) != 0;
361 }
362 for (mmc_sint_t i=0; i<modelData->nAliasInteger; i++) if(!modelData->integerAlias[i].filterOutput) {
363 if(modelData->integerAlias[i].aliasType == 0) /* variable */ {
364 modelData->integerAlias[i].filterOutput = regexec(&myregex, modelData->integerAlias[i].info.name, 0, NULL__null, 0) != 0;
365 if (0 == modelData->integerAlias[i].filterOutput) {
366 modelData->integerVarsData[modelData->integerAlias[i].nameID].filterOutput = 0;
367 }
368 } else if(modelData->integerAlias[i].aliasType == 1) /* parameter */ {
369 modelData->integerAlias[i].filterOutput = regexec(&myregex, modelData->integerAlias[i].info.name, 0, NULL__null, 0) != 0;
370 if (0 == modelData->integerAlias[i].filterOutput && resultFormatHasCheapAliasesAndParameters) {
371 modelData->integerParameterData[modelData->integerAlias[i].nameID].filterOutput = 0;
372 }
373 }
374 }
375 for (mmc_sint_t i=0; i<modelData->nVariablesBoolean; i++) if(!modelData->booleanVarsData[i].filterOutput) {
376 modelData->booleanVarsData[i].filterOutput = regexec(&myregex, modelData->booleanVarsData[i].info.name, 0, NULL__null, 0) != 0;
377 }
378 for (mmc_sint_t i=0; i<modelData->nAliasBoolean; i++) if(!modelData->booleanAlias[i].filterOutput) {
379 if(modelData->booleanAlias[i].aliasType == 0) /* variable */ {
380 modelData->booleanAlias[i].filterOutput = regexec(&myregex, modelData->booleanAlias[i].info.name, 0, NULL__null, 0) != 0;
381 if (0 == modelData->booleanAlias[i].filterOutput) {
382 modelData->booleanVarsData[modelData->booleanAlias[i].nameID].filterOutput = 0;
383 }
384 } else if(modelData->booleanAlias[i].aliasType == 1) /* parameter */ {
385 modelData->booleanAlias[i].filterOutput = regexec(&myregex, modelData->booleanAlias[i].info.name, 0, NULL__null, 0) != 0;
386 if (0 == modelData->booleanAlias[i].filterOutput && resultFormatHasCheapAliasesAndParameters) {
387 modelData->booleanParameterData[modelData->booleanAlias[i].nameID].filterOutput = 0;
388 }
389 }
390 }
391 for (mmc_sint_t i=0; i<modelData->nVariablesString; i++) if(!modelData->stringVarsData[i].filterOutput) {
392 modelData->stringVarsData[i].filterOutput = regexec(&myregex, modelData->stringVarsData[i].info.name, 0, NULL__null, 0) != 0;
393 }
394 for (mmc_sint_t i=0; i<modelData->nAliasString; i++) if(!modelData->stringAlias[i].filterOutput) {
395 if(modelData->stringAlias[i].aliasType == 0) /* variable */ {
396 modelData->stringAlias[i].filterOutput = regexec(&myregex, modelData->stringAlias[i].info.name, 0, NULL__null, 0) != 0;
397 if (0 == modelData->stringAlias[i].filterOutput) {
398 modelData->stringVarsData[modelData->stringAlias[i].nameID].filterOutput = 0;
399 }
400 } else if(modelData->stringAlias[i].aliasType == 1) /* parameter */ {
401 modelData->stringAlias[i].filterOutput = regexec(&myregex, modelData->stringAlias[i].info.name, 0, NULL__null, 0) != 0;
402 if (0 == modelData->stringAlias[i].filterOutput && resultFormatHasCheapAliasesAndParameters) {
403 modelData->stringParameterData[modelData->stringAlias[i].nameID].filterOutput = 0;
404 }
405 }
406 }
407 regfree(&myregex);
408#endif
409 return;
410}
411
412/**
413 * Starts a non-interactive simulation
414 */
415int startNonInteractiveSimulation(int argc, char**argv, DATA* data, threadData_t *threadData)
416{
417 TRACE_PUSH
418
419 int retVal = -1;
420
421 /* linear model option is set : <-l lintime> */
422 int create_linearmodel = omc_flag[FLAG_L];
423 const char* lintime = omc_flagValue[FLAG_L];
424
425 /* activated measure time option with LOG_STATS */
426 int measure_time_flag_previous = measure_time_flag;
427 if (!measure_time_flag && (ACTIVE_STREAM(LOG_STATS)(useStream[LOG_STATS]) || omc_flag[FLAG_CPU]))
428 {
429 measure_time_flag = 1;
430 }
431 errno(*__errno_location ()) = 0;
432 if (omc_flag[FLAG_ALARM]) {
433 char *endptr;
434 mmc_sint_t alarmVal = strtol(omc_flagValue[FLAG_ALARM],&endptr,10);
435 if (errno(*__errno_location ()) || *endptr != 0) {
436 throwStreamPrint(threadData, "-alarm takes an integer argument (got '%s')", omc_flagValue[FLAG_ALARM]);
437 }
438 alarm(alarmVal);
439 }
440
441 /* calc numStep */
442 data->simulationInfo->numSteps = static_cast<modelica_integer>(round((data->simulationInfo->stopTime - data->simulationInfo->startTime)/data->simulationInfo->stepSize));
443 infoStreamPrint(LOG_SOLVER, 0, "numberOfIntervals = %ld", (long) data->simulationInfo->numSteps);
444
445 { /* Setup the clock */
446 enum omc_rt_clock_t clock = OMC_CLOCK_REALTIME;
447 const char *clockName;
448 if((clockName = omc_flagValue[FLAG_CLOCK]) != NULL__null) {
449 if(0 == strcmp(clockName, "CPU")) {
450 clock = OMC_CLOCK_CPUTIME;
451 } else if(0 == strcmp(clockName, "RT")) {
452 clock = OMC_CLOCK_REALTIME;
453 } else if(0 == strcmp(clockName, "CYC")) {
454 clock = OMC_CPU_CYCLES;
455 } else {
456 warningStreamPrint(LOG_STDOUT, 0, "[unknown clock-type] got %s, expected CPU|RT|CYC. Defaulting to RT.", clockName);
457 }
458 }
459 if(rt_set_clock(clock)) {
460 warningStreamPrint(LOG_STDOUT, 0, "Chosen clock-type: %s not available for the current platform. Defaulting to real-time.", clockName);
461 }
462 }
463
464 if(measure_time_flag) {
465 rt_tick(SIM_TIMER_INFO_XML14);
466 modelInfoInit(&data->modelData->modelDataXml);
467 rt_accumulate(SIM_TIMER_INFO_XML14);
468 //std::cerr << "ModelData with " << data->modelData->modelDataXml.nFunctions << " functions and " << data->modelData->modelDataXml.nEquations << " equations and " << data->modelData->modelDataXml.nProfileBlocks << " profileBlocks\n" << std::endl;
469 rt_init(SIM_TIMER_FIRST_FUNCTION16 + data->modelData->modelDataXml.nFunctions + data->modelData->modelDataXml.nEquations + data->modelData->modelDataXml.nProfileBlocks + 4 /* sentinel */);
470 rt_measure_overhead(SIM_TIMER_TOTAL0);
471 rt_clear(SIM_TIMER_TOTAL0);
472 rt_tick(SIM_TIMER_TOTAL0);
473 rt_clear(SIM_TIMER_PREINIT6);
474 rt_tick(SIM_TIMER_PREINIT6);
475 rt_clear(SIM_TIMER_OUTPUT3);
476 rt_clear(SIM_TIMER_EVENT4);
477 rt_clear(SIM_TIMER_INIT1);
478 }
479
480 if(create_linearmodel)
481 {
482 if(lintime == NULL__null) {
483 data->simulationInfo->stopTime = data->simulationInfo->startTime;
484 } else {
485 data->simulationInfo->stopTime = atof(lintime);
486 }
487 infoStreamPrint(LOG_STDOUT, 0, "Linearization will performed at point of time: %f", data->simulationInfo->stopTime);
488 }
489
490 /* set delta x for linearization */
491 if(omc_flag[FLAG_DELTA_X_LINEARIZE]) {
492 numericalDifferentiationDeltaXlinearize = atof(omc_flagValue[FLAG_DELTA_X_LINEARIZE]);
493 infoStreamPrint(LOG_SOLVER, 0, "Set delta x for numerical differentiation of the linearization to %f", numericalDifferentiationDeltaXlinearize);
494 }else{
495 numericalDifferentiationDeltaXlinearize = sqrt(DBL_EPSILON2.2204460492503131e-16*2e1);
496 }
497
498 /* set delta x for integration methods dassl, ida */
499 if(omc_flag[FLAG_DELTA_X_SOLVER]) {
500 numericalDifferentiationDeltaXsolver = atof(omc_flagValue[FLAG_DELTA_X_SOLVER]);
501 infoStreamPrint(LOG_SOLVER, 0, "Set delta x for numerical differentiation of the integrator to %f", numericalDifferentiationDeltaXsolver);
502 }else{
503 numericalDifferentiationDeltaXsolver = sqrt(DBL_EPSILON2.2204460492503131e-16);
504 }
505
506 if(omc_flag[FLAG_S]) {
507 if (omc_flagValue[FLAG_S]) {
508 data->simulationInfo->solverMethod = GC_strdup(omc_flagValue[FLAG_S]);
509 infoStreamPrint(LOG_SOLVER, 0, "overwrite solver method: %s [from command line]", data->simulationInfo->solverMethod);
510 }
511 }
512 /* if the model is compiled in daeMode then we have to use ida solver */
513 if (compiledInDAEMode && std::string("ida") != data->simulationInfo->solverMethod) {
514 data->simulationInfo->solverMethod = GC_strdup(std::string("ida").c_str());
515 infoStreamPrint(LOG_SIMULATION, 0, "overwrite solver method: %s [DAEmode works only with IDA solver]", data->simulationInfo->solverMethod);
516 }
517
518 // Create a result file
519 const char *result_file = omc_flagValue[FLAG_R];
520 string result_file_cstr;
521 if (result_file) {
522 data->modelData->resultFileName = GC_strdup(result_file);
523 } else if (omc_flag[FLAG_OUTPUT_PATH]) { /* read the output path from the command line (if any) */
524 if (0 > GC_asprintf(&result_file, "%s/%s_res.%s", omc_flagValue[FLAG_OUTPUT_PATH], data->modelData->modelFilePrefix, data->simulationInfo->outputFormat)) {
525 throwStreamPrint(NULL__null, "simulation_runtime.c: Error: can not allocate memory.");
526 }
527 data->modelData->resultFileName = GC_strdup(result_file);
528 } else {
529 result_file_cstr = string(data->modelData->modelFilePrefix) + string("_res.") + data->simulationInfo->outputFormat;
530 data->modelData->resultFileName = GC_strdup(result_file_cstr.c_str());
531 }
532
533 string init_initMethod = "";
534 string init_file = "";
535 string init_time_string = "";
536 double init_time = 0.0;
537 string outputVariablesAtEnd = "";
538 int cpuTime = omc_flag[FLAG_CPU];
539
540 if(omc_flag[FLAG_IIM]) {
541 init_initMethod = omc_flagValue[FLAG_IIM];
542 }
543 if(omc_flag[FLAG_IIF]) {
544 init_file = omc_flagValue[FLAG_IIF];
545 }
546 if(omc_flag[FLAG_IIT]) {
547 init_time_string = omc_flagValue[FLAG_IIT];
548 init_time = atof(init_time_string.c_str());
549 }
550 if(omc_flag[FLAG_ILS]) {
551 init_lambda_steps = atoi(omc_flagValue[FLAG_ILS]);
552 if(init_lambda_steps <= 0) {
553 init_lambda_steps = 0;
554 infoStreamPrint(LOG_STDOUT, 0, "Number of lambda steps set to 0. Homotopy is disabled.");
555 }
556 else {
557 infoStreamPrint(LOG_STDOUT, 0, "Number of lambda steps for homotopy approach changed to %d", init_lambda_steps);
558 }
559 }
560 if(omc_flag[FLAG_MAX_BISECTION_ITERATIONS]) {
561 maxBisectionIterations = atoi(omc_flagValue[FLAG_MAX_BISECTION_ITERATIONS]);
562 infoStreamPrint(LOG_STDOUT, 0, "Maximum number of bisection iterations changed to %d", maxBisectionIterations);
563 }
564 if(omc_flag[FLAG_MAX_EVENT_ITERATIONS]) {
565 maxEventIterations = atoi(omc_flagValue[FLAG_MAX_EVENT_ITERATIONS]);
566 infoStreamPrint(LOG_STDOUT, 0, "Maximum number of event iterations changed to %d", maxEventIterations);
567 }
568 if(omc_flag[FLAG_OUTPUT]) {
569 outputVariablesAtEnd = omc_flagValue[FLAG_OUTPUT];
570 }
571
572 /* Check if logging should be enabled */
573 if ((data->simulationInfo->useLoggingTime == 1) && (data->simulationInfo->startTime >= data->simulationInfo->loggingTimeRecord[0])) {
574 reactivateLogging();
575 }
576
577 retVal = callSolver(data, threadData, init_initMethod, init_file, init_time, outputVariablesAtEnd, cpuTime, argv[0]);
578
579 /* Check if logging should be disabled */
580 if (data->simulationInfo->useLoggingTime == 1) {
581 deactivateLogging();
582 }
583
584 if (omc_flag[FLAG_ALARM]) {
585 alarm(0);
586 }
587
588 if(0 == retVal && omc_flag[FLAG_DATA_RECONCILE])
589 {
590 infoStreamPrint(LOG_STDOUT, 0, "DataReconciliation Starting!");
591 infoStreamPrint(LOG_STDOUT, 0, "%s", data->modelData->modelName);
592 retVal = dataReconciliation(data, threadData);
593 infoStreamPrint(LOG_STDOUT, 0, "DataReconciliation Completed!");
594 }
595
596 if(0 == retVal && create_linearmodel) {
597 rt_tick(SIM_TIMER_JACOBIAN5);
598 retVal = linearize(data, threadData);
599 rt_accumulate(SIM_TIMER_JACOBIAN5);
600 infoStreamPrint(LOG_STDOUT, 0, "Linear model is created!");
601 }
602
603 /* Use the saved state of measure_time_flag.
604 * measure_time_flag is set to active when LOG_STATS is ON.
605 * So before doing the profiling reset the measure_time_flag to measure_time_flag_previous state.
606 */
607 measure_time_flag = measure_time_flag_previous;
608 string output_path = "";
609 if (0 == retVal && measure_time_flag) {
610 if (omc_flag[FLAG_OUTPUT_PATH]) { /* read the output path from the command line (if any) */
611 output_path = string(omc_flagValue[FLAG_INPUT_PATH]) + string("/");
612 }
613 const string jsonInfo = string(data->modelData->modelFilePrefix) + "_prof.json";
614 const string modelInfo = string(data->modelData->modelFilePrefix) + "_prof.xml";
615 const string plotFile = string(data->modelData->modelFilePrefix) + "_prof.plt";
616 rt_accumulate(SIM_TIMER_TOTAL0);
617 const char* plotFormat = omc_flagValue[FLAG_MEASURETIMEPLOTFORMAT];
618 retVal = printModelInfo(data, threadData, output_path.c_str(), modelInfo.c_str(), plotFile.c_str(), plotFormat ? plotFormat : "svg",
619 data->simulationInfo->solverMethod, data->simulationInfo->outputFormat, data->modelData->resultFileName) && retVal;
620 retVal = printModelInfoJSON(data, threadData, output_path.c_str(), jsonInfo.c_str(), data->modelData->resultFileName) && retVal;
621 }
622
623 TRACE_POP
624 return retVal;
625}
626
627/*! \fn initializeResultData(DATA* simData, int cpuTime)
628 *
629 * \param [ref] [simData]
630 * \param [int] [cpuTime]
631 *
632 * This function initializes result object to emit data.
633 */
634int initializeResultData(DATA* simData, threadData_t *threadData, int cpuTime)
635{
636 int resultFormatHasCheapAliasesAndParameters = 0;
637 int retVal = 0;
638 mmc_sint_t maxSteps = 4 * simData->simulationInfo->numSteps;
639 sim_result.filename = strdup(simData->modelData->resultFileName);
640 sim_result.numpoints = maxSteps;
641 sim_result.cpuTime = cpuTime;
642 if (sim_noemit || 0 == strcmp("empty", simData->simulationInfo->outputFormat)) {
643 /* Default is set to noemit */
644 } else if(0 == strcmp("csv", simData->simulationInfo->outputFormat)) {
645 sim_result.init = omc_csv_init;
646 sim_result.emit = omc_csv_emit;
647 /* sim_result.writeParameterData = omc_csv_writeParameterData; */
648 sim_result.free = omc_csv_free;
649 } else if(0 == strcmp("mat", simData->simulationInfo->outputFormat)) {
650 sim_result.init = mat4_init4;
651 sim_result.emit = mat4_emit4;
652 sim_result.writeParameterData = mat4_writeParameterData4;
653 sim_result.free = mat4_free4;
654 resultFormatHasCheapAliasesAndParameters = 1;
655#if !defined(OMC_MINIMAL_RUNTIME)
656 } else if(0 == strcmp("wall", simData->simulationInfo->outputFormat)) {
657 sim_result.init = recon_wall_init;
658 sim_result.emit = recon_wall_emit;
659 sim_result.writeParameterData = recon_wall_writeParameterData;
660 sim_result.free = recon_wall_free;
661 resultFormatHasCheapAliasesAndParameters = 1;
662 } else if(0 == strcmp("plt", simData->simulationInfo->outputFormat)) {
663 sim_result.init = plt_init;
664 sim_result.emit = plt_emit;
665 /* sim_result.writeParameterData = plt_writeParameterData; */
666 sim_result.free = plt_free;
667 }
668 //NEW interactive
669 else if(0 == strcmp("ia", simData->simulationInfo->outputFormat)) {
670 sim_result.init = ia_init;
671 sim_result.emit = ia_emit;
672 //sim_result.writeParameterData = ia_writeParameterData;
673 sim_result.free = ia_free;
674#endif
675 } else {
676 cerr << "Unknown output format: " << simData->simulationInfo->outputFormat << endl;
677 return 1;
678 }
679 initializeOutputFilter(simData->modelData, simData->simulationInfo->variableFilter, resultFormatHasCheapAliasesAndParameters);
680 sim_result.init(&sim_result, simData, threadData);
681 infoStreamPrint(LOG_SOLVER, 0, "Allocated simulation result data storage for method '%s' and file='%s'", (char*) simData->simulationInfo->outputFormat, sim_result.filename);
682 return 0;
683}
684
685/**
686 * Calls the solver which is selected in the parameter string "method"
687 * This function is used for interactive and non-interactive simulation
688 * Parameter method:
689 * "" & "dassl" calls a DASSL Solver
690 * "euler" calls an Euler solver
691 * "rungekutta" calls a fourth-order Runge-Kutta Solver
692 */
693static int callSolver(DATA* simData, threadData_t *threadData, string init_initMethod, string init_file,
694 double init_time, string outputVariablesAtEnd, int cpuTime, const char *argv_0)
695{
696 TRACE_PUSH
697 int retVal = -1;
698 mmc_sint_t i;
699 mmc_sint_t solverID = S_UNKNOWN;
700 const char* outVars = (outputVariablesAtEnd.size() == 0) ? NULL__null : outputVariablesAtEnd.c_str();
701 MMC_TRY_INTERNAL(mmc_jumper){ jmp_buf new_mmc_jumper, *old_jumper __attribute__((unused))
= threadData->mmc_jumper; threadData->mmc_jumper = &
new_mmc_jumper; if (_setjmp (new_mmc_jumper) == 0) {
702 MMC_TRY_INTERNAL(globalJumpBuffer){ jmp_buf new_mmc_jumper, *old_jumper __attribute__((unused))
= threadData->globalJumpBuffer; threadData->globalJumpBuffer
= &new_mmc_jumper; if (_setjmp (new_mmc_jumper) == 0) {
703
704 if (initializeResultData(simData, threadData, cpuTime)) {
705 TRACE_POP
706 return -1;
707 }
708 simData->real_time_sync.scaling = getFlagReal(FLAG_RT, 0.0);
709
710 if(std::string("") == simData->simulationInfo->solverMethod) {
711#if defined(WITH_DASSL)
712 solverID = S_DASSL;
713#else
714 solverID = S_RUNGEKUTTA;
715#endif
716 } else {
717 for(i=1; i<S_MAX; ++i) {
718 if(std::string(SOLVER_METHOD_NAME[i]) == simData->simulationInfo->solverMethod) {
719 solverID = i;
720 }
721 }
722 }
723 /* if no states are present, then we can
724 * use euler method, since it does nothing.
725 */
726 if ( (simData->modelData->nStates < 1 &&
727 solverID != S_OPTIMIZATION &&
728 solverID != S_SYM_SOLVER &&
729 !compiledInDAEMode) ||
730 (compiledInDAEMode && (simData->simulationInfo->daeModeData->nResidualVars +
731 simData->simulationInfo->daeModeData->nAlgebraicDAEVars < 1))
732 )
733 {
734 solverID = S_EULER;
735 if (compiledInDAEMode)
736 {
737 simData->callback->functionDAE = evaluateDAEResiduals_wrapperEventUpdate;
738 }
739 }
740
741 if(S_UNKNOWN == solverID) {
742 warningStreamPrint(LOG_STDOUT, 0, "unrecognized option -s %s", (char*) simData->simulationInfo->solverMethod);
743 warningStreamPrint(LOG_STDOUT, 0, "current options are:");
744 for(i=1; i<S_MAX; ++i) {
745 warningStreamPrint(LOG_STDOUT, 0, "%-18s [%s]", SOLVER_METHOD_NAME[i], SOLVER_METHOD_DESC[i]);
746 }
747 throwStreamPrint(threadData,"see last warning");
748 retVal = 1;
749 } else {
750 infoStreamPrint(LOG_SOLVER, 0, "recognized solver: %s", SOLVER_METHOD_NAME[solverID]);
751 /* special solvers */
752#ifdef _OMC_QSS_LIB
753 if(S_QSS == solverID) {
754 retVal = qss_main(argc, argv, simData->simulationInfo->startTime,
755 simData->simulationInfo->stopTime, simData->simulationInfo->stepSize,
756 simData->simulationInfo->numSteps, simData->simulationInfo->tolerance, 3);
757 } else /* standard solver interface */
758#endif
759 retVal = solver_main(simData, threadData, init_initMethod.c_str(), init_file.c_str(), init_time, solverID, outVars, argv_0);
760 }
761
762 MMC_CATCH_INTERNAL(mmc_jumper)} threadData->mmc_jumper = old_jumper;mmc_catch_dummy_fn()
;}
763 MMC_CATCH_INTERNAL(globalJumpBuffer)} threadData->globalJumpBuffer = old_jumper;mmc_catch_dummy_fn
();}
764
765 sim_result.free(&sim_result, simData, threadData);
766
767 TRACE_POP
768 return retVal;
769}
770
771
772/**
773 * Initialization is the same for interactive or non-interactive simulation
774 */
775int initRuntimeAndSimulation(int argc, char**argv, DATA *data, threadData_t *threadData)
776{
777 int i;
778 initDumpSystem();
779
780 if(setLogFormat(argc, argv) || helpFlagSet(argc, argv) || checkCommandLineArguments(argc, argv))
1
Assuming the condition is false
2
Assuming the condition is false
3
Assuming the condition is false
4
Taking false branch
781 {
782 infoStreamPrint(LOG_STDOUT, 1, "usage: %s", argv[0]);
783
784 for(i=1; i<FLAG_MAX; ++i)
785 {
786 if(FLAG_TYPE[i] == FLAG_TYPE_FLAG) {
787 infoStreamPrint(LOG_STDOUT, 0, "<-%s>\n %s", FLAG_NAME[i], FLAG_DESC[i]);
788 } else if(FLAG_TYPE[i] == FLAG_TYPE_OPTION) {
789 infoStreamPrint(LOG_STDOUT, 0, "<-%s=value> or <-%s value>\n %s", FLAG_NAME[i], FLAG_NAME[i], FLAG_DESC[i]);
790 } else {
791 warningStreamPrint(LOG_STDOUT, 0, "[unknown flag-type] <-%s>", FLAG_NAME[i]);
792 }
793 }
794
795 messageClose(LOG_STDOUT);
796 EXIT(0){fflush(__null); _exit(0);};
797 }
798
799 if(omc_flag[FLAG_HELP]) {
5
Assuming the condition is false
6
Taking false branch
800 std::string option = omc_flagValue[FLAG_HELP];
801
802 for(i=1; i<FLAG_MAX; ++i)
803 {
804 if(option == std::string(FLAG_NAME[i]))
805 {
806 int j;
807
808 if(FLAG_TYPE[i] == FLAG_TYPE_FLAG)
809 infoStreamPrint(LOG_STDOUT, 1, "detailed flag-description for: <-%s>\n%s", FLAG_NAME[i], FLAG_DETAILED_DESC[i]);
810 else if(FLAG_TYPE[i] == FLAG_TYPE_OPTION)
811 infoStreamPrint(LOG_STDOUT, 1, "detailed flag-description for: <-%s=value> or <-%s value>\n%s", FLAG_NAME[i], FLAG_NAME[i], FLAG_DETAILED_DESC[i]);
812 else
813 warningStreamPrint(LOG_STDOUT, 1, "[unknown flag-type] <-%s>", FLAG_NAME[i]);
814
815 /* detailed information for some flags */
816 switch(i)
817 {
818 case FLAG_IDA_LS:
819 for(j=1; j<IDA_LS_MAX; ++j) {
820 infoStreamPrint(LOG_STDOUT, 0, "%-18s [%s]", IDA_LS_METHOD[j], IDA_LS_METHOD_DESC[j]);
821 }
822 break;
823
824 case FLAG_IIM:
825 for(j=1; j<IIM_MAX; ++j) {
826 infoStreamPrint(LOG_STDOUT, 0, "%-18s [%s]", INIT_METHOD_NAME[j], INIT_METHOD_DESC[j]);
827 }
828 break;
829
830 case FLAG_JACOBIAN:
831 for(j=1; j<JAC_MAX; ++j) {
832 infoStreamPrint(LOG_STDOUT, 0, "%-18s [%s]", JACOBIAN_METHOD[j], JACOBIAN_METHOD_DESC[j]);
833 }
834 break;
835
836 case FLAG_LS:
837 for(j=1; j<LS_MAX; ++j) {
838 infoStreamPrint(LOG_STDOUT, 0, "%-18s [%s]", LS_NAME[j], LS_DESC[j]);
839 }
840 break;
841
842 case FLAG_LSS:
843 for(j=1; j<LSS_MAX; ++j) {
844 infoStreamPrint(LOG_STDOUT, 0, "%-18s [%s]", LSS_NAME[j], LSS_DESC[j]);
845 }
846 break;
847
848 case FLAG_LV:
849 for(j=firstOMCErrorStream; j<SIM_LOG_MAX; ++j) {
850 infoStreamPrint(LOG_STDOUT, 0, "%-18s [%s]", LOG_STREAM_NAME[j], LOG_STREAM_DESC[j]);
851 }
852 break;
853
854 case FLAG_NEWTON_STRATEGY:
855 for(j=firstOMCErrorStream; j<NEWTON_MAX; ++j) {
856 infoStreamPrint(LOG_STDOUT, 0, "%-18s [%s]", NEWTONSTRATEGY_NAME[j], NEWTONSTRATEGY_DESC[j]);
857 }
858 break;
859
860 case FLAG_NLS:
861 for(j=firstOMCErrorStream; j<NLS_MAX; ++j) {
862 infoStreamPrint(LOG_STDOUT, 0, "%-18s [%s]", NLS_NAME[j], NLS_DESC[j]);
863 }
864 break;
865
866 case FLAG_NLS_LS:
867 for(j=firstOMCErrorStream; j<NLS_LS_MAX; ++j) {
868 infoStreamPrint(LOG_STDOUT, 0, "%-18s [%s]", NLS_LS_METHOD[j], NLS_LS_METHOD_DESC[j]);
869 }
870 break;
871
872 case FLAG_S:
873 for(j=1; j<S_MAX; ++j) {
874 infoStreamPrint(LOG_STDOUT, 0, "%-18s [%s]", SOLVER_METHOD_NAME[j], SOLVER_METHOD_DESC[j]);
875 }
876 break;
877 }
878 messageClose(LOG_STDOUT);
879
880 EXIT(0){fflush(__null); _exit(0);};
881 }
882 }
883
884 warningStreamPrint(LOG_STDOUT, 0, "invalid command line option: -help=%s", option.c_str());
885 warningStreamPrint(LOG_STDOUT, 0, "use %s -help for a list of all command-line flags", argv[0]);
886 EXIT(0){fflush(__null); _exit(0);};
887 }
888
889 setGlobalVerboseLevel(argc, argv);
890 setGlobalLoggingTime(argc, argv, data->simulationInfo);
7
Calling 'setGlobalLoggingTime'
891 initializeDataStruc(data, threadData);
892 if(!data)
893 {
894 std::cerr << "Error: Could not initialize the global data structure file" << std::endl;
895 EXIT(1){fflush(__null); _exit(1);};
896 }
897
898 readFlag(&data->simulationInfo->nlsMethod, NLS_MAX, omc_flagValue[FLAG_NLS], "-nls", NLS_NAME, NLS_DESC);
899 readFlag(&data->simulationInfo-> lsMethod, LS_MAX, omc_flagValue[FLAG_LS ], "-ls", LS_NAME, LS_DESC);
900 readFlag(&data->simulationInfo->lssMethod, LSS_MAX, omc_flagValue[FLAG_LSS], "-lss", LSS_NAME, LSS_DESC);
901 readFlag(&homBacktraceStrategy, HOM_BACK_STRAT_MAX, omc_flagValue[FLAG_HOMOTOPY_BACKTRACE_STRATEGY], "-homBacktraceStrategy", HOM_BACK_STRAT_NAME, HOM_BACK_STRAT_DESC);
902 readFlag(&data->simulationInfo->newtonStrategy, NEWTON_MAX, omc_flagValue[FLAG_NEWTON_STRATEGY], "-newton", NEWTONSTRATEGY_NAME, NEWTONSTRATEGY_DESC);
903 data->simulationInfo->nlsCsvInfomation = omc_flag[FLAG_NLS_INFO];
904 readFlag(&data->simulationInfo->nlsLinearSolver, NLS_LS_MAX, omc_flagValue[FLAG_NLS_LS], "-nlsLS", NLS_LS_METHOD, NLS_LS_METHOD_DESC);
905
906 if(omc_flag[FLAG_HOMOTOPY_ADAPT_BEND]) {
907 homAdaptBend = atof(omc_flagValue[FLAG_HOMOTOPY_ADAPT_BEND]);
908 infoStreamPrint(LOG_STDOUT, 0, "homotopy parameter homAdaptBend changed to %f", homAdaptBend);
909 }
910
911 if(omc_flag[FLAG_HOMOTOPY_H_EPS]) {
912 homHEps = atof(omc_flagValue[FLAG_HOMOTOPY_H_EPS]);
913 infoStreamPrint(LOG_STDOUT, 0, "homotopy parameter homHEps changed to %f", homHEps);
914 }
915
916 if(omc_flag[FLAG_HOMOTOPY_MAX_LAMBDA_STEPS]) {
917 homMaxLambdaSteps = atoi(omc_flagValue[FLAG_HOMOTOPY_MAX_LAMBDA_STEPS]);
918 infoStreamPrint(LOG_STDOUT, 0, "homotopy parameter homMaxLambdaSteps changed to %d", homMaxLambdaSteps);
919 }
920
921 if(omc_flag[FLAG_HOMOTOPY_MAX_NEWTON_STEPS]) {
922 homMaxNewtonSteps = atoi(omc_flagValue[FLAG_HOMOTOPY_MAX_NEWTON_STEPS]);
923 infoStreamPrint(LOG_STDOUT, 0, "homotopy parameter homMaxNewtonSteps changed to %d", homMaxNewtonSteps);
924 }
925
926 if(omc_flag[FLAG_HOMOTOPY_MAX_TRIES]) {
927 homMaxTries = atoi(omc_flagValue[FLAG_HOMOTOPY_MAX_TRIES]);
928 infoStreamPrint(LOG_STDOUT, 0, "homotopy parameter homMaxTries changed to %d", homMaxTries);
929 }
930
931 if(omc_flag[FLAG_HOMOTOPY_TAU_DEC_FACTOR]) {
932 homTauDecreasingFactor = atof(omc_flagValue[FLAG_HOMOTOPY_TAU_DEC_FACTOR]);
933 infoStreamPrint(LOG_STDOUT, 0, "homotopy parameter homTauDecreasingFactor changed to %f", homTauDecreasingFactor);
934 }
935
936 if(omc_flag[FLAG_HOMOTOPY_TAU_DEC_FACTOR_PRED]) {
937 homTauDecreasingFactorPredictor = atof(omc_flagValue[FLAG_HOMOTOPY_TAU_DEC_FACTOR_PRED]);
938 infoStreamPrint(LOG_STDOUT, 0, "homotopy parameter homTauDecreasingFactorPredictor changed to %f", homTauDecreasingFactorPredictor);
939 }
940
941 if(omc_flag[FLAG_HOMOTOPY_TAU_INC_FACTOR]) {
942 homTauIncreasingFactor = atof(omc_flagValue[FLAG_HOMOTOPY_TAU_INC_FACTOR]);
943 infoStreamPrint(LOG_STDOUT, 0, "homotopy parameter homTauIncreasingFactor changed to %f", homTauIncreasingFactor);
944 }
945
946 if(omc_flag[FLAG_HOMOTOPY_TAU_INC_THRESHOLD]) {
947 homTauIncreasingThreshold = atof(omc_flagValue[FLAG_HOMOTOPY_TAU_INC_THRESHOLD]);
948 infoStreamPrint(LOG_STDOUT, 0, "homotopy parameter homTauIncreasingThreshold changed to %f", homTauIncreasingThreshold);
949 }
950
951 if(omc_flag[FLAG_HOMOTOPY_TAU_MAX]) {
952 homTauMax = atof(omc_flagValue[FLAG_HOMOTOPY_TAU_MAX]);
953 infoStreamPrint(LOG_STDOUT, 0, "homotopy parameter homTauMax changed to %f", homTauMax);
954 }
955
956 if(omc_flag[FLAG_HOMOTOPY_TAU_MIN]) {
957 homTauMin = atof(omc_flagValue[FLAG_HOMOTOPY_TAU_MIN]);
958 infoStreamPrint(LOG_STDOUT, 0, "homotopy parameter homTauMin changed to %f", homTauMin);
959 }
960
961 if(omc_flag[FLAG_HOMOTOPY_TAU_START]) {
962 homTauStart = atof(omc_flagValue[FLAG_HOMOTOPY_TAU_START]);
963 infoStreamPrint(LOG_STDOUT, 0, "homotopy parameter homTauStart changed to %f", homTauStart);
964 }
965
966 if(omc_flag[FLAG_LSS_MAX_DENSITY]) {
967 linearSparseSolverMaxDensity = atof(omc_flagValue[FLAG_LSS_MAX_DENSITY]);
968 infoStreamPrint(LOG_STDOUT, 0, "Maximum density for using linear sparse solver changed to %f", linearSparseSolverMaxDensity);
969 }
970 if(omc_flag[FLAG_LSS_MIN_SIZE]) {
971 linearSparseSolverMinSize = atoi(omc_flagValue[FLAG_LSS_MIN_SIZE]);
972 infoStreamPrint(LOG_STDOUT, 0, "Maximum system size for using linear sparse solver changed to %d", linearSparseSolverMinSize);
973 }
974 if(omc_flag[FLAG_NLS_MAX_DENSITY]) {
975 nonlinearSparseSolverMaxDensity = atof(omc_flagValue[FLAG_NLS_MAX_DENSITY]);
976 infoStreamPrint(LOG_STDOUT, 0, "Maximum density for using non-linear sparse solver changed to %f", nonlinearSparseSolverMaxDensity);
977 }
978 if(omc_flag[FLAG_NLS_MIN_SIZE]) {
979 nonlinearSparseSolverMinSize = atoi(omc_flagValue[FLAG_NLS_MIN_SIZE]);
980 infoStreamPrint(LOG_STDOUT, 0, "Maximum system size for using non-linear sparse solver changed to %d", nonlinearSparseSolverMinSize);
981 }
982 if(omc_flag[FLAG_NEWTON_XTOL]) {
983 newtonXTol = atof(omc_flagValue[FLAG_NEWTON_XTOL]);
984 infoStreamPrint(LOG_STDOUT, 0, "Tolerance for updating solution vector in Newton solver changed to %g", newtonXTol);
985 }
986
987 if(omc_flag[FLAG_NEWTON_FTOL]) {
988 newtonFTol = atof(omc_flagValue[FLAG_NEWTON_FTOL]);
989 infoStreamPrint(LOG_STDOUT, 0, "Tolerance for accepting accuracy in Newton solver changed to %g", newtonFTol);
990 }
991
992 if(omc_flag[FLAG_NEWTON_MAX_STEP_FACTOR]) {
993 maxStepFactor = atof(omc_flagValue[FLAG_NEWTON_MAX_STEP_FACTOR]);
994 infoStreamPrint(LOG_STDOUT, 0, "Maximum step size factor for a Newton step changed to %g", newtonFTol);
995 }
996
997 if(omc_flag[FLAG_STEADY_STATE_TOL]) {
998 steadyStateTol = atof(omc_flagValue[FLAG_STEADY_STATE_TOL]);
999 infoStreamPrint(LOG_STDOUT, 0, "Tolerance for steady state detection changed to %g", steadyStateTol);
1000 }
1001
1002 if(omc_flag[FLAG_DAE_MODE]) {
1003 warningStreamPrint(LOG_STDOUT, 0, "The daeMode flag is *deprecated*, because it is not needed any more.\n"
1004 "If a model is compiled in \"DAEmode\" with compiler flag --daeMode, then it simulates automatically in DAE mode.");
1005 }
1006
1007 rt_tick(SIM_TIMER_INIT_XML13);
1008 read_input_xml(data->modelData, data->simulationInfo);
1009 data->simulationInfo->minStepSize = 4.0 * DBL_EPSILON2.2204460492503131e-16 * fmax(fabs(data->simulationInfo->startTime),fabs(data->simulationInfo->stopTime));
1010 rt_accumulate(SIM_TIMER_INIT_XML13);
1011
1012 /* Set the maximum number of threads prior to any allocation w.r.t.
1013 * linear systems and Jacobians in order to avoid memory leaks.
1014 */
1015#ifdef USE_PARJAC
1016 int num_threads = omc_get_max_threads();
1017 if (omc_flag[FLAG_JACOBIAN_THREADS]) {
1018 int num_threads_tmp = atoi(omc_flagValue[FLAG_JACOBIAN_THREADS]);
1019 infoStreamPrint(LOG_STDOUT, 0,
1020 "Number of threads passed via -jacobianThreads: %d",
1021 num_threads_tmp);
1022 if (0 >= num_threads_tmp) {
1023 warningStreamPrint(LOG_STDOUT, 0,
1024 "Number of desired OpenMP threads for parallel Jacobian evaluation is <= 0.");
1025 warningStreamPrint(LOG_STDOUT, 0, "Use omp_get_max_threads().");
1026 } else {
1027 num_threads = num_threads_tmp;
1028 }
1029 }
1030 omp_set_num_threads(num_threads);
1031
1032 infoStreamPrint(LOG_STDOUT, 0,
1033 "Number of OpenMP threads for parallel Jacobian evaluation: %d",
1034 omc_get_max_threads());
1035#else
1036 if (omc_flag[FLAG_JACOBIAN_THREADS]) {
1037 warningStreamPrint(LOG_STDOUT, 0,
1038 "Simulation flag jacobianThreads not available. Make sure you have configured omc with \"--enable-parjac\" and build with a compiler supporting OpenMP.");
1039 }
1040#endif
1041
1042 /* initialize static data of mixed/linear/non-linear system solvers */
1043 initializeMixedSystems(data, threadData);
1044 initializeLinearSystems(data, threadData);
1045 initializeNonlinearSystems(data, threadData);
1046
1047 sim_noemit = omc_flag[FLAG_NOEMIT];
1048
1049#ifndef NO_INTERACTIVE_DEPENDENCY
1050 if(omc_flag[FLAG_PORT]) {
1051 std::istringstream stream(omc_flagValue[FLAG_PORT]);
1052 int port;
1053 stream >> port;
1054 sim_communication_port_open = 1;
1055 sim_communication_port_open &= sim_communication_port.create();
1056 sim_communication_port_open &= sim_communication_port.connect("127.0.0.1", port);
1057
1058 if(0 != strcmp("ia", data->simulationInfo->outputFormat)) {
1059 communicateStatus("Starting", 0.0, data->simulationInfo->startTime, 0);
1060 }
1061 }
1062
1063 if (isXMLTCP && !sim_communication_port_open) {
1064 errorStreamPrint(LOG_STDOUT, 0, "xmltcp log format requires a TCP-port to be passed (and successfully open)");
1065 EXIT(1){fflush(__null); _exit(1);};
1066 }
1067#endif
1068 // ppriv - NO_INTERACTIVE_DEPENDENCY - for simpler debugging in Visual Studio
1069
1070 return 0;
1071}
1072
1073static DATA *SimulationRuntime_printStatus_data = NULL__null;
1074void SimulationRuntime_printStatus(int sig)
1075{
1076 DATA *data = SimulationRuntime_printStatus_data;
1077 printf("<status>\n");
1078 printf("<model>%s</model>\n", data->modelData->modelFilePrefix);
1079 printf("<phase>UNKNOWN</phase>\n");
1080 printf("<currentStepSize>%g</currentStepSize>\n", data->simulationInfo->stepSize);
1081 printf("<oldTime>%.12g</oldTime>\n", data->localData[1]->timeValue);
1082 printf("<oldTime2>%.12g</oldTime2>\n", data->localData[2]->timeValue);
1083 printf("<diffOldTime>%g</diffOldTime>\n", data->localData[1]->timeValue-data->localData[2]->timeValue);
1084 printf("<currentTime>%g</currentTime>\n", data->localData[0]->timeValue);
1085 printf("<diffCurrentTime>%g</diffCurrentTime>\n", data->localData[0]->timeValue-data->localData[1]->timeValue);
1086 printf("</status>\n");
1087}
1088
1089void communicateMsg(char id, unsigned int size, const char *data)
1090{
1091#ifndef NO_INTERACTIVE_DEPENDENCY
1092 if(sim_communication_port_open)
1093 {
1094 int msgSize = sizeof(char) + sizeof(unsigned int) + size;
1095 char* msg = new char[msgSize];
1096 memcpy(msg+0, &id, sizeof(char));
1097 memcpy(msg+sizeof(char), &size, sizeof(unsigned int));
1098 memcpy(msg+sizeof(char)+sizeof(unsigned int), data, size);
1099 sim_communication_port.sendBytes(msg, msgSize);
1100 delete[] msg;
1101 }
1102#endif
1103}
1104
1105
1106/* \brief main function for simulator
1107 *
1108 * The arguments for the main function are:
1109 * -v verbose = debug
1110 * -vf = flags set verbosity flags
1111 * -f init_file.txt use input data from init file.
1112 * -r res.plt write result to file.
1113 */
1114
1115int _main_SimulationRuntime(int argc, char**argv, DATA *data, threadData_t *threadData)
1116{
1117#if defined(__MINGW32__) || defined(_MSC_VER)
1118 /* Support for non-ASCII characters
1119 * Read the unicode command line arguments and replace the normal arguments with it.
1120 */
1121 wchar_t** wargv = CommandLineToArgvW(GetCommandLineW(), &argc);
1122 for (int i = 0; i < argc; i++) {
1123 WIDECHAR_TO_MULTIBYTE_LENGTH(wargv[i], len);
1124 WIDECHAR_TO_MULTIBYTE_VAR(wargv[i], buf, len);
1125 strcpy(argv[i], buf);
1126 MULTIBYTE_OR_WIDECHAR_VAR_FREE(buf);
1127 }
1128#endif
1129
1130 int retVal = -1;
1131 MMC_TRY_INTERNAL(globalJumpBuffer){ jmp_buf new_mmc_jumper, *old_jumper __attribute__((unused))
= threadData->globalJumpBuffer; threadData->globalJumpBuffer
= &new_mmc_jumper; if (_setjmp (new_mmc_jumper) == 0) {
1132 if (initRuntimeAndSimulation(argc, argv, data, threadData)) //initRuntimeAndSimulation returns 1 if an error occurs
1133 return 1;
1134
1135 /* sighandler_t oldhandler = different type on all platforms... */
1136#ifdef SIGUSR110
1137 SimulationRuntime_printStatus_data = data; /* Global, but at least we get something back; doesn't matter which simulation run */
1138 signal(SIGUSR110, SimulationRuntime_printStatus);
1139#endif
1140
1141 retVal = startNonInteractiveSimulation(argc, argv, data, threadData);
1142
1143 freeMixedSystems(data, threadData); /* free mixed system data */
1144 freeLinearSystems(data, threadData); /* free linear system data */
1145 freeNonlinearSystems(data, threadData); /* free nonlinear system data */
1146
1147 data->callback->callExternalObjectDestructors(data, threadData);
1148 deInitializeDataStruc(data);
1149 fflush(NULL__null);
1150 MMC_CATCH_INTERNAL(globalJumpBuffer)} threadData->globalJumpBuffer = old_jumper;mmc_catch_dummy_fn
();}
1151
1152#ifndef NO_INTERACTIVE_DEPENDENCY
1153 if(sim_communication_port_open)
1154 {
1155 sim_communication_port.close();
1156 }
1157#endif
1158
1159 return retVal;
1160}
1161
1162#if !defined(OMC_MINIMAL_RUNTIME)
1163const char* prettyPrintNanoSec(int64_t ns, int *v)
1164{
1165 if (ns > 100000000000L || ns < -100000000000L) {
1166 *v = ns / 1000000000L;
1167 return "s";
1168 } if (ns > 100000000L || ns < -100000000L) {
1169 *v = ns / 1000000L;
1170 return "ms";
1171 } else if (ns > 100000L || ns < -100000L) {
1172 *v = ns / 1000L;
1173 return "µs";
1174 } else {
1175 *v = ns;
1176 return "ns";
1177 }
1178}
1179#endif
1180
1181#ifndef NO_INTERACTIVE_DEPENDENCY
1182static std::stringstream xmlTcpStream;
1183static int numOpenTags=0;
1184
1185static void printEscapedXMLTCP(std::stringstream *s, const char *msg)
1186{
1187 while (*msg) {
1188 if (*msg == '&') {
1189 *s << "&amp;";
1190 } else if (*msg == '<') {
1191 *s << "&lt;";
1192 } else if (*msg == '>') {
1193 *s << "&gt;";
1194 } else if (*msg == '"') {
1195 *s << "&quot;";
1196 } else {
1197 *s << *msg;
1198 }
1199 msg++;
1200 }
1201}
1202
1203static inline__inline__ void sendXMLTCPIfClosed()
1204{
1205 if (numOpenTags==0) {
1206 sim_communication_port.send(xmlTcpStream.str());
1207 xmlTcpStream.str("");
1208 }
1209}
1210
1211static void messageXMLTCP(int type, int stream, int indentNext, char *msg, int subline, const int *indexes)
1212{
1213 numOpenTags++;
1214 xmlTcpStream << "<message stream=\"" << LOG_STREAM_NAME[stream] << "\" type=\"" << LOG_TYPE_DESC[type] << "\" text=\"";
1215 printEscapedXMLTCP(&xmlTcpStream, msg);
1216 if (indexes) {
1217 int i;
1218 xmlTcpStream << "\">\n";
1219 for (i=1; i<=*indexes; i++) {
1220 xmlTcpStream << "<used index=\"" << indexes[i] << "\" />\n";
1221 }
1222 if (!indentNext) {
1223 numOpenTags--;
1224 xmlTcpStream << "</message>\n";
1225 }
1226 } else {
1227 if (indentNext) {
1228 xmlTcpStream << "\">\n";
1229 } else {
1230 numOpenTags--;
1231 xmlTcpStream << "\" />\n";
1232 }
1233 }
1234 sendXMLTCPIfClosed();
1235}
1236
1237static void messageCloseXMLTCP(int stream)
1238{
1239 if (ACTIVE_STREAM(stream)(useStream[stream])) {
1240 numOpenTags--;
1241 xmlTcpStream << "</message>\n";
1242 sendXMLTCPIfClosed();
1243 }
1244}
1245
1246static void messageCloseXMLTCPWarning(int stream)
1247{
1248 if (ACTIVE_WARNING_STREAM(stream)(showAllWarnings || useStream[stream])) {
1249 numOpenTags--;
1250 xmlTcpStream << "</message>\n";
1251 sendXMLTCPIfClosed();
1252 }
1253}
1254#endif
1255
1256static void printEscapedXML(const char *msg)
1257{
1258 while (*msg) {
1259 if (*msg == '&') fputs("&amp;", stdoutstdout);
1260 else if (*msg == '<') fputs("&lt;", stdoutstdout);
1261 else if (*msg == '>') fputs("&gt;", stdoutstdout);
1262 else if (*msg == '"') fputs("&quot;", stdoutstdout);
1263 else fputc(*msg, stdoutstdout);
1264 msg++;
1265 }
1266}
1267
1268static void messageXML(int type, int stream, int indentNext, char *msg, int subline, const int *indexes)
1269{
1270 printf("<message stream=\"%s\" type=\"%s\" text=\"", LOG_STREAM_NAME[stream], LOG_TYPE_DESC[type]);
1271 printEscapedXML(msg);
1272 if (indexes) {
1273 int i;
1274 printf("\">\n");
1275 for (i=1; i<=*indexes; i++) {
1276 printf("<used index=\"%d\" />\n", indexes[i]);
1277 }
1278 if (!indentNext) {
1279 fputs("</message>\n",stdoutstdout);
1280 }
1281 } else {
1282 fputs(indentNext ? "\">\n" : "\" />\n", stdoutstdout);
1283 }
1284 fflush(stdoutstdout);
1285}
1286
1287static void messageCloseXML(int stream)
1288{
1289 if (ACTIVE_STREAM(stream)(useStream[stream])) {
1290 fputs("</message>\n", stdoutstdout);
1291 fflush(stdoutstdout);
1292 }
1293}
1294
1295static void messageCloseXMLWarning(int stream)
1296{
1297 if (ACTIVE_WARNING_STREAM(stream)(showAllWarnings || useStream[stream])) {
1298 fputs("</message>\n", stdoutstdout);
1299 fflush(stdoutstdout);
1300 }
1301}
1302
1303void setStreamPrintXML(int isXML)
1304{
1305 if (isXML==1) {
1306 messageFunction = messageXML;
1307 messageClose = messageCloseXML;
1308 messageCloseWarning = messageCloseXMLWarning;
1309#ifndef NO_INTERACTIVE_DEPENDENCY
1310 } else if (isXML==2) {
1311 messageFunction = messageXMLTCP;
1312 messageClose = messageCloseXMLTCP;
1313 messageCloseWarning = messageCloseXMLTCPWarning;
1314 isXMLTCP = 1;
1315#endif
1316 } else {
1317 /* Already set... */
1318 }
1319}
1320
1321void communicateStatus(const char *phase, double completionPercent /*0.0 to 1.0*/, double currentTime, double currentStepSize)
1322{
1323#ifndef NO_INTERACTIVE_DEPENDENCY
1324 if (sim_communication_port_open && isXMLTCP) {
1325 std::stringstream s;
1326 s << "<status phase=\"" << phase << "\" currentStepSize=\"" << currentStepSize << "\" time=\"" << currentTime << "\" progress=\"" << (int)(completionPercent*10000) << "\" />" << std::endl;
1327 std::string str(s.str());
1328 sim_communication_port.send(str);
1329 } else if (sim_communication_port_open) {
1330 std::stringstream s;
1331 s << (int)(completionPercent*10000) << " " << phase << endl;
1332 std::string str(s.str());
1333 sim_communication_port.send(str);
1334 }
1335#endif
1336}
1337
1338} // extern "C"