Bug Summary

File:OMCompiler/Compiler/runtime/./SimulationResultsCmp.c
Warning:line 467, column 11
Value stored to 'increased' is never read

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 <stdio.h>
32#include <stdlib.h>
33#include <stdint.h>
34#include <errno(*__errno_location ()).h>
35#include <string.h>
36#include <assert.h>
37
38#include "systemimpl.h"
39
40/* Size of the buffer for warnings and other messages */
41#define WARNINGBUFFSIZE4096 4096
42
43typedef struct {
44 double *data;
45 unsigned int n;
46} DataField;
47
48typedef struct {
49 char *name;
50 double data;
51 double dataref;
52 double time;
53 double timeref;
54 char interpolate;
55} DiffData;
56
57typedef struct {
58 DiffData *data;
59 unsigned int n;
60 unsigned int n_max;
61} DiffDataField;
62
63typedef enum {
64 NORM1,
65 NORM2,
66 MAX_ERR
67} ErrorMethod;
68
69#define DOUBLEEQUAL_TOTAL0.0000000001 0.0000000001
70#define DOUBLEEQUAL_REL0.00001 0.00001
71
72static SimulationResult_Globals simresglob_c = {UNKNOWN_PLOT,0};
73static SimulationResult_Globals simresglob_ref = {UNKNOWN_PLOT,0};
74
75static char ** getVars(void *vars, unsigned int* nvars)
76{
77 char **cmpvars = NULL((void*)0);
78 unsigned int ncmpvars = 0;
79 unsigned int i = 0;
80 void *v;
81
82 /* Count the number of variables in the list. */
83 for(v = vars; MMC_NILHDR(((0) << 10) + (((0) & 255) << 2)) != MMC_GETHDR(v)(*(mmc_uint_t*)((void*)((char*)(v) - 3))); v = MMC_CDR(v)(*(void**)(((void*)((void**)(((void*)((char*)(v) - 3))) + (2)
))))
) {
84 ++ncmpvars;
85 }
86
87 /* Allocate a new string array to contain the variable names. */
88 cmpvars = (char**)omc_alloc_interface.malloc(sizeof(char*)*(ncmpvars));
89
90 /* Copy the variable names from the MetaModelica list to the string array. */
91 for(; MMC_NILHDR(((0) << 10) + (((0) & 255) << 2)) != MMC_GETHDR(vars)(*(mmc_uint_t*)((void*)((char*)(vars) - 3))); vars = MMC_CDR(vars)(*(void**)(((void*)((void**)(((void*)((char*)(vars) - 3))) + (
2)))))
) {
92 cmpvars[i++] = omc_alloc_interface.malloc_strdup(MMC_STRINGDATA(MMC_CAR(vars))(((struct mmc_string*)((void*)((char*)((*(void**)(((void*)((void
**)(((void*)((char*)(vars) - 3))) + (1)))))) - 3)))->data)
);
93 }
94
95 *nvars = ncmpvars;
96 return cmpvars;
97}
98
99static DataField getData(const char *varname,const char *filename, unsigned int size, int suggestRealAll, SimulationResult_Globals* srg, int runningTestsuite)
100{
101 DataField res;
102 void *cmpvar,*dataset,*lst,*datasetBackup;
103 unsigned int i;
104 res.n = 0;
105 res.data = NULL((void*)0);
106
107 /* fprintf(stderr, "getData of Var: %s from file %s\n", varname,filename); */
108 cmpvar = mmc_mk_nil()((void*)((char*)(&(mmc_nil).header) + 3));
109 cmpvar = mmc_mk_cons(mmc_mk_scon(varname),cmpvar);
110 dataset = SimulationResultsImpl__readDataset(filename,cmpvar,size,suggestRealAll,srg,runningTestsuite);
111 if (dataset==NULL((void*)0)) {
112 /* fprintf(stderr, "getData of Var: %s failed!\n",varname); */
113 return res;
114 }
115
116 /* fprintf(stderr, "Data of Var: %s\n", varname); */
117 /* First calculate the length of the matrix */
118 datasetBackup = dataset;
119 while (MMC_NILHDR(((0) << 10) + (((0) & 255) << 2)) != MMC_GETHDR(dataset)(*(mmc_uint_t*)((void*)((char*)(dataset) - 3)))) {
120 lst = MMC_CAR(dataset)(*(void**)(((void*)((void**)(((void*)((char*)(dataset) - 3)))
+ (1)))))
;
121 while (MMC_NILHDR(((0) << 10) + (((0) & 255) << 2)) != MMC_GETHDR(lst)(*(mmc_uint_t*)((void*)((char*)(lst) - 3)))) {
122 res.n++;
123 lst = MMC_CDR(lst)(*(void**)(((void*)((void**)(((void*)((char*)(lst) - 3))) + (
2)))))
;
124 }
125 dataset = MMC_CDR(dataset)(*(void**)(((void*)((void**)(((void*)((char*)(dataset) - 3)))
+ (2)))))
;
126 }
127 if (res.n == 0) return res;
128
129 /* The allocate and read the values */
130 dataset = datasetBackup;
131 i = res.n;
132 res.data = (double*) malloc(sizeof(double)*res.n);
133 while (MMC_NILHDR(((0) << 10) + (((0) & 255) << 2)) != MMC_GETHDR(dataset)(*(mmc_uint_t*)((void*)((char*)(dataset) - 3)))) {
134 lst = MMC_CAR(dataset)(*(void**)(((void*)((void**)(((void*)((char*)(dataset) - 3)))
+ (1)))))
;
135 while (MMC_NILHDR(((0) << 10) + (((0) & 255) << 2)) != MMC_GETHDR(lst)(*(mmc_uint_t*)((void*)((char*)(lst) - 3)))) {
136 res.data[--i] = mmc_prim_get_real(MMC_CAR(lst)(*(void**)(((void*)((void**)(((void*)((char*)(lst) - 3))) + (
1)))))
);
137 lst = MMC_CDR(lst)(*(void**)(((void*)((void**)(((void*)((char*)(lst) - 3))) + (
2)))))
;
138 }
139 dataset = MMC_CDR(dataset)(*(void**)(((void*)((void**)(((void*)((char*)(dataset) - 3)))
+ (2)))))
;
140 }
141 assert(i == 0)((void) sizeof ((i == 0) ? 1 : 0), __extension__ ({ if (i == 0
) ; else __assert_fail ("i == 0", "./SimulationResultsCmp.c",
141, __extension__ __PRETTY_FUNCTION__); }))
;
142
143 /* for (i=0;i<res.n;i++)
144 fprintf(stderr, "%d: %.15g\n", i, res.data[i]); */
145
146 return res;
147}
148
149/* see http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ */
150static char almostEqualRelativeAndAbs(double a, double b, double reltol, double abstol)
151{
152 /* Check if the numbers are really close -- needed when comparing numbers near zero. */
153 double diff = fabs(a - b);
154 if (diff <= abstol) {
155 return 1;
156 }
157 if (diff <= fmax(fabs(a),fabs(b)) * reltol) {
158 return 1;
159 }
160 return 0;
161}
162
163static char almostEqualWithDefaultTolerance(double a, double b)
164{
165 return almostEqualRelativeAndAbs(a,b,DOUBLEEQUAL_REL0.00001,DOUBLEEQUAL_TOTAL0.0000000001);
166}
167
168static double deltaData(ErrorMethod errMethod, DataField *time, DataField *reftime, DataField *data, DataField *refdata)
169{
170 unsigned int i, iRef, i2;
171 double res,res0, val, valRef, t;
172 res = 0;
173 res0 = 0;
174 i = 0;
175 for (iRef=0;iRef < reftime->n;iRef++){
176 valRef = refdata->data[iRef];
177 t = reftime->data[iRef];
178 //get left and right reference point to interpolate
179 while((time->data[i] < t))
180 {
181 i++;
182 }
183 i2 = i+1;
184 //there is a result value at time t
185 if (fabs(time->data[i]-t) <= fmax((0.0001*time->data[time->n]),1e-12))
186 {
187 val = data->data[i];
188 }
189 //interpolate result value at time t
190 else
191 {
192 //printf("xl %f xr %f tl %f tr %f \n", data->data[i], data->data[i2], time->data[i], time->data[i2]);
193 val = (data->data[i2] - data->data[i])/(time->data[i2] - time->data[i])*(t - time->data[i])+data->data[i];
194 }
195 switch(errMethod){
196 case NORM1:
197 res0 += fabs(valRef-val); break;
198 case NORM2:
199 res0 += pow((valRef-val),2); break;
200 case MAX_ERR:
201 res0 = fmax(fabs(valRef-val),res0); break;
202 default:
203 res0 += fabs(valRef-val); break;
204 }
205 //fprintf(stderr, "at time %f, val: %f and valRef: %f and res %f\n",t,val,valRef, res0);
206 }
207 switch(errMethod){
208 case NORM2:
209 res = sqrt(res0); break;
210 default:
211 res = res0; break;
212 }
213 return res;
214}
215
216
217static unsigned int cmpData(int isResultCmp, char* varname, DataField *time, DataField *reftime, DataField *data, DataField *refdata, double reltol, double abstol, DiffDataField *ddf, char **cmpdiffvars, unsigned int vardiffindx, int keepEqualResults, void **diffLst, const char *prefix)
218{
219 unsigned int i,j,k,j_event;
220 double t,tr,d,dr,err,d_left,d_right,dr_left,dr_right,t_event;
221 char increased = 0;
222 char interpolate = 0;
223 char isdifferent = 0;
224 char refevent = 0;
225 double average=0;
226 FILE *fout = NULL((void*)0);
227 char *fname = NULL((void*)0);
228 if (!isResultCmp) {
229 fname = (char*) malloc(25 + strlen(prefix) + strlen(varname));
230 sprintf(fname, "%s.%s.csv", prefix, varname);
231 fout = fopen(fname,"w");
232 if (fout) {
233 fprintf(fout, "time,reference,actual,err,relerr,threshold\n");
234 }
235 }
236 for (i=0;i<refdata->n;i++){
237 average += fabs(refdata->data[i]);
238 }
239 average = average/((double)refdata->n);
240#ifdef DEBUGOUTPUT
241 fprintf(stderrstderr, "average: %.15g\n",average);
242#endif
243 average = reltol*fabs(average)+abstol;
244 j = 0;
245 tr = reftime->data[j];
246 dr = refdata->data[j];
247#ifdef DEBUGOUTPUT
248 fprintf(stderrstderr, "compare: %s\n",varname);
249#endif
250 for (i=0;i<data->n;i++){
251 t = time->data[i];
252 d = data->data[i];
253 increased = 0;
254#ifdef DEBUGOUTPUT
255 fprintf(stderrstderr, "i: %d t: %.15g d:%.15g\n",i,t,d);
256#endif
257 while(tr < t){
258 if (j +1< reftime->n) {
259 j += 1;
260 tr = reftime->data[j];
261 increased = 1;
262 if (tr == t) {
263 break;
264 }
265#ifdef DEBUGOUTPUT
266 fprintf(stderrstderr, "j: %d tr:%.15g\n",j,tr);
267#endif
268 }
269 else
270 break;
271 }
272 if (increased==1) {
273 if ( (fabs((t-tr)/tr) > reltol) || (fabs(t-tr) > fabs(t-reftime->data[j-1]))) {
274 j = j- 1;
275 tr = reftime->data[j];
276 }
277 }
278#ifdef DEBUGOUTPUT
279 fprintf(stderrstderr, "i: %d t: %.15g d:%.15g j: %d tr:%.15g\n",i,t,d,j,tr);
280#endif
281 /* events, in case of an event compare only the left and right values of the absolute event time range,
282 * this means ta_left = min(t_left,tr_left) and
283 * ta_right = max(t_right,ta_right) */
284 if(i<time->n) {
285#ifdef DEBUGOUTPUT
286 fprintf(stderrstderr, "check event: %.15g - %.15g = %.15g\n",t,time->data[i+1],fabs(t-time->data[i+1]));
287#endif
288 /* an event */
289 if (almostEqualWithDefaultTolerance(t,time->data[i+1])) {
290#ifdef DEBUGOUTPUT
291 fprintf(stderrstderr, "event: %.15g %d %.15g\n",t,i,d);
292#endif
293 /* left value */
294 d_left = d;
295#ifdef DEBUGOUTPUT
296 fprintf(stderrstderr, "left value: %.15g %d %.15g\n",t,i,d_left);
297#endif
298 /* right value */
299 if (i+1<data->n) {
300 while (almostEqualWithDefaultTolerance(t,time->data[i+1])) {
301 i +=1;
302 if (i+1>=data->n) break;
303 }
304 }
305 t = time->data[i];
306 d_right = data->data[i];
307#ifdef DEBUGOUTPUT
308 fprintf(stderrstderr, "right value: %.15g %d %.15g\n",t,i,d_right);
309#endif
310 /* search event in reference forwards */
311 refevent = 0;
312 t_event = t + t*reltol*0.1;
313 /* do not exceed next time step */
314 if (i+1<=data->n) {
315 t_event = (t_event > time->data[i])?time->data[i]:t_event;
316 }else{
317 t_event = (t_event > time->data[i+1])?time->data[i+1]:t_event;
318 }
319 j_event = j;
320 while(tr < t_event) {
321 if (j+1<reftime->n) {
322 if (almostEqualWithDefaultTolerance(tr,reftime->data[j+1])) {
323 dr_left = refdata->data[j];
324#ifdef DEBUGOUTPUT
325 fprintf(stderrstderr, "ref left value: %.15g %d %.15g\n",tr,j,dr_left);
326#endif
327 refevent = 1;
328
329 do {
330 j +=1;
331 if (j+1>=reftime->n) break;
332 } while (almostEqualWithDefaultTolerance(tr,reftime->data[j+1]));
333 }
334 }
335 if (refevent == 0) {
336 j += 1;
337 if (j >= reftime->n)
338 break;
339 tr = reftime->data[j];
340 }
341 else {
342 tr = reftime->data[j];
343 break;
344 }
345 }
346 if (refevent==1) {
347 tr = reftime->data[j];
348 dr_right = refdata->data[j];
349#ifdef DEBUGOUTPUT
350 fprintf(stderrstderr, "ref right value: %.15g %d %.15g\n",tr,j,dr_right);
351#endif
352
353 err = fabs(d_left-dr_left);
354#ifdef DEBUGOUTPUT
355 fprintf(stderrstderr, "delta:%.15g reltol:%.15g\n",err,average);
356#endif
357 if ( err < average){
358 err = fabs(d_right-dr_right);
359#ifdef DEBUGOUTPUT
360 fprintf(stderrstderr, "delta:%.15g reltol:%.15g\n",err,average);
361#endif
362 if ( err < average ) {
363 continue;
364 }
365 }
366 }
367 else {
368 /* search event in reference backwards */
369 j = j_event;
370 tr = reftime->data[j];
371 refevent = 0;
372 t_event = t - t*reltol*0.1;
373 while(tr > t_event) {
374 if (j-1>0) {
375 if (almostEqualWithDefaultTolerance(tr,reftime->data[j-1])) {
376 dr_right = refdata->data[j];
377#ifdef DEBUGOUTPUT
378 fprintf(stderrstderr, "ref right value: %.15g %d %.15g\n",tr,j,dr_right);
379#endif
380 refevent = 1;
381
382 do {
383 j -=1;
384 if (j-1<=0) break;
385 } while (almostEqualWithDefaultTolerance(tr,reftime->data[j-1]));
386 }
387 }
388 if (refevent == 0) {
389 j -= 1;
390 if (j == 0)
391 break;
392 tr = reftime->data[j];
393 }
394 else {
395 tr = reftime->data[j];
396 break;
397 }
398 }
399 if (refevent==1) {
400 tr = reftime->data[j];
401 dr_left = refdata->data[j];
402#ifdef DEBUGOUTPUT
403 fprintf(stderrstderr, "ref left value: %.15g %d %.15g\n",tr,j,dr_left);
404#endif
405 err = fabs(d_left-dr_left);
406#ifdef DEBUGOUTPUT
407 fprintf(stderrstderr, "delta:%.15g reltol:%.15g\n",err,average);
408#endif
409 if ( err < average){
410 err = fabs(d_right-dr_right);
411#ifdef DEBUGOUTPUT
412 fprintf(stderrstderr, "delta:%.15g reltol:%.15g\n",err,average);
413#endif
414 if ( err < average){
415 j = j_event;
416 tr = reftime->data[j];
417 continue;
418 }
419 }
420 }
421 j = j_event;
422 tr = reftime->data[j];
423 }
424 }
425 }
426
427 interpolate = 0;
428#ifdef DEBUGOUTPUT
429 fprintf(stderrstderr, "interpolate? %d %.15g:%.15g %.15g:%.15g\n",i,t,tr,fabs((t-tr)/tr),abstol);
430#endif
431 if (fabs(t-tr) > 0.00001) {
432 interpolate = 1;
433 }
434
435 dr = refdata->data[j];
436 if (interpolate==1){
437#ifdef DEBUGOUTPUT
438 fprintf(stderrstderr, "interpolate %.15g:%.15g %.15g:%.15g %d",t,d,tr,dr,j);
439#endif
440 unsigned int jj = j;
441 /* look for interpolation partner */
442 if (tr > t) {
443 if (j-1 > 0) {
444 jj = j-1;
445 increased = 0;
446 if (reftime->data[jj] == tr){
447 increased = 1;
448 do {
449 jj -= 1;
450 if (jj<=0) break;
451 } while (reftime->data[jj] == tr);
452 }
453 }
454#ifdef DEBUGOUTPUT
455 fprintf(stderrstderr, "-> %d %.15g %.15g\n",jj,reftime->data[jj],refdata->data[jj]);
456#endif
457 if (reftime->data[jj] != tr){
458 dr = refdata->data[jj] + ((dr-refdata->data[jj])/(tr-reftime->data[jj]))*(t-reftime->data[jj]);
459 }
460#ifdef DEBUGOUTPUT
461 fprintf(stderrstderr, "-> dr:%.15g\n",dr);
462#endif
463 }
464 else {
465 if (j+1<reftime->n) {
466 jj = j+1;
467 increased = 0;
Value stored to 'increased' is never read
468 if (reftime->data[jj] == tr){
469 increased = 1;
470 do {
471 jj += 1;
472 if (jj>=reftime->n) break;
473 } while (reftime->data[jj] == tr);
474 }
475 }
476#ifdef DEBUGOUTPUT
477 fprintf(stderrstderr, "-> %d %.15g %.15g\n",jj,reftime->data[jj],tr);
478#endif
479 if (reftime->data[jj] != tr){
480 dr = dr + ((refdata->data[jj] - dr)/(reftime->data[jj] - tr))*(t-tr);
481 }
482#ifdef DEBUGOUTPUT
483 fprintf(stderrstderr, "-> dr:%.15g\n",dr);
484#endif
485 }
486 }
487#ifdef DEBUGOUTPUT
488 fprintf(stderrstderr, "j: %d tr: %.15g dr:%.15g t:%.15g d:%.15g\n",j,tr,dr,t,d);
489#endif
490 err = fabs(d-dr);
491#ifdef DEBUGOUTPUT
492 fprintf(stderrstderr, "delta:%.15g reltol:%.15g\n",err,average);
493#endif
494 if (fout) {
495 fprintf(fout, "%.15g,%.15g,%.15g,%.15g,%.15g,%.15g\n",tr,dr,d,err,almostEqualWithDefaultTolerance(d,0) ? err/average : fabs(err/d),average);
496 }
497 if ( err > average){
498 if (j+1<reftime->n) {
499 if (reftime->data[j+1] == tr) {
500 dr = refdata->data[j+1];
501 err = fabs(d-dr);
502 }
503 }
504
505 if (err < average){
506 continue;
507 }
508
509 isdifferent = 1;
510 if (isResultCmp) { /* If we produce the full diff, this data has already been output */
511 if (ddf->n >= ddf->n_max) {
512 DiffData *newData;
513 ddf->n_max = ddf->n_max ? ddf->n_max*2 : 1024;
514 newData = (DiffData*) realloc(ddf->data, sizeof(DiffData)*(ddf->n_max));
515 if (!newData) continue; /* realloc failed... pretty bad, but let's continue */
516 ddf->data = newData;
517 }
518 ddf->data[ddf->n].name = varname;
519 ddf->data[ddf->n].data = d;
520 ddf->data[ddf->n].dataref = dr;
521 ddf->data[ddf->n].time = t;
522 ddf->data[ddf->n].timeref = tr;
523 ddf->data[ddf->n].interpolate = interpolate?'1':'0';
524 ddf->n +=1;
525 }
526 }
527 }
528 if (isdifferent) {
529 cmpdiffvars[vardiffindx] = varname;
530 vardiffindx++;
531 if (!isResultCmp) {
532 *diffLst = mmc_mk_cons(mmc_mk_scon(varname),*diffLst);
533 }
534 }
535 if (fout) {
536 fclose(fout);
537 }
538 if (!isdifferent && 0==keepEqualResults && 0==isResultCmp) {
539 SystemImpl__removeFile(fname);
540 }
541 if (fname) {
542 free(fname);
543 }
544 return vardiffindx;
545}
546
547static int writeLogFile(const char *filename,DiffDataField *ddf,const char *f,const char *reff,double reltol,double abstol)
548{
549 FILE* fout;
550 unsigned int i;
551 /* fprintf(stderr, "writeLogFile: %s\n",filename); */
552 fout = fopen(filename, "w");
553 if (!fout)
554 return -1;
555
556 fprintf(fout, "\"Generated by OpenModelica\";;;;;\n");
557 fprintf(fout, "\"Compared Files\";;;\"absolute tolerance\";%.15g;relative tolerance;%.15g\n",abstol,reltol);
558 fprintf(fout, "\"%s\";;;;;;\n",f);
559 fprintf(fout, "\"%s\";;;;;;\n",reff);
560 fprintf(fout, "\"Name\";\"Time\";\"DataPoint\";\"RefTime\";\"RefDataPoint\";\"absolute error\";\"relative error\";interpolate;\n");
561 for (i=0;i<ddf->n;i++){
562 fprintf(fout, "%s;%.15g;%.15g;%.15g;%.15g;%.15g;%.15g;%c;\n",ddf->data[i].name,ddf->data[i].time,ddf->data[i].data,ddf->data[i].timeref,ddf->data[i].dataref,
563 fabs(ddf->data[i].data-ddf->data[i].dataref),fabs((ddf->data[i].data-ddf->data[i].dataref)/ddf->data[i].dataref),ddf->data[i].interpolate);
564 }
565 fclose(fout);
566 /* fprintf(stderr, "writeLogFile: %s finished\n",filename); */
567 return 0;
568}
569
570static const char* getTimeVarName(void *vars) {
571 const char *res = "time";
572 while (MMC_NILHDR(((0) << 10) + (((0) & 255) << 2)) != MMC_GETHDR(vars)(*(mmc_uint_t*)((void*)((char*)(vars) - 3)))) {
573 char *var = MMC_STRINGDATA(MMC_CAR(vars))(((struct mmc_string*)((void*)((char*)((*(void**)(((void*)((void
**)(((void*)((char*)(vars) - 3))) + (1)))))) - 3)))->data)
;
574 if (0==strcmp("time",var)) break;
575 if (0==strcmp("Time",var)) {
576 res="Time";
577 break;
578 }
579 vars = MMC_CDR(vars)(*(void**)(((void*)((void**)(((void*)((char*)(vars) - 3))) + (
2)))))
;
580 }
581 return res;
582}
583
584#include "SimulationResultsCmpTubes.c"
585
586/* Common, huge function, for both result comparison and result diff */
587void* SimulationResultsCmp_compareResults(int isResultCmp, int runningTestsuite, const char *filename, const char *reffilename, const char *resultfilename, double reltol, double abstol, double reltolDiffMaxMin, double rangeDelta, void *vars, int keepEqualResults, int *success, int isHtml, char **htmlOut)
588{
589 char **cmpvars=NULL((void*)0);
590 char **cmpdiffvars=NULL((void*)0);
591 unsigned int vardiffindx=0;
592 unsigned int ncmpvars = 0;
593 unsigned int ngetfailedvars = 0;
594 void *allvars,*allvarsref,*res;
595 unsigned int i,size,size_ref,len,j,k;
596 char *var,*var1,*var2;
597 DataField time,timeref,data,dataref;
598 DiffDataField ddf;
599 const char *msg[2] = {"",""};
600 const char *timeVarName, *timeVarNameRef;
601 int suggestReadAll=0;
602 ddf.data=NULL((void*)0);
603 ddf.n=0;
604 ddf.n_max=0;
605 len = 1;
606 int offset, offsetRef;
607
608 /* open files */
609 /* fprintf(stderr, "Open File %s\n", filename); */
610 if (UNKNOWN_PLOT == SimulationResultsImpl__openFile(filename,&simresglob_c)) {
611 char *str = (char*) omc_alloc_interface.malloc(25+strlen(filename));
612 void *res = NULL((void*)0);
613 *str = 0;
614 strcat(strcat(str,"Error opening file: "), filename);
615 res = mmc_mk_scon(str);
616 GC_free(str);
617 return mmc_mk_cons(res,mmc_mk_nil()((void*)((char*)(&(mmc_nil).header) + 3)));
618 }
619 /* fprintf(stderr, "Open File %s\n", reffilename); */
620 if (UNKNOWN_PLOT == SimulationResultsImpl__openFile(reffilename,&simresglob_ref)) {
621 char *str = (char*) omc_alloc_interface.malloc(35+strlen(reffilename));
622 void *res = NULL((void*)0);
623 *str = 0;
624 strcat(strcat(str,"Error opening reference file: "), reffilename);
625 res = mmc_mk_scon(str);
626 GC_free(str);
627 return mmc_mk_cons(res,mmc_mk_nil()((void*)((char*)(&(mmc_nil).header) + 3)));
628 }
629
630 size = SimulationResultsImpl__readSimulationResultSize(filename,&simresglob_c);
631 /* fprintf(stderr, "Read size of File %s size= %d\n", filename,size); */
632 size_ref = SimulationResultsImpl__readSimulationResultSize(reffilename,&simresglob_ref);
633 /* fprintf(stderr, "Read size of File %s size= %d\n", reffilename,size_ref); */
634
635 /* get vars to compare */
636 cmpvars = getVars(vars,&ncmpvars);
637 /* if no var compare all vars */
638 allvars = SimulationResultsImpl__readVarsFilterAliases(filename,&simresglob_c);
639 allvarsref = SimulationResultsImpl__readVarsFilterAliases(reffilename,&simresglob_ref);
640 if (ncmpvars==0) {
641 suggestReadAll = 1;
642 cmpvars = getVars(allvarsref,&ncmpvars);
643 if (ncmpvars==0) return mmc_mk_cons(mmc_mk_scon("Error Get Vars!"),mmc_mk_nil()((void*)((char*)(&(mmc_nil).header) + 3)));
644 }
645#ifdef DEBUGOUTPUT
646 fprintf(stderrstderr, "Compare Vars:\n");
647 for(i=0;i<ncmpvars;i++)
648 fprintf(stderrstderr, "Var: %s\n", cmpvars[i]);
649#endif
650 /* get time */
651 /* fprintf(stderr, "get time\n"); */
652 timeVarName = getTimeVarName(allvars);
653 timeVarNameRef = getTimeVarName(allvarsref);
654 time = getData(timeVarName,filename,size,suggestReadAll,&simresglob_c,runningTestsuite);
655 if (time.n==0) {
656 return mmc_mk_cons(mmc_mk_scon("Error get time!"),mmc_mk_nil()((void*)((char*)(&(mmc_nil).header) + 3)));
657 }
658 /* fprintf(stderr, "get reftime\n"); */
659 timeref = getData(timeVarNameRef,reffilename,size_ref,suggestReadAll,&simresglob_ref,runningTestsuite);
660 if (timeref.n==0) {
661 return mmc_mk_cons(mmc_mk_scon("Error get ref time!"),mmc_mk_nil()((void*)((char*)(&(mmc_nil).header) + 3)));
662 }
663 cmpdiffvars = (char**)omc_alloc_interface.malloc(sizeof(char*)*(ncmpvars));
664 /* check if time is larger or less reftime */
665 res = mmc_mk_nil()((void*)((char*)(&(mmc_nil).header) + 3));
666 if (fabs(time.data[time.n-1]-timeref.data[timeref.n-1]) > reltol*fabs(timeref.data[timeref.n-1])) {
667 char buf[WARNINGBUFFSIZE4096];
668#ifdef DEBUGOUTPUT
669 fprintf(stderrstderr, "max time value=%.15g ref max time value: %.15g\n",time.data[time.n-1],timeref.data[timeref.n-1]);
670#endif
671 snprintf(buf,WARNINGBUFFSIZE4096,"Resultfile and Reference have different end time points!\n"
672 "Reffile[%d]=%f\n"
673 "File[%d]=%f\n",timeref.n,timeref.data[timeref.n-1],time.n,time.data[time.n-1]);
674 c_add_message(NULL((void*)0),-1, ErrorType_scripting, ErrorLevel_warning, buf, NULL((void*)0), 0);
675 }
676 /* calculate offsets */
677 for(offset=0; offset<time.n-1 && time.data[offset] == time.data[offset+1]; ++offset);
678 for(offsetRef=0; offsetRef<timeref.n-1 && timeref.data[offsetRef] == timeref.data[offsetRef+1]; ++offsetRef);
679 var1=NULL((void*)0);
680 var2=NULL((void*)0);
681 /* compare vars */
682 /* fprintf(stderr, "compare vars\n"); */
683 for (i=0;i<ncmpvars;i++) {
684 var = cmpvars[i];
685 len = strlen(var);
686 if (var1) {
687 free(var1);
688 var1 = NULL((void*)0);
689 }
690 var1 = (char*) omc_alloc_interface.malloc(len+10);
691 k = 0;
692 for (j=0;j<len;j++) {
693 if (var[j] !='\"' ) {
694 var1[k] = var[j];
695 k +=1;
696 }
697 }
698 var1[k] = 0;
699 /* fprintf(stderr, "compare var: %s\n",var); */
700 /* check if in ref_file */
701 dataref = getData(var1,reffilename,size_ref,suggestReadAll,&simresglob_ref,runningTestsuite);
702 if (dataref.n==0) {
703 if (dataref.data) {
704 free(dataref.data);
705 }
706 if (var1) {
707 GC_free(var1);
708 var1 = NULL((void*)0);
709 }
710 msg[0] = runningTestsuite ? SystemImpl__basename(reffilename) : reffilename;
711 msg[1] = var;
712 c_add_message(NULL((void*)0),-1, ErrorType_scripting, ErrorLevel_warning, gettext("Get data of variable %s from file %s failed!\n")dcgettext (((void*)0), "Get data of variable %s from file %s failed!\n"
, 5)
, msg, 2);
713 ngetfailedvars++;
714 continue;
715 }
716 /* check if in file */
717 data = getData(var1,filename,size,suggestReadAll,&simresglob_c,runningTestsuite);
718 if (data.n==0) {
719 if (data.data) {
720 free(data.data);
721 }
722 if (var1) {
723 GC_free(var1);
724 var1 = NULL((void*)0);
725 }
726 msg[0] = runningTestsuite ? SystemImpl__basename(filename) : filename;
727 msg[1] = var;
728 c_add_message(NULL((void*)0),-1, ErrorType_scripting, ErrorLevel_warning, gettext("Get data of variable %s from file %s failed!\n")dcgettext (((void*)0), "Get data of variable %s from file %s failed!\n"
, 5)
, msg, 2);
729 ngetfailedvars++;
730 continue;
731 }
732 /* adjust initial data points */
733 for(j=offset; j>0; j--)
734 data.data[j-1] = data.data[j];
735 for(j=offsetRef; j>0; j--)
736 dataref.data[j-1] = dataref.data[j];
737 /* compare */
738 if (isHtml) {
739 vardiffindx = cmpDataTubes(isResultCmp,var,&time,&timeref,&data,&dataref,reltol,rangeDelta,reltolDiffMaxMin,&ddf,cmpdiffvars,vardiffindx,keepEqualResults,&res,resultfilename,1,htmlOut);
740 } else if (isResultCmp) {
741 vardiffindx = cmpData(isResultCmp,var,&time,&timeref,&data,&dataref,reltol,abstol,&ddf,cmpdiffvars,vardiffindx,keepEqualResults,&res,resultfilename);
742 } else {
743 vardiffindx = cmpDataTubes(isResultCmp,var,&time,&timeref,&data,&dataref,reltol,rangeDelta,reltolDiffMaxMin,&ddf,cmpdiffvars,vardiffindx,keepEqualResults,&res,resultfilename,0,0);
744 }
745 /* free */
746 if (dataref.data) {
747 free(dataref.data);
748 }
749 if (data.data) {
750 free(data.data);
751 }
752 if (var1) {
753 GC_free(var1);
754 var1 = NULL((void*)0);
755 }
756 }
757
758 if (isResultCmp) {
759 if (writeLogFile(resultfilename,&ddf,filename,reffilename,reltol,abstol)) {
760 c_add_message(NULL((void*)0),-1, ErrorType_scripting, ErrorLevel_warning, gettext("Cannot write to the difference (.csv) file!\n")dcgettext (((void*)0), "Cannot write to the difference (.csv) file!\n"
, 5)
, msg, 0);
761 }
762
763 if ((ddf.n > 0) || (ngetfailedvars > 0) || vardiffindx > 0){
764 /* fprintf(stderr, "diff: %d\n",ddf.n); */
765 /* for (i=0;i<vardiffindx;i++)
766 fprintf(stderr, "diffVar: %s\n",cmpdiffvars[i]); */
767 for (i=0;i<vardiffindx;i++){
768 res = (void*)mmc_mk_cons(mmc_mk_scon(cmpdiffvars[i]),res);
769 }
770 res = mmc_mk_cons(mmc_mk_scon("Files not Equal!"),res);
771 c_add_message(NULL((void*)0),-1, ErrorType_scripting, ErrorLevel_warning, gettext("Files not Equal\n")dcgettext (((void*)0), "Files not Equal\n", 5), msg, 0);
772 } else {
773 res = mmc_mk_cons(mmc_mk_scon("Files Equal!"),res);
774 }
775 } else {
776 if (success) {
777 *success = ((ddf.n == 0) && (vardiffindx == 0));
778 }
779 }
780
781 // if (var1) free(var1);
782 // if (var2) free(var2);
783 if (ddf.data) free(ddf.data);
784 if (cmpvars) GC_free(cmpvars);
785 if (time.data) free(time.data);
786 if (timeref.data) free(timeref.data);
787 if (cmpdiffvars) GC_free(cmpdiffvars);
788 /* close files */
789 SimulationResultsImpl__close(&simresglob_c);
790 SimulationResultsImpl__close(&simresglob_ref);
791
792 return res;
793}
794
795
796/* Common, huge function, for both result comparison and result diff */
797double SimulationResultsCmp_deltaResults(const char *filename, const char *reffilename, const char *methodname, void *vars)
798{
799 double res = 0;
800 unsigned int i,size,size_ref, len, k, j;
801 unsigned int ncmpvars = 0;
802 void *allvars,*allvarsref;
803 char *var,*var1;
804 char **cmpvars=NULL((void*)0);
805 int suggestReadAll=0;
806 DataField time,timeref,data,dataref;
807 const char *timeVarName, *timeVarNameRef;
808 int offset, offsetRef;
809 const char *msg[2] = {"",""};
810
811 /* choose error method */
812 ErrorMethod errMethod;
813
814 if (0 == strcmp(methodname, "1norm")){
815 errMethod = NORM1;
816 }
817 else if (0 == strcmp(methodname, "2norm")){
818 errMethod = NORM2;
819 }
820 else if (0 == strcmp(methodname, "maxerr")){
821 errMethod = MAX_ERR;
822 }
823 else {
824 msg[0] = methodname;
825 c_add_message(NULL((void*)0),-1, ErrorType_scripting, ErrorLevel_warning, gettext("Unknown method string: %s. 1-Norm is chosen.")dcgettext (((void*)0), "Unknown method string: %s. 1-Norm is chosen."
, 5)
, msg, 1);
826 errMethod = NORM1;
827 }
828
829 /* open files */
830 /* fprintf(stderr, "Open File %s\n", filename); */
831
832 SimulationResultsImpl__close(&simresglob_c);
833 SimulationResultsImpl__close(&simresglob_ref);
834
835 if (UNKNOWN_PLOT == SimulationResultsImpl__openFile(filename,&simresglob_c)) {
836 msg[0] = filename;
837 c_add_message(NULL((void*)0),-1, ErrorType_scripting, ErrorLevel_error, gettext("Error opening file: %s.")dcgettext (((void*)0), "Error opening file: %s.", 5), msg, 1);
838 return -1;
839 }
840 /* fprintf(stderr, "Open File %s\n", reffilename); */
841 if (UNKNOWN_PLOT == SimulationResultsImpl__openFile(reffilename,&simresglob_ref)) {
842 msg[0] = filename;
843 c_add_message(NULL((void*)0),-1, ErrorType_scripting, ErrorLevel_error, gettext("Error opening reference file: %s.")dcgettext (((void*)0), "Error opening reference file: %s.", 5
)
, msg, 1);
844 return -1;
845 }
846
847 size = SimulationResultsImpl__readSimulationResultSize(filename,&simresglob_c);
848 /*fprintf(stderr, "Read size of File %s size= %d\n", filename,size);*/
849 size_ref = SimulationResultsImpl__readSimulationResultSize(reffilename,&simresglob_ref);
850 /*fprintf(stderr, "Read size of File %s size= %d\n", reffilename,size_ref);*/
851
852 /* get vars to compare */
853 cmpvars = getVars(vars,&ncmpvars);
854 /* if no var compare all vars */
855 allvars = SimulationResultsImpl__readVarsFilterAliases(filename,&simresglob_c);
856 allvarsref = SimulationResultsImpl__readVarsFilterAliases(reffilename,&simresglob_ref);
857 if (ncmpvars==0) {
858 suggestReadAll = 1;
859 cmpvars = getVars(allvarsref,&ncmpvars);
860 if (ncmpvars==0){
861 c_add_message(NULL((void*)0),-1, ErrorType_scripting, ErrorLevel_error, gettext("Error Getting Vars.")dcgettext (((void*)0), "Error Getting Vars.", 5), msg, 1);
862 return -1;
863 }
864 }
865 #ifdef DEBUGOUTPUT
866 fprintf(stderrstderr, "Compare Vars:\n");
867 for(i=0;i<ncmpvars;i++)
868 fprintf(stderrstderr, "Var: %s\n", cmpvars[i]);
869 #endif
870
871 /* get time */
872 /*fprintf(stderr, "get time\n");*/
873 timeVarName = getTimeVarName(allvars);
874 timeVarNameRef = getTimeVarName(allvarsref);
875 time = getData(timeVarName,filename,size,suggestReadAll,&simresglob_c,0);
876 if (time.n==0) {
877 c_add_message(NULL((void*)0),-1, ErrorType_scripting, ErrorLevel_error, gettext("Error get time!")dcgettext (((void*)0), "Error get time!", 5), msg, 0);
878 return -1;
879 }
880 /*fprintf(stderr, "get reftime\n");*/
881 timeref = getData(timeVarNameRef,reffilename,size_ref,suggestReadAll,&simresglob_ref,0);
882 if (timeref.n==0) {
883 c_add_message(NULL((void*)0),-1, ErrorType_scripting, ErrorLevel_error, gettext("Error get reference time!")dcgettext (((void*)0), "Error get reference time!", 5), msg, 0);
884 return -1;
885 }
886
887 /* check if time is larger or less reftime */
888 if (time.data[0] > timeref.data[0]) {
889 c_add_message(NULL((void*)0),-1, ErrorType_scripting, ErrorLevel_error, gettext("The result file starts before the reference file.")dcgettext (((void*)0), "The result file starts before the reference file."
, 5)
, msg, 0);
890 return -1;
891 }
892 if(time.data[time.n-1] < timeref.data[timeref.n-1]){
893 c_add_message(NULL((void*)0),-1, ErrorType_scripting, ErrorLevel_error, gettext("The result file ends before the reference file.")dcgettext (((void*)0), "The result file ends before the reference file."
, 5)
, msg, 0);
894 return -1;
895 }
896
897 /* calculate offsets */
898 for(offset=0; offset<time.n-1 && time.data[offset] == time.data[offset+1]; ++offset);
899 for(offsetRef=0; offsetRef<timeref.n-1 && timeref.data[offsetRef] == timeref.data[offsetRef+1]; ++offsetRef);
900 var1=NULL((void*)0);
901 /* compare vars */
902 /* fprintf(stderr, "compare vars\n"); */
903 for (i=0;i<ncmpvars;i++) {
904 var = cmpvars[i];
905 len = strlen(var);
906 if (var1) {
907 free(var1);
908 var1 = NULL((void*)0);
909 }
910 var1 = (char*) omc_alloc_interface.malloc(len+10);
911 k = 0;
912 for (j=0;j<len;j++) {
913 if (var[j] !='\"' ) {
914 var1[k] = var[j];
915 k +=1;
916 }
917 }
918 var1[k] = 0;
919 /* fprintf(stderr, "compare var: %s\n",var); */
920 /* check if in ref_file */
921 dataref = getData(var1,reffilename,size_ref,suggestReadAll,&simresglob_ref,0);
922 if (dataref.n==0) {
923 if (dataref.data) {
924 free(dataref.data);
925 }
926 if (var1) {
927 GC_free(var1);
928 var1 = NULL((void*)0);
929 }
930 continue;
931 }
932 /* check if in file */
933 data = getData(var1,filename,size,suggestReadAll,&simresglob_c,0);
934 if (data.n==0) {
935 if (data.data) {
936 free(data.data);
937 }
938 if (var1) {
939 GC_free(var1);
940 var1 = NULL((void*)0);
941 }
942 continue;
943 }
944 /* adjust initial data points */
945 for(j=offset; j>0; j--)
946 data.data[j-1] = data.data[j];
947 for(j=offsetRef; j>0; j--)
948 dataref.data[j-1] = dataref.data[j];
949
950 /* calulate delta */
951 res += deltaData(errMethod,&time,&timeref,&data,&dataref);
952
953 /* free */
954 if (dataref.data) {
955 free(dataref.data);
956 }
957 if (data.data) {
958 free(data.data);
959 }
960 if (var1) {
961 GC_free(var1);
962 var1 = NULL((void*)0);
963 }
964 }
965 if (cmpvars) GC_free(cmpvars);
966 if (time.data) free(time.data);
967 if (timeref.data) free(timeref.data);
968
969 /* close files */
970 SimulationResultsImpl__close(&simresglob_c);
971 SimulationResultsImpl__close(&simresglob_ref);
972 return res;
973}
974