Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 0.0% 0 / 0 / 118
Functions: 0.0% 0 / 0 / 3
Branches: 0.0% 0 / 0 / 140

OMCompiler/SimulationRuntime/c/simulation/results/simulation_result_ia.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 /*
29 * This file contains functions for sending the result of a simulation via TCP/IP.
30 *
31 * Message: [ID | SIZE | DATA]
32 * ID: 1 byte
33 * SIZE: 4 bytes
34 * DATA: SIZE bytes
35 *
36 * A message with ID=2 contains the number of Real, Integer, Boolean and String variables together with their names.
37 * A message with ID=4 contains all the values (same order as for ID=2: Real, Integer, Boolean, String).
38 * A message with ID=6 indicates that the simulation is completed.
39 */
40
41 #include "util/omc_error.h"
42 #include "simulation_result_ia.h"
43 #include "util/rtclock.h"
44
45 #include <fstream>
46 #include <iostream>
47 #include <map>
48 #include <string>
49 #include <utility>
50 #include <cstring>
51 #include <cstdlib>
52 #include <stdint.h>
53 #include <assert.h>
54 #include "../simulation_runtime.h"
55
56 typedef struct IA_DATA
57 {
58 unsigned int nReal;
59 unsigned int nInteger;
60 unsigned int nBoolean;
61 unsigned int nString;
62 } IA_DATA;
63
64 ✗ void ia_init(simulation_result *self, DATA *data, threadData_t *threadData)
65 {
66 ✗ IA_DATA *iaData = new IA_DATA;
67 ✗ self->storage = iaData;
68
69 ✗ const MODEL_DATA *mData = data->modelData;
70 int i;
71 unsigned int strLength = 0;
72 iaData->nReal = 0;
73 ✗ iaData->nInteger = 0;
74 ✗ iaData->nBoolean = 0;
75 ✗ iaData->nString = 0;
76
77 // count real vars
78 { // time
79 ✗ iaData->nReal++;
80 strLength += 5;
81 }
82 ✗ for(i=0; i<mData->nVariablesReal; i++) if(!mData->realVarsData[i].filterOutput)
83 {
84 ✗ iaData->nReal++;
85 ✗ strLength += strlen(mData->realVarsData[i].info.name) + 1;
86 }
87 ✗ for(i=0; i<mData->nAliasReal; i++) if(!mData->realAlias[i].filterOutput && data->modelData->realAlias[i].aliasType != ALIAS_TYPE_PARAMETER)
88 {
89 ✗ iaData->nReal++;
90 ✗ strLength += strlen(mData->realAlias[i].info.name) + 1;
91 }
92
93 // count integer vars
94 ✗ for(i=0; i<mData->nVariablesInteger; i++) if(!mData->integerVarsData[i].filterOutput)
95 {
96 ✗ iaData->nInteger++;
97 ✗ strLength += strlen(mData->integerVarsData[i].info.name) + 1;
98 }
99 ✗ for(i=0; i<mData->nAliasInteger; i++) if(!mData->integerAlias[i].filterOutput && data->modelData->integerAlias[i].aliasType != ALIAS_TYPE_PARAMETER)
100 {
101 ✗ iaData->nInteger++;
102 ✗ strLength += strlen(mData->integerAlias[i].info.name) + 1;
103 }
104
105 // count boolean vars
106 ✗ for(i=0; i<mData->nVariablesBoolean; i++) if(!mData->booleanVarsData[i].filterOutput)
107 {
108 ✗ iaData->nBoolean++;
109 ✗ strLength += strlen(mData->booleanVarsData[i].info.name) + 1;
110 }
111 ✗ for(i=0; i<mData->nAliasBoolean; i++) if(!mData->booleanAlias[i].filterOutput && data->modelData->booleanAlias[i].aliasType != ALIAS_TYPE_PARAMETER)
112 {
113 ✗ iaData->nBoolean++;
114 ✗ strLength += strlen(mData->booleanAlias[i].info.name) + 1;
115 }
116
117 // count string vars
118 ✗ for(i=0; i<mData->nVariablesString; i++) if(!mData->stringVarsData[i].filterOutput)
119 {
120 ✗ iaData->nString++;
121 ✗ strLength += strlen(mData->stringVarsData[i].info.name) + 1;
122 }
123 ✗ for(i=0; i<mData->nAliasString; i++) if(!mData->stringAlias[i].filterOutput && data->modelData->stringAlias[i].aliasType != ALIAS_TYPE_PARAMETER)
124 {
125 ✗ iaData->nString++;
126 ✗ strLength += strlen(mData->stringAlias[i].info.name) + 1;
127 }
128
129 ✗ unsigned int msgSIZE = 4*sizeof(unsigned int) + strLength;
130 ✗ char* msgDATA = new char[msgSIZE];
131 unsigned int offset = 0;
132
133 ✗ memcpy(msgDATA+offset, &iaData->nReal, sizeof(unsigned int)); offset += sizeof(unsigned int);
134 ✗ memcpy(msgDATA+offset, &iaData->nInteger, sizeof(unsigned int)); offset += sizeof(unsigned int);
135 ✗ memcpy(msgDATA+offset, &iaData->nBoolean, sizeof(unsigned int)); offset += sizeof(unsigned int);
136 ✗ memcpy(msgDATA+offset, &iaData->nString, sizeof(unsigned int)); offset += sizeof(unsigned int);
137
138 // real vars
139 { // time
140 ✗ memcpy(msgDATA+offset, "time", 5); offset += 5;
141 }
142 ✗ for(i=0; i<mData->nVariablesReal; i++) if(!mData->realVarsData[i].filterOutput)
143 {
144 ✗ strLength = strlen(mData->realVarsData[i].info.name) + 1;
145 ✗ memcpy(msgDATA+offset, mData->realVarsData[i].info.name, strLength); offset += strLength;
146 }
147 ✗ for(i=0; i<mData->nAliasReal; i++) if(!mData->realAlias[i].filterOutput && data->modelData->realAlias[i].aliasType != ALIAS_TYPE_PARAMETER)
148 {
149 ✗ strLength = strlen(mData->realAlias[i].info.name) + 1;
150 ✗ memcpy(msgDATA+offset, mData->realAlias[i].info.name, strLength); offset += strLength;
151 }
152
153 // integer vars
154 ✗ for(i=0; i<mData->nVariablesInteger; i++) if(!mData->integerVarsData[i].filterOutput)
155 {
156 ✗ strLength = strlen(mData->integerVarsData[i].info.name) + 1;
157 ✗ memcpy(msgDATA+offset, mData->integerVarsData[i].info.name, strLength); offset += strLength;
158 }
159 ✗ for(i=0; i<mData->nAliasInteger; i++) if(!mData->integerAlias[i].filterOutput && data->modelData->integerAlias[i].aliasType != ALIAS_TYPE_PARAMETER)
160 {
161 ✗ strLength = strlen(mData->integerAlias[i].info.name) + 1;
162 ✗ memcpy(msgDATA+offset, mData->integerAlias[i].info.name, strLength); offset += strLength;
163 }
164
165 // boolean vars
166 ✗ for(i=0; i<mData->nVariablesBoolean; i++) if(!mData->booleanVarsData[i].filterOutput)
167 {
168 ✗ strLength = strlen(mData->booleanVarsData[i].info.name) + 1;
169 ✗ memcpy(msgDATA+offset, mData->booleanVarsData[i].info.name, strLength); offset += strLength;
170 }
171 ✗ for(i=0; i<mData->nAliasBoolean; i++) if(!mData->booleanAlias[i].filterOutput && data->modelData->booleanAlias[i].aliasType != ALIAS_TYPE_PARAMETER)
172 {
173 ✗ strLength = strlen(mData->booleanAlias[i].info.name) + 1;
174 ✗ memcpy(msgDATA+offset, mData->booleanAlias[i].info.name, strLength); offset += strLength;
175 }
176
177 // string vars
178 ✗ for(i=0; i<mData->nVariablesString; i++) if(!mData->stringVarsData[i].filterOutput)
179 {
180 ✗ strLength = strlen(mData->stringVarsData[i].info.name) + 1;
181 ✗ memcpy(msgDATA+offset, mData->stringVarsData[i].info.name, strLength); offset += strLength;
182 }
183 ✗ for(i=0; i<mData->nAliasString; i++) if(!mData->stringAlias[i].filterOutput && data->modelData->stringAlias[i].aliasType != ALIAS_TYPE_PARAMETER)
184 {
185 ✗ strLength = strlen(mData->stringAlias[i].info.name) + 1;
186 ✗ memcpy(msgDATA+offset, mData->stringAlias[i].info.name, strLength); offset += strLength;
187 }
188
189 ✗ communicateMsg(2, msgSIZE, msgDATA);
190 ✗ delete[] msgDATA;
191
192 ✗ }
193
194 ✗ void ia_emit(simulation_result *self, DATA *data, threadData_t *threadData)
195 {
196 ✗ rt_tick(SIM_TIMER_OUTPUT);
197
198 int i;
199 ✗ const IA_DATA *iaData = (IA_DATA*)self->storage;
200
201 // count string length
202 unsigned int strLength = 0;
203 ✗ for(i=0; i<data->modelData->nVariablesString; i++) if(!data->modelData->stringVarsData[i].filterOutput) {
204 ✗ strLength += omc_string_len(data->localData[0]->stringVars[i]) + 1;
205 }
206 ✗ for(i=0; i<data->modelData->nAliasString; i++) if(!data->modelData->stringAlias[i].filterOutput && data->modelData->stringAlias[i].aliasType != ALIAS_TYPE_PARAMETER) {
207 ✗ strLength += omc_string_len(data->localData[0]->stringVars[data->modelData->stringAlias[i].nameID]) + 1;
208 }
209
210 ✗ unsigned int msgSIZE = iaData->nReal*sizeof(modelica_real) + iaData->nInteger*sizeof(modelica_integer) + iaData->nBoolean*sizeof(modelica_boolean) + strLength;
211 ✗ char* msgDATA = new char[msgSIZE];
212 unsigned int offset = 0;
213
214 // time
215 ✗ memcpy(msgDATA+offset, &(data->localData[0]->timeValue), sizeof(modelica_real)); offset += sizeof(modelica_real);
216 ✗ for(i=0; i<data->modelData->nVariablesReal; i++) if(!data->modelData->realVarsData[i].filterOutput)
217 {
218 ✗ memcpy(msgDATA+offset, &(data->localData[0]->realVars[i]), sizeof(modelica_real)); offset += sizeof(modelica_real);
219 }
220
221 ✗ modelica_real value = 0;
222 ✗ for(i=0; i<data->modelData->nAliasReal; i++) if(!data->modelData->realAlias[i].filterOutput && data->modelData->realAlias[i].aliasType != ALIAS_TYPE_PARAMETER)
223 {
224 ✗ if (data->modelData->realAlias[i].aliasType == ALIAS_TYPE_TIME)
225 ✗ value = (data->localData[0])->timeValue;
226 else
227 ✗ value = (data->localData[0])->realVars[data->modelData->realAlias[i].nameID];
228
229 ✗ if (data->modelData->realAlias[i].negate)
230 ✗ value *= -1.0;
231
232 ✗ memcpy(msgDATA+offset, &value, sizeof(modelica_real)); offset += sizeof(modelica_real);
233 }
234
235
236 ✗ for(i=0; i<data->modelData->nVariablesInteger; i++) if(!data->modelData->integerVarsData[i].filterOutput)
237 {
238 ✗ memcpy(msgDATA+offset, &(data->localData[0]->integerVars[i]), sizeof(modelica_integer)); offset += sizeof(modelica_integer);
239 }
240
241 ✗ modelica_integer intValue = 0;
242 ✗ for(i=0; i<data->modelData->nAliasInteger; i++) if(!data->modelData->integerAlias[i].filterOutput && data->modelData->integerAlias[i].aliasType != ALIAS_TYPE_PARAMETER)
243 {
244 ✗ if (data->modelData->integerAlias[i].negate)
245 ✗ intValue = -(data->localData[0]->integerVars[data->modelData->integerAlias[i].nameID]);
246 else
247 ✗ intValue = data->localData[0]->integerVars[data->modelData->integerAlias[i].nameID];
248
249 ✗ memcpy(msgDATA+offset, &intValue, sizeof(modelica_integer)); offset += sizeof(modelica_integer);
250 }
251
252
253 ✗ for(i=0; i<data->modelData->nVariablesBoolean; i++) if(!data->modelData->booleanVarsData[i].filterOutput)
254 {
255 ✗ memcpy(msgDATA+offset, &(data->localData[0]->booleanVars[i]), sizeof(modelica_boolean)); offset += sizeof(modelica_boolean);
256 }
257
258 modelica_boolean boolValue;
259 ✗ for(i=0; i<data->modelData->nAliasBoolean; i++) if(!data->modelData->booleanAlias[i].filterOutput && data->modelData->booleanAlias[i].aliasType != ALIAS_TYPE_PARAMETER)
260 {
261 ✗ if (data->modelData->booleanAlias[i].negate)
262 ✗ boolValue = (data->localData[0])->booleanVars[data->modelData->booleanAlias[i].nameID]==1?0:1;
263 else
264 ✗ boolValue = (data->localData[0])->booleanVars[data->modelData->booleanAlias[i].nameID];
265
266 ✗ memcpy(msgDATA+offset, &boolValue, sizeof(modelica_boolean)); offset += sizeof(modelica_boolean);
267 }
268
269
270 ✗ for(i=0; i<data->modelData->nVariablesString; i++) if(!data->modelData->stringVarsData[i].filterOutput)
271 {
272 ✗ strLength = omc_string_len((data->localData[0])->stringVars[i]) + 1;
273 ✗ memcpy(msgDATA+offset, omc_string_data((data->localData[0])->stringVars[i]), strLength); offset += strLength;
274 }
275
276 ✗ for(i=0; i<data->modelData->nAliasString; i++) if(!data->modelData->stringAlias[i].filterOutput && data->modelData->stringAlias[i].aliasType != ALIAS_TYPE_PARAMETER)
277 {
278 ✗ strLength = omc_string_len((data->localData[0])->stringVars[data->modelData->stringAlias[i].nameID]) + 1;
279 ✗ memcpy(msgDATA+offset, omc_string_data((data->localData[0])->stringVars[data->modelData->stringAlias[i].nameID]), strLength); offset += strLength;
280 }
281
282 ✗ communicateMsg(4, msgSIZE, msgDATA);
283 ✗ delete[] msgDATA;
284
285 ✗ rt_accumulate(SIM_TIMER_OUTPUT);
286 ✗ }
287
288 ✗ void ia_free(simulation_result *self, DATA *data, threadData_t *threadData)
289 {
290 ✗ rt_tick(SIM_TIMER_OUTPUT);
291
292 ✗ delete (IA_DATA*)self->storage;
293 ✗ self->storage = NULL;
294 ✗ communicateMsg(6, 0, 0);
295
296 ✗ rt_accumulate(SIM_TIMER_OUTPUT);
297 ✗ }
298