Bug Summary

File:OMCompiler/SimulationRuntime/c/./util/OldModelicaTables.c
Warning:line 798, column 3
Null pointer passed as an argument to a 'nonnull' parameter

Annotated Source Code

[?] Use j/k keys for keyboard navigation

1/*
2 * This file is part of OpenModelica.
3 *
4 * Copyright (c) 1998-2014, Open Source Modelica Consortium (OSMC),
5 * c/o Linköpings universitet, 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 THE BSD NEW LICENSE OR THE
11 * GPL VERSION 3 LICENSE OR THE OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2.
12 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
13 * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3,
14 * ACCORDING TO RECIPIENTS CHOICE.
15 *
16 * The OpenModelica software and the OSMC (Open Source Modelica Consortium)
17 * Public License (OSMC-PL) are obtained from OSMC, either from the above
18 * address, from the URLs: http://www.openmodelica.org or
19 * http://www.ida.liu.se/projects/OpenModelica, and in the OpenModelica
20 * distribution. GNU version 3 is obtained from:
21 * http://www.gnu.org/copyleft/gpl.html. The New BSD License is obtained from:
22 * http://www.opensource.org/licenses/BSD-3-Clause.
23 *
24 * This program is distributed WITHOUT ANY WARRANTY; without even the implied
25 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, EXCEPT AS
26 * EXPRESSLY SET FORTH IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE
27 * CONDITIONS OF OSMC-PL.
28 *
29 */
30
31#include <stdio.h>
32#include <string.h>
33#include <stdlib.h>
34#include <math.h>
35#include <ctype.h>
36
37#include "../omc_inline.h"
38#include "../ModelicaUtilities.h"
39#ifdef _MSC_VER
40#include "omc_msvc.h"
41#endif
42
43/* Definition to get some Debug information if interface is called */
44/* #define INFOS */
45
46/* Definition to make a copy of the arrays */
47#define COPY_ARRAYS
48
49typedef struct InterpolationTable
50{
51 char *filename;
52 char *tablename;
53 char own_data;
54 double* data;
55 size_t rows;
56 size_t cols;
57 char colWise;
58 int ipoType;
59 int expoType;
60 double startTime;
61} InterpolationTable;
62
63typedef struct InterpolationTable2D
64{
65 char *filename;
66 char *tablename;
67 char own_data;
68 double *data;
69 size_t rows;
70 size_t cols;
71
72 char colWise;
73 int ipoType;
74 int expoType;
75} InterpolationTable2D;
76
77static InterpolationTable** interpolationTables=NULL((void*)0);
78static int ninterpolationTables=0;
79static InterpolationTable2D** interpolationTables2D=NULL((void*)0);
80static int ninterpolationTables2D=0;
81
82static InterpolationTable *InterpolationTable_init(double time,double startTime, int ipoType, int expoType,
83 const char* tableName, const char* fileName,
84 const double *table,
85 int tableDim1, int tableDim2,int colWise);
86/* InterpolationTable *InterpolationTable_Copy(InterpolationTable *orig); */
87static void InterpolationTable_deinit(InterpolationTable *tpl);
88static double InterpolationTable_interpolate(InterpolationTable *tpl, double time, size_t col);
89static double InterpolationTable_maxTime(InterpolationTable *tpl);
90static double InterpolationTable_minTime(InterpolationTable *tpl);
91static char InterpolationTable_compare(InterpolationTable *tpl, const char* fname, const char* tname, const double* table);
92
93static double InterpolationTable_extrapolate(InterpolationTable *tpl, double time, size_t col, char beforeData);
94static inline__inline__ double InterpolationTable_interpolateLin(InterpolationTable *tpl, double time, size_t i, size_t j);
95static inline__inline__ double InterpolationTable_interpolateSpline(InterpolationTable *tpl, double time, size_t i, size_t j);
96static inline__inline__ const double InterpolationTable_getElt(InterpolationTable *tpl, size_t row, size_t col);
97static void InterpolationTable_checkValidityOfData(InterpolationTable *tpl);
98
99
100static InterpolationTable2D *InterpolationTable2D_init(int ipoType, const char* tableName,
101 const char* fileName, const double *table,
102 int tableDim1, int tableDim2, int colWise);
103static void InterpolationTable2D_deinit(InterpolationTable2D *table);
104static double InterpolationTable2D_interpolate(InterpolationTable2D *tpl, double x1, double x2);
105static char InterpolationTable2D_compare(InterpolationTable2D *tpl, const char* fname, const char* tname, const double* table);
106static double InterpolationTable2D_linInterpolate(double x, double x_1, double x_2, double f_1, double f_2);
107static const double InterpolationTable2D_getElt(InterpolationTable2D *tpl, size_t row, size_t col);
108static void InterpolationTable2D_checkValidityOfData(InterpolationTable2D *tpl);
109
110
111
112/* Initialize table.
113 * timeIn - time
114 * startTime - time-Offset for the signal.
115 * ipoType - type of interpolation.
116 * 0 = linear interpolation,
117 * 1 = smooth interpolation with akima splines s.t der(y) is continuous
118 * expoType - extrapolation type
119 * 0 = hold first/last value outside the range
120 * 1 = extrapolate outside the rang using last/first two values
121 * 2 = periodically repeat table data
122 * tableName - name of table
123 * table - matrix with table data
124 * tableDim1 - number of rows of table
125 * tableDim2 - number of columns of table.
126 * colWise - 0 = column major order
127 * 1 = row major order
128 */
129
130
131int omcTableTimeIni(double timeIn, double startTime,int ipoType,int expoType,
132 const char *tableName, const char* fileName,
133 const double *table,int tableDim1, int tableDim2,int colWise)
134{
135 int i = 0;
136 InterpolationTable** tmp = NULL((void*)0);
137#ifdef INFOS
138 INFO10("Init Table \n timeIn %f \n startTime %f \n ipoType %d \n expoType %d \n tableName %s \n fileName %s \n table %p \n tableDim1 %d \n tableDim2 %d \n colWise %d", timeIn, startTime, ipoType, expoType, tableName, fileName, table, tableDim1, tableDim2, colWise);
139#endif
140 /* if table is already initialized, find it */
141 for(i = 0; i < ninterpolationTables; ++i)
142 if(InterpolationTable_compare(interpolationTables[i],fileName,tableName,table))
143 {
144#ifdef INFOS
145 infoStreamPrint("Table id = %d",i);
146#endif
147 return i;
148 }
149#ifdef INFOS
150 infoStreamPrint("Table id = %d",ninterpolationTables);
151#endif
152 /* increase array */
153 tmp = (InterpolationTable**)malloc((ninterpolationTables+1)*sizeof(InterpolationTable*));
154 if (!tmp) {
155 ModelicaFormatError("Not enough memory for new Table[%lu] Tablename %s Filename %s", (unsigned long)ninterpolationTables, tableName, fileName);
156 }
157 for(i = 0; i < ninterpolationTables; ++i)
158 {
159 tmp[i] = interpolationTables[i];
160 }
161 free(interpolationTables);
162 interpolationTables = tmp;
163 ninterpolationTables++;
164 /* otherwise initialize new table */
165 interpolationTables[ninterpolationTables-1] = InterpolationTable_init(timeIn,startTime,
166 ipoType,expoType,
167 tableName, fileName,
168 table, tableDim1,
169 tableDim2, colWise);
170 return (ninterpolationTables-1);
171}
172
173
174void omcTableTimeIpoClose(int tableID)
175{
176#ifdef INFOS
177 infoStreamPrint("Close Table[%d]",tableID);
178#endif
179 if(tableID >= 0 && tableID < (int)ninterpolationTables)
180 {
181 InterpolationTable_deinit(interpolationTables[tableID]);
182 interpolationTables[tableID] = NULL((void*)0);
183 ninterpolationTables--;
184 }
185 if(ninterpolationTables <=0)
186 free(interpolationTables);
187}
188
189
190double omcTableTimeIpo(int tableID, int icol, double timeIn)
191{
192#ifdef INFOS
193 infoStreamPrint("Interpolate Table[%d][%d] add Time %f",tableID,icol,timeIn);
194#endif
195 if(tableID >= 0 && tableID < (int)ninterpolationTables)
196 {
197 return InterpolationTable_interpolate(interpolationTables[tableID],timeIn,icol-1);
198 }
199 else
200 return 0.0;
201}
202
203
204double omcTableTimeTmax(int tableID)
205{
206#ifdef INFOS
207 infoStreamPrint("Time max from Table[%d]",tableID);
208#endif
209 if(tableID >= 0 && tableID < (int)ninterpolationTables)
210 return InterpolationTable_maxTime(interpolationTables[tableID]);
211 else
212 return 0.0;
213}
214
215
216double omcTableTimeTmin(int tableID)
217{
218#ifdef INFOS
219 infoStreamPrint("Time min from Table[%d]",tableID);
220#endif
221 if(tableID >= 0 && tableID < (int)ninterpolationTables)
222 return InterpolationTable_minTime(interpolationTables[tableID]);
223 else
224 return 0.0;
225}
226
227
228int omcTable2DIni(int ipoType, const char *tableName, const char* fileName,
229 const double *table,int tableDim1,int tableDim2,int colWise)
230{
231 int i=0;
232 InterpolationTable2D** tmp = NULL((void*)0);
233#ifdef INFOS
234 infoStreamPrint("Init Table \n ipoType %f \n tableName %f \n fileName %d \n table %p \n tableDim1 %d \n tableDim2 %d \n colWise %d", ipoType, tableName, fileName, table, tableDim1, tableDim2, colWise);
235#endif
236 /* if table is already initialized, find it */
237 for(i = 0; i < ninterpolationTables2D; ++i)
238 if(InterpolationTable2D_compare(interpolationTables2D[i],fileName,tableName,table))
239 {
240#ifdef INFOS
241 infoStreamPrint("Table id = %d",i);
242#endif
243 return i;
244 }
245#ifdef INFOS
246 infoStreamPrint("Table id = %d",ninterpolationTables2D);
247#endif
248 /* increase array */
249 tmp = (InterpolationTable2D**)malloc((ninterpolationTables2D+1)*sizeof(InterpolationTable2D*));
250 if (!tmp) {
251 ModelicaFormatError("Not enough memory for new Table[%lu] Tablename %s Filename %s", (unsigned long)ninterpolationTables, tableName, fileName);
252 }
253 for(i = 0; i < ninterpolationTables2D; ++i)
254 {
255 tmp[i] = interpolationTables2D[i];
256 }
257 free(interpolationTables2D);
258 interpolationTables2D = tmp;
259 ninterpolationTables2D++;
260 /* otherwise initialize new table */
261 interpolationTables2D[ninterpolationTables2D-1] = InterpolationTable2D_init(ipoType,tableName,
262 fileName,table,tableDim1,tableDim2,colWise);
263 return (ninterpolationTables2D-1);
264}
265
266
267void omcTable2DIpoClose(int tableID)
268{
269#ifdef INFOS
270 infoStreamPrint("Close Table[%d]",tableID);
271#endif
272 if(tableID >= 0 && tableID < (int)ninterpolationTables2D)
273 {
274 InterpolationTable2D_deinit(interpolationTables2D[tableID]);
275 interpolationTables2D[tableID] = NULL((void*)0);
276 ninterpolationTables2D--;
277 }
278 if(ninterpolationTables2D <=0)
279 free(interpolationTables2D);
280}
281
282
283double omcTable2DIpo(int tableID,double u1_, double u2_)
284{
285#ifdef INFOS
286 infoStreamPrint("Interpolate Table[%d][%d] add Time %f",tableID,u1_,u2_);
287#endif
288 if(tableID >= 0 && tableID < (int)ninterpolationTables2D)
289 return InterpolationTable2D_interpolate(interpolationTables2D[tableID], u1_, u2_);
290 else
291 return 0.0;
292}
293
294/* ******************************
295 *** IMPLEMENTATION ***
296 ******************************
297*/
298
299static void openFile(const char *filename, const char* tableName, size_t *rows, size_t *cols, double **data);
300
301
302/* \brief Read data from text file.
303
304 Text file format:
305 #1
306 double A(2,2) # comment here
307 1 0
308 0 1
309 double M(3,3) # comment
310 1 2 3
311 3 4 5
312 1 1 1
313*/
314
315typedef struct TEXT_FILE
316{
317 FILE *fp;
318 size_t line;
319 size_t cpos;
320 fpos_t *lnStart;
321 char *filename;
322} TEXT_FILE;
323
324static TEXT_FILE *Text_open(const char *filename)
325{
326 TEXT_FILE *f=(TEXT_FILE*)calloc(1,sizeof(TEXT_FILE));
327 if (!f) {
328 ModelicaFormatError("Not enough memory for Filename: %s",filename);
329 }
330 else
331 {
332 size_t l = strlen(filename);
333 f->filename = (char*)malloc((l+1)*sizeof(char));
334 if (!f->filename) {
335 ModelicaFormatError("Not enough memory for Filename: %s",filename);
336 }
337 else
338 {
339 size_t i;
340 for(i=0;i<=l;i++) {
341 f->filename[i] = filename[i];
342 }
343 f->fp = fopen(filename,"r");
344 if (!f->fp) {
345 ModelicaFormatError("Cannot open File %s",filename);
346 }
347 }
348 }
349 return f;
350}
351
352static void Text_close(TEXT_FILE *f)
353{
354 if(f)
355 {
356 if(f->filename)
357 free(f->filename);
358 fclose(f->fp);
359 free(f);
360 }
361}
362
363static void trim(const char **ptr, size_t *len)
364{
365 for(; *len > 0; ++(*ptr), --(*len))
366 if(!isspace(*(*ptr))((*__ctype_b_loc ())[(int) ((*(*ptr)))] & (unsigned short
int) _ISspace)
) return;
367}
368
369static char readChr(const char **ptr, size_t *len, char chr)
370{
371 trim(ptr,len);
372 if((*len)-- > 0 && *((*ptr)++) != chr)
373 return 0;
374 trim(ptr,len);
375 return 1;
376}
377
378static char parseHead(TEXT_FILE *f, const char* hdr, size_t hdrLen, const char **name,
379 size_t *rows, size_t *cols)
380{
381 char* endptr;
382 size_t hLen = hdrLen;
383 size_t len = 0;
384
385 trim(&hdr, &hLen);
386
387 if(strncmp("double", hdr, fmin((size_t)6, hLen)) != 0)
388 return 0;
389 hdr += 6;
390 hLen -= 6;
391 trim(&hdr, &hLen);
392
393 for(len = 1; len < hLen; ++len)
394 if(isspace(hdr[len])((*__ctype_b_loc ())[(int) ((hdr[len]))] & (unsigned short
int) _ISspace)
|| hdr[len] == '(')
395 {
396 *name = hdr;
397 hdr += len;
398 hLen -= len;
399 break;
400 }
401 if(!readChr(&hdr, &hLen, '('))
402 {
403 fclose(f->fp);
404 ModelicaFormatError("In file `%s': parsing error at line %lu and col %lu.", f->filename, (unsigned long)f->line, (unsigned long)(hdrLen-hLen));
405 }
406 *rows = (size_t)strtol(hdr, &endptr, 10);
407 if(hdr == endptr)
408 {
409 fclose(f->fp);
410 ModelicaFormatError("In file `%s': parsing error at line %lu and col %lu.", f->filename, (unsigned long)f->line, (unsigned long)(hdrLen-hLen));
411 }
412 hLen -= endptr-hdr;
413 hdr = endptr;
414 if(!readChr(&hdr, &hLen, ','))
415 {
416 fclose(f->fp);
417 ModelicaFormatError("In file `%s': parsing error at line %lu and col %lu.", f->filename, (unsigned long)f->line, (unsigned long)(hdrLen-hLen));
418 }
419 *cols = (size_t)strtol(hdr, &endptr, 10);
420 if(hdr == endptr)
421 {
422 fclose(f->fp);
423 ModelicaFormatError("In file `%s': parsing error at line %lu and col %lu.", f->filename, (unsigned long)f->line, (unsigned long)(hdrLen-hLen));
424 }
425 hLen -= endptr-hdr;
426 hdr = endptr;
427 readChr(&hdr, &hLen, ')');
428
429 if((hLen > 0) && ((*hdr) != '#'))
430 {
431 fclose(f->fp);
432 ModelicaFormatError("In file `%s': parsing error at line %lu and col %lu.", f->filename, (unsigned long)f->line, (unsigned long)(hdrLen-hLen));
433 }
434
435 return 1;
436}
437
438static size_t Text_readLine(TEXT_FILE *f, char **data, size_t *size)
439__attribute__((nonnull));
440
441static size_t Text_readLine(TEXT_FILE *f, char **data, size_t *size)
442{
443 size_t col = 0;
444 size_t i = 0;
445 char *buf = *data;
446 memset(*data, 0, sizeof(char)*(*size));
447
448 /* read whole line */
449 while(!feof(f->fp))
450 {
451 int ch;
452 if(col >= *size)
453 {
454 size_t s = *size * 2 + 1024;
455 char *tmp = (char*)calloc(s, sizeof(char));
456 if (!tmp) {
457 ModelicaFormatError("Not enough memory for loading file %s",f->filename);
458 }
459 for(i = 0; i < *size; i++)
460 tmp[i] = buf[i];
461 if(buf)
462 free(buf);
463 *data = tmp;
464 buf = *data;
465 *size = s;
466 }
467 ch = fgetc(f->fp);
468 if(ferror(f->fp))
469 {
470 fclose(f->fp);
471 ModelicaFormatError("In file `%s': parsing error at line %lu and col %lu.", f->filename, (unsigned long)f->line, (unsigned long)col);
472 }
473 if(ch == '\n')
474 break;
475 buf[col] = ch;
476 col++;
477 }
478 return col;
479}
480
481static char Text_findTable(TEXT_FILE *f, const char* tableName, size_t *cols, size_t *rows)
482{
483 char *strLn=0;
484 const char *tblName=0;
485 size_t buflen=0;
486 size_t _cols = 0;
487 size_t _rows = 0;
488
489 while(!feof(f->fp))
490 {
491 size_t col;
492 /* start new line, update counters */
493 ++f->line;
494 /* read whole line */
495 col = Text_readLine(f,&strLn,&buflen);
496 /* check if we read header */
497 if(parseHead(f,strLn,col,&tblName,&_rows,&_cols))
498 {
499 /* is table name the one we are looking for? */
500 if(strncmp(tblName,tableName,strlen(tableName))==0)
501 {
502 *cols = _cols;
503 *rows = _rows;
504 if(strLn)
505 free(strLn);
506 return 1;
507 }
508 }
509 }
510 /* no header found */
511 if(strLn)
512 free(strLn);
513 return 0;
514}
515
516static void Text_readTable(TEXT_FILE *f, double *buf, size_t rows, size_t cols)
517{
518 size_t i = 0;
519 size_t j = 0;
520 char *strLn=0;
521 size_t buflen=0;
522 char *entp = 0;
523 for(i = 0; i < rows; ++i)
524 {
525 size_t sl;
526 char *number;
527 ++f->line;
528 sl = Text_readLine(f,&strLn,&buflen);
529 number = strLn;
530 for(j = 0; j < cols; ++j)
531 {
532 /* remove sufix whitespaces */
533 buf[i*cols+j] = strtod(number,&entp);
534 /* move to next number */
535 number = entp;
536 }
537 }
538 if(strLn)
539 free(strLn);
540
541}
542
543/*
544 Mat File implementation
545*/
546typedef struct {
547 long type;
548 long mrows;
549 long ncols;
550 long imagf;
551 long namelen;
552} hdr_t;
553
554typedef struct MAT_FILE
555{
556 FILE *fp;
557 hdr_t hdr;
558 char *filename;
559} MAT_FILE;
560
561static MAT_FILE *Mat_open(const char *filename)
562{
563 size_t l,i;
564 MAT_FILE *f=(MAT_FILE*)calloc(1,sizeof(MAT_FILE));
565 if (!f) {
566 ModelicaFormatError("Not enough memory for Filename %s",filename);
567 }
568 memset(&(f->hdr),0,sizeof(hdr_t));
569 l = strlen(filename);
570 f->filename = (char*)malloc((l+1)*sizeof(char));
571 if (!f->filename) {
572 ModelicaFormatError("Not enough memory for Filename %s",filename);
573 }
574 for(i=0;i<=l;i++)
575 {
576 f->filename[i] = filename[i];
577 }
578 f->fp = fopen(filename,"rb");
579 if (!f->fp) {
580 ModelicaFormatError("Cannot open File %s",filename);
581 }
582 return f;
583}
584
585static void Mat_close(MAT_FILE *f)
586{
587 if(f)
588 {
589 if(f->filename)
590 free(f->filename);
591 fclose(f->fp);
592 free(f);
593 }
594}
595
596static size_t Mat_getTypeSize(MAT_FILE *f, long type)
597{
598 switch((type%1000)/100) {
599 case 0:
600 return sizeof(double);
601 case 1:
602 return sizeof(float);
603 case 2:
604 return 4;
605 case 3:
606 case 4:
607 return 2;
608 case 5:
609 return 1;
610 default:
611 fclose(f->fp);
612 ModelicaFormatError("Corrupted MAT-file: `%s'",f->filename);
613 return 0; /* Cannot reach this */
614 }
615}
616
617static char Mat_findTable(MAT_FILE *f, const char* tableName, size_t *cols, size_t *rows)
618{
619 char name[256];
620 while(!feof(f->fp))
621 {
622 long pos;
623
624 char * returnTmp = fgets((char*)&f->hdr,sizeof(hdr_t),f->fp);
625 if(ferror(f->fp))
626 {
627 fclose(f->fp);
628 ModelicaFormatError("Could not read from file `%s'.",f->filename);
629 }
630 returnTmp = fgets(name,fmin(f->hdr.namelen,(long)256),f->fp);
631 if(strncmp(tableName,name,strlen(tableName)) == 0)
632 {
633 if(f->hdr.type%10 != 0 || f->hdr.type/1000 > 1)
634 {
635 fclose(f->fp);
636 ModelicaFormatError("Table `%s' not in supported format.",tableName);
637 }
638 if(f->hdr.mrows <= 0 || f->hdr.ncols <= 0)
639 {
640 fclose(f->fp);
641 ModelicaFormatError("Table `%s' has zero dimensions.",tableName);
642 }
643 if(f->hdr.mrows <= 0 || f->hdr.ncols <= 0)
644 {
645 fclose(f->fp);
646 ModelicaFormatError("Table `%s' has zero dimensions [%lu,%lu].", tableName, (unsigned long)f->hdr.mrows, (unsigned long)f->hdr.ncols);
647 }
648 *rows = f->hdr.mrows;
649 *cols = f->hdr.ncols;
650 return 1;
651 }
652 pos = ftell(f->fp);
653 fseek(f->fp,f->hdr.mrows*f->hdr.ncols*Mat_getTypeSize(f,f->hdr.type)*(f->hdr.imagf?2:1),pos);
654 }
655 return 0;
656}
657
658typedef union {
659 char p[8];
660 double d;
661 float f;
662 int i;
663 short s;
664 unsigned short us;
665 unsigned char c;
666} elem_t;
667
668inline__inline__ static char getEndianness()
669{
670 const int endian_test = 1;
671 return ((*(char*)&endian_test) == 0);
672}
673
674#define correctEndianness(stype,type)__inline__ static type correctEndianness_stype (type _num, char
dataEndianness) { typedef union { type num; unsigned char b[
sizeof(type)]; } elem_u_stype; elem_u_stype dat1, dat2; if(getEndianness
() != dataEndianness) { size_t i; dat1.num = _num; for(i=0; i
< sizeof(type); ++i) dat2.b[i] = dat1.b[sizeof(type)-i-1]
; return dat2.num; } return _num; }
inline__inline__ static type correctEndianness_ ## stype (type _num, char dataEndianness) \
675{ \
676 typedef union \
677 { \
678 type num; \
679 unsigned char b[sizeof(type)]; \
680 } elem_u_ ## stype; \
681 elem_u_ ## stype dat1, dat2; \
682 if(getEndianness() != dataEndianness) \
683 { \
684 size_t i; \
685 dat1.num = _num; \
686 for(i=0; i < sizeof(type); ++i) \
687 dat2.b[i] = dat1.b[sizeof(type)-i-1]; \
688 return dat2.num; \
689 } \
690 return _num; \
691} \
692
693correctEndianness(d,double)__inline__ static double correctEndianness_d (double _num, char
dataEndianness) { typedef union { double num; unsigned char b
[sizeof(double)]; } elem_u_d; elem_u_d dat1, dat2; if(getEndianness
() != dataEndianness) { size_t i; dat1.num = _num; for(i=0; i
< sizeof(double); ++i) dat2.b[i] = dat1.b[sizeof(double)-
i-1]; return dat2.num; } return _num; }
694correctEndianness(f,float)__inline__ static float correctEndianness_f (float _num, char
dataEndianness) { typedef union { float num; unsigned char b
[sizeof(float)]; } elem_u_f; elem_u_f dat1, dat2; if(getEndianness
() != dataEndianness) { size_t i; dat1.num = _num; for(i=0; i
< sizeof(float); ++i) dat2.b[i] = dat1.b[sizeof(float)-i-
1]; return dat2.num; } return _num; }
695correctEndianness(i,int)__inline__ static int correctEndianness_i (int _num, char dataEndianness
) { typedef union { int num; unsigned char b[sizeof(int)]; } elem_u_i
; elem_u_i dat1, dat2; if(getEndianness() != dataEndianness) {
size_t i; dat1.num = _num; for(i=0; i < sizeof(int); ++i)
dat2.b[i] = dat1.b[sizeof(int)-i-1]; return dat2.num; } return
_num; }
696correctEndianness(s,short)__inline__ static short correctEndianness_s (short _num, char
dataEndianness) { typedef union { short num; unsigned char b
[sizeof(short)]; } elem_u_s; elem_u_s dat1, dat2; if(getEndianness
() != dataEndianness) { size_t i; dat1.num = _num; for(i=0; i
< sizeof(short); ++i) dat2.b[i] = dat1.b[sizeof(short)-i-
1]; return dat2.num; } return _num; }
697correctEndianness(us,unsigned short)__inline__ static unsigned short correctEndianness_us (unsigned
short _num, char dataEndianness) { typedef union { unsigned short
num; unsigned char b[sizeof(unsigned short)]; } elem_u_us; elem_u_us
dat1, dat2; if(getEndianness() != dataEndianness) { size_t i
; dat1.num = _num; for(i=0; i < sizeof(unsigned short); ++
i) dat2.b[i] = dat1.b[sizeof(unsigned short)-i-1]; return dat2
.num; } return _num; }
698correctEndianness(c,unsigned char)__inline__ static unsigned char correctEndianness_c (unsigned
char _num, char dataEndianness) { typedef union { unsigned char
num; unsigned char b[sizeof(unsigned char)]; } elem_u_c; elem_u_c
dat1, dat2; if(getEndianness() != dataEndianness) { size_t i
; dat1.num = _num; for(i=0; i < sizeof(unsigned char); ++i
) dat2.b[i] = dat1.b[sizeof(unsigned char)-i-1]; return dat2.
num; } return _num; }
699
700
701
702
703static double Mat_getElem(elem_t *num, char type, char dataEndianness)
704{
705 switch(type) {
706 case 0:
707 return correctEndianness_d(num->d,dataEndianness);
708 case 1:
709 return correctEndianness_f(num->f,dataEndianness);
710 case 2:
711 return correctEndianness_i(num->i,dataEndianness);
712 case 3:
713 return correctEndianness_s(num->s,dataEndianness);
714 case 4:
715 return correctEndianness_us(num->us,dataEndianness);
716 default:
717 return correctEndianness_c(num->c,dataEndianness);
718 }
719}
720
721static void Mat_readTable(MAT_FILE *f, double *buf, size_t rows, size_t cols)
722{
723 elem_t readbuf;
724 size_t i=0;
725 size_t j=0;
726 long P = (f->hdr.type%1000)/100;
727 char isBigEndian = (f->hdr.type/1000) == 1;
728 size_t elemSize = Mat_getTypeSize(f,f->hdr.type);
729
730 for(i=0; i < rows; ++i)
731 for(j=0; j < cols; ++j)
732 {
733 char * returnTmp = fgets(readbuf.p,elemSize,f->fp);
734 if(ferror(f->fp))
735 {
736 fclose(f->fp);
737 ModelicaFormatError("Could not read from file `%s'.",f->filename);
738 }
739 buf[i*cols+j] = Mat_getElem(&readbuf,(char)P,isBigEndian);
740 }
741}
742
743/*
744 CSV File implementation
745*/
746typedef struct CSV_FILE
747{
748 FILE *fp;
749 char *filename;
750 long int data;
751 size_t line;
752} CSV_FILE;
753
754static CSV_FILE *csv_open(const char *filename)
755{
756 CSV_FILE *f=(CSV_FILE*)calloc(1,sizeof(CSV_FILE));
757 if (!f) {
758 ModelicaFormatError("Not enough memory for Filename %s",filename);
759 }
760 else
761 {
762 size_t l = strlen(filename);
763 f->filename = (char*)malloc((l+1)*sizeof(char));
764 if (!f->filename) {
765 ModelicaFormatError("Not enough memory for Filename %s",filename);
766 }
767 else
768 {
769 size_t i;
770 for(i=0;i<=l;i++) {
771 f->filename[i] = filename[i];
772 }
773 f->fp = fopen(filename,"r");
774 if (!f->fp) {
775 ModelicaFormatError("Cannot open File %s",filename);
776 }
777 }
778 }
779 return f;
780}
781
782static void csv_close(CSV_FILE *f)
783{
784 if(f)
785 {
786 if(f->filename)
787 free(f->filename);
788 fclose(f->fp);
789 free(f);
790 }
791}
792
793static size_t csv_readLine(CSV_FILE *f, char **data, size_t *size)
794{
795 size_t col = 0;
796 size_t i = 0;
797 char *buf = *data;
798 memset(*data, 0, sizeof(char)*(*size));
5
Null pointer passed as an argument to a 'nonnull' parameter
799
800 /* read whole line */
801 while(!feof(f->fp))
802 {
803 int ch;
804 if(col >= *size)
805 {
806 size_t s = *size * 2 + 1024;
807 char *tmp = (char*)calloc(s, sizeof(char));
808 if (!tmp) {
809 ModelicaFormatError("Not enough memory for loading file %s",f->filename);
810 }
811 for(i = 0; i < *size; i++)
812 tmp[i] = buf[i];
813 if(buf)
814 free(buf);
815 *data = tmp;
816 buf = *data;
817 *size = s;
818 }
819 ch = fgetc(f->fp);
820 if(ferror(f->fp))
821 {
822 fclose(f->fp);
823 ModelicaFormatError("In file `%s': parsing error at line %lu and col %lu.", f->filename, (unsigned long)f->line, (unsigned long)col);
824 }
825 if(ch == '\n')
826 break;
827 buf[col] = ch;
828 col++;
829 }
830 return col;
831}
832
833static char csv_findTable(CSV_FILE *f, const char *tableName, size_t *cols, size_t *rows)
834{
835 char *strLn=0;
836 size_t buflen=0;
837 size_t i=0;
838 size_t _cols = 1;
839 char stop=0;
840 *cols=0;
841 *rows=0;
842 while(!feof(f->fp))
843 {
844 size_t col;
845 /* start new line, update counters */
846 ++f->line;
847 /* read whole line */
848 col = csv_readLine(f,&strLn,&buflen);
849
850 if(strcmp(strLn,tableName)==0)
851 {
852 f->data = ftell (f->fp);
853 if(ferror(f->fp))
854 {
855 perror ("The following error occurred");
856 ModelicaFormatError("Cannot get File Position! from File %s",f->filename);
857 }
858 while(!feof(f->fp) && (stop==0))
859 {
860 col = csv_readLine(f,&strLn,&buflen);
861 for(i = 0; i<buflen;i++)
862 {
863 if(strLn[i]== ',')
864 {
865 _cols++;
866 continue;
867 }
868 if(strLn[i]== 0)
869 break;
870 if(isdigit(strLn[i])((*__ctype_b_loc ())[(int) ((strLn[i]))] & (unsigned short
int) _ISdigit)
== 0)
871 {
872 if(strLn[i] != 'e')
873 if(strLn[i] != 'E')
874 if(strLn[i] != '+')
875 if(strLn[i] != '-')
876 stop = 1;
877 }
878 }
879 (*rows)++;
880 *cols = fmax(_cols,*cols);
881 _cols = 1;
882 }
883 if(strLn)
884 free(strLn);
885 return 1;
886 }
887 }
888 if(strLn)
889 free(strLn);
890 return 0;
891}
892
893static void csv_readTable(CSV_FILE *f, const char *tableName, double *data, size_t rows, size_t cols)
894__attribute__((nonnull));
895
896static void csv_readTable(CSV_FILE *f, const char *tableName, double *data, size_t rows, size_t cols)
897{
898 char *strLn=NULL((void*)0);
1
'strLn' initialized to a null pointer value
899 size_t buflen=0;
900 size_t row=0;
901 size_t lh=0;
902 char *number=NULL((void*)0);
903 char *entp=NULL((void*)0);
904 fseek ( f->fp , 0 , SEEK_SET0 );
905 /* WHY DOES THIS NOT WORK
906 if(fseek ( f->fp , f->data , SEEK_CUR ))
907 {
908 throwStreamPrint("Cannot set File Position! from File %s, no data is readed",f->filename);
909 }
910 */
911 while(!feof(f->fp))
2
Assuming the condition is true
3
Loop condition is true. Entering loop body
912 {
913 size_t col = csv_readLine(f,&strLn,&buflen);
4
Calling 'csv_readLine'
914
915 if(strcmp(strLn,tableName)==0)
916 {
917 for(row=0;row<rows;row++)
918 {
919 size_t c = csv_readLine(f,&strLn,&buflen);
920 number = strLn;
921 for(col=0;col<cols;col++)
922 {
923 data[row*cols+col] = strtod(number,&entp);
924 trim((const char**)&entp,&lh);
925 number = entp+1;
926 }
927 }
928 break;
929 }
930 }
931 if(strLn)
932 free(strLn);
933}
934
935/*
936 Open specified file
937*/
938static void openFile(const char *filename, const char* tableName, size_t *rows, size_t *cols, double **data)
939{
940 size_t sl = 0;
941 char filetype[5] = {0};
942 /* get File Type */
943 sl = strlen(filename);
944 filetype[3] = filename[sl-1];
945 filetype[2] = filename[sl-2];
946 filetype[1] = filename[sl-3];
947 filetype[0] = filename[sl-4];
948
949 /* read data from file*/
950 if(strncmp(filetype,".csv",4) == 0) /* text file */
951 {
952 CSV_FILE *f=NULL((void*)0);
953 f = csv_open(filename);
954 if(csv_findTable(f,tableName,cols,rows))
955 {
956 *data = (double*)calloc((*cols)*(*rows),sizeof(double));
957 if (!*data) {
958 ModelicaFormatError("Not enough memory for Table: %s",tableName);
959 }
960 csv_readTable(f,tableName,*data,*rows,*cols);
961 csv_close(f);
962 return;
963 }
964 csv_close(f);
965 ModelicaFormatError("No table named `%s' in file `%s'.",tableName,filename);
966 }
967 else if(strncmp(filetype,".mat",4) == 0) /* mat file */
968 {
969 MAT_FILE *f= Mat_open(filename);
970 if(Mat_findTable(f,tableName,cols,rows))
971 {
972 *data = (double*)calloc((*cols)*(*rows),sizeof(double));
973 if (!*data) {
974 ModelicaFormatError("Not enough memory for Table: %s",tableName);
975 }
976 Mat_readTable(f,*data,*rows,*cols);
977 Mat_close(f);
978 return;
979 }
980 Mat_close(f);
981 ModelicaFormatError("No table named `%s' in file `%s'.",tableName,filename);
982 }
983 else if(strncmp(filetype,".txt",4) == 0) /* csv file */
984 {
985 TEXT_FILE *f= Text_open(filename);
986 if(Text_findTable(f,tableName,cols,rows))
987 {
988 *data = (double*)calloc((*cols)*(*rows),sizeof(double));
989 if (!*data) {
990 ModelicaFormatError("Not enough memory for Table: %s",tableName);
991 }
992 Text_readTable(f,*data,*rows,*cols);
993 Text_close(f);
994 return;
995 }
996 Text_close(f);
997 ModelicaFormatError("No table named `%s' in file `%s'.",tableName,filename);
998 }
999 ModelicaFormatError("Interpolation table: %s from file %s uknown file extension -- `%s'.",tableName,filename,filetype);
1000}
1001
1002/*
1003 implementation of InterpolationTable methods
1004*/
1005
1006static char *copyTableNameFile(const char *name)
1007{
1008 size_t l = 0;
1009 char *dst=NULL((void*)0);
1010 l = strlen(name);
1011 if(l==0)
1012 l = 6;
1013 dst = (char*)malloc((l+1)*sizeof(char));
1014 if (!dst) {
1015 ModelicaFormatError("Not enough memory for Table: %s",name);
1016 }
1017 if(name)
1018 {
1019 size_t i;
1020 for(i=0;i<=l;i++)
1021 {
1022 dst[i] = name[i];
1023 }
1024 }
1025 else
1026 {
1027 strcpy(dst,"NoName");
1028 }
1029 return dst;
1030}
1031
1032static InterpolationTable* InterpolationTable_init(double time, double startTime,
1033 int ipoType, int expoType,
1034 const char* tableName, const char* fileName,
1035 const double* table, int tableDim1,
1036 int tableDim2, int colWise)
1037{
1038 size_t size = tableDim1*tableDim2;
1039 InterpolationTable *tpl = 0;
1040 tpl = (InterpolationTable*)calloc(1,sizeof(InterpolationTable));
1041 if (!tpl) {
1042 ModelicaFormatError("Not enough memory for Table: %s",tableName);
1043 }
1044 else
1045 {
1046 tpl->rows = tableDim1;
1047 tpl->cols = tableDim2;
1048 tpl->colWise = colWise;
1049 tpl->ipoType = ipoType;
1050 tpl->expoType = expoType;
1051 tpl->startTime = startTime;
1052
1053 tpl->tablename = copyTableNameFile(tableName);
1054 tpl->filename = copyTableNameFile(fileName);
1055
1056 if(fileName && strncmp("NoName",fileName,6) != 0)
1057 {
1058 openFile(fileName,tableName,&(tpl->rows),&(tpl->cols),&(tpl->data));
1059 tpl->own_data = 1;
1060 } else
1061 {
1062#ifndef COPY_ARRAYS
1063 if (!table) {
1064 ModelicaFormatError("Not enough memory for Table: %s",tableName);
1065 }
1066 tpl->data = *(double**)((void*)&table);
1067#else
1068 size_t i;
1069 /* tpl->data = const_cast<double*>(table); */
1070 tpl->data = (double*)malloc(size*sizeof(double));
1071 if (!tpl->data) {
1072 ModelicaFormatError("Not enough memory for Table: %s",tableName);
1073 }
1074 tpl->own_data = 1;
1075
1076 for(i=0;i<size;i++)
1077 {
1078 tpl->data[i] = table[i];
1079 }
1080#endif
1081 }
1082 /* check that time column is strictly monotonous */
1083 InterpolationTable_checkValidityOfData(tpl);
1084 }
1085 return tpl;
1086}
1087
1088static void InterpolationTable_deinit(InterpolationTable *tpl)
1089{
1090 if(tpl)
1091 {
1092 if(tpl->own_data)
1093 free(tpl->data);
1094 free(tpl);
1095 }
1096}
1097
1098static double InterpolationTable_interpolate(InterpolationTable *tpl, double time, size_t col)
1099{
1100 size_t i = 0;
1101 size_t lastIdx = tpl->colWise ? tpl->cols : tpl->rows;
1102
1103 if(!tpl->data) return 0.0;
1104
1105 /* adrpo: if we have only one row [0, 0.7] return the value column */
1106 if(lastIdx == 1)
1107 {
1108 return InterpolationTable_getElt(tpl,0,col);
1109 }
1110
1111 /* substract time offset */
1112 if(time < InterpolationTable_minTime(tpl))
1113 return InterpolationTable_extrapolate(tpl,time,col,time <= InterpolationTable_minTime(tpl));
1114
1115 for(i = 0; i < lastIdx; ++i) {
1116 if(InterpolationTable_getElt(tpl,i,0) > time) {
1117 if(tpl->ipoType == 1 || lastIdx==2)
1118 return InterpolationTable_interpolateLin(tpl,time, i-1,col);
1119 else if(tpl->ipoType == 2){
1120 return InterpolationTable_interpolateSpline(tpl,time, i-1,col);
1121 }
1122 }
1123 }
1124 return InterpolationTable_extrapolate(tpl,time,col,time <= InterpolationTable_minTime(tpl));
1125}
1126
1127static double InterpolationTable_maxTime(InterpolationTable *tpl)
1128{
1129 return (tpl->data?InterpolationTable_getElt(tpl,tpl->rows-1,0):0.0);
1130}
1131static double InterpolationTable_minTime(InterpolationTable *tpl)
1132{
1133 return (tpl->data?tpl->data[0]:0.0);
1134}
1135
1136static char InterpolationTable_compare(InterpolationTable *tpl, const char* fname, const char* tname,
1137 const double* table)
1138{
1139 if( (fname == NULL((void*)0) || tname == NULL((void*)0)) || ((strncmp("NoName",fname,6) == 0 && strncmp("NoName",tname,6) == 0)) )
1140 {
1141 /* table passed as memory location */
1142 return (tpl->data == table);
1143 }
1144 else
1145 {
1146 /* table loaded from file */
1147 return ((!strncmp(tpl->filename,fname,6)) && (!strncmp(tpl->tablename,tname,6)));
1148 }
1149}
1150
1151static double InterpolationTable_extrapolate(InterpolationTable *tpl, double time, size_t col,
1152 char beforeData)
1153{
1154 size_t lastIdx;
1155
1156 switch(tpl->expoType) {
1157 case 1:
1158 /* hold last/first value */
1159 return InterpolationTable_getElt(tpl,(beforeData ? 0 : tpl->rows-1),col);
1160 case 2:
1161 /* extrapolate through first/last two values */
1162 lastIdx = (tpl->colWise ? tpl->cols : tpl->rows) - 2;
1163 return InterpolationTable_interpolateLin(tpl,time,(beforeData ? 0 : lastIdx),col);
1164 case 3:
1165 /* periodically repeat signal */
1166 time = tpl->startTime + (time - InterpolationTable_maxTime(tpl)*floor(time/InterpolationTable_maxTime(tpl)));
1167 return InterpolationTable_interpolate(tpl,time,col);
1168 default:
1169 return 0.0;
1170 }
1171}
1172
1173static double InterpolationTable_interpolateLin(InterpolationTable *tpl, double time, size_t i, size_t j)
1174{
1175 double t_1 = InterpolationTable_getElt(tpl,i,0);
1176 double t_2 = InterpolationTable_getElt(tpl,i+1,0);
1177 double y_1 = InterpolationTable_getElt(tpl,i,j);
1178 double y_2 = InterpolationTable_getElt(tpl,i+1,j);
1179 /*if(std::abs(t_2-t_1) < 100.0*std::numeric_limits<double>::epsilon())
1180 return y_1;
1181 else
1182 */
1183 return (y_1 + ((time-t_1)/(t_2-t_1)) * (y_2-y_1));
1184}
1185
1186static double InterpolationTable_interpolateSpline(InterpolationTable *tpl, double time, size_t i, size_t j)
1187{
1188 size_t lastIdx = tpl->colWise ? tpl->cols : tpl->rows;
1189 double x1,x2,x3,x4,x5,x6;
1190 double y1,y2,y3,y4,y5,y6;
1191 double m1,m2,m3,m4,m5;
1192 double t1,t2;
1193 double p0,p1,p2,p3;
1194 double x;
1195
1196 x3 = InterpolationTable_getElt(tpl,i,0);
1197 x4 = InterpolationTable_getElt(tpl,i+1,0);
1198 y3 = InterpolationTable_getElt(tpl,i,j);
1199 y4 = InterpolationTable_getElt(tpl,i+1,j);
1200
1201 if(i > 1){
1202 x1 = InterpolationTable_getElt(tpl,i-2,0);
1203 x2 = InterpolationTable_getElt(tpl,i-1,0);
1204 y1 = InterpolationTable_getElt(tpl,i-2,j);
1205 y2 = InterpolationTable_getElt(tpl,i-1,j);
1206 }
1207 else if(i == 1){
1208 x2 = InterpolationTable_getElt(tpl,i-1,0);
1209 x1 = x3 + x2 - x4;
1210 y2 = InterpolationTable_getElt(tpl,i-1,j);
1211 y1 = (y4-y3)*(x2-x1)/(x4-x3) - 2*(y3-y2)*(x2-x1)/(x3-x2) + y2;
1212 }
1213 else{
1214 x5 = InterpolationTable_getElt(tpl,i+2,0);
1215 x1 = 2*x3-x5;
1216 x2 = x4 + x3 - x5;
1217 y5 = InterpolationTable_getElt(tpl,i+2,j);
1218 y2 = (y5-y4)*(x3-x2)/(x5-x4) - 2*(y4-y3)*(x3-x2)/(x4-x3) + y3;
1219 y1 = (y4-y3)*(x2-x1)/(x4-x3) - 2*(y3-y2)*(x2-x1)/(x3-x2) + y2;
1220 }
1221
1222 if(i < lastIdx-3){
1223 x5 = InterpolationTable_getElt(tpl,i+2,0);
1224 x6 = InterpolationTable_getElt(tpl,i+3,0);
1225 y5 = InterpolationTable_getElt(tpl,i+2,j);
1226 y6 = InterpolationTable_getElt(tpl,i+3,j);
1227 }
1228 else if(i < lastIdx-2){
1229 x5 = InterpolationTable_getElt(tpl,i+2,0);
1230 x6 = x5 - x3 + x4;
1231 y5 = InterpolationTable_getElt(tpl,i+2,j);
1232 y6 = 2*(y5-y4)*(x6-x5)/(x5-x4) - (y4-y3)*(x6-x5)/(x4-x3) + y5;
1233 }
1234 else{
1235 x5 = x4 - x2 + x3;
1236 x6 = 2*x4 - x2;
1237 y5 = 2*(y4-y3)*(x5-x4)/(x4-x3) - (y3-y2)*(x5-x4)/(x3-x2) + y4;
1238 y6 = 2*(y5-y4)*(x6-x5)/(x5-x4) - (y4-y3)*(x6-x5)/(x4-x3) + y5;
1239 }
1240
1241 m1 = (y2-y1)/(x2-x1);
1242 m2 = (y3-y2)/(x3-x2);
1243 m3 = (y4-y3)/(x4-x3);
1244 m4 = (y5-y4)/(x5-x4);
1245 m5 = (y6-y5)/(x6-x5);
1246
1247 if(m1==m2 && m3==m4)
1248 t1 = 0.5*(m2+m3);
1249 else
1250 t1 = (fabs(m4-m3)*m2+fabs(m2-m1)*m3) / (fabs(m4-m3)+fabs(m2-m1));
1251
1252 if(m2==m3 && m4==m5)
1253 t2 = 0.5*(m3+m4);
1254 else
1255 t2 = (fabs(m5-m4)*m3+fabs(m3-m2)*m4) / (fabs(m5-m4)+fabs(m3-m2));
1256
1257 p0 = y3;
1258 p1 = t1;
1259 p2 = (3*(y4-y3)/(x4-x3)-2*t1-t2)/(x4-x3);
1260 p3 = (t1+t2-2*(y4-y3)/(x4-x3))/((x4-x3)*(x4-x3));
1261
1262 // printf("\ni=%d\n", i);
1263 // printf("\nx1=%g\nx2=%g\nx3=%g\nx4=%g\nx5=%g\nx6=%g\n", x1,x2,x3,x4,x5,x6);
1264 // printf("\ny1=%g\ny2=%g\ny3=%g\ny4=%g\ny5=%g\ny6=%g\n", y1,y2,y3,y4,y5,y6);
1265 // printf("\nm1=%g\nm2=%g\nm3=%g\nm4=%g\nm5=%g\n", m1,m2,m3,m4,m5);
1266 // printf("\nt1=%g\nt2=%g\n", t1,t2);
1267 // printf("\np0=%g\np1=%g\np2=%g\np3=%g\n", p0,p1,p2,p3);
1268 // printf("\nx=%g\n", x);
1269
1270 return p0 + (time-x3) * (p1 + (time-x3) * (p2 + (time-x3) * p3));
1271}
1272
1273static const double InterpolationTable_getElt(InterpolationTable *tpl, size_t row, size_t col)
1274{
1275 /* is this really correct? doesn't it depends on tpl>colWise? */
1276 if (!(row < tpl->rows && col < tpl->cols)) {
1277 ModelicaFormatError("In Table: %s from File: %s with Size[%lu,%lu] try to get Element[%lu,%lu] out of range!",
1278 tpl->tablename, tpl->filename,
1279 (unsigned long)tpl->rows, (unsigned long)tpl->cols,
1280 (unsigned long)row, (unsigned long)col);
1281 }
1282
1283 return tpl->data[tpl->colWise ? col*tpl->rows+row : row*tpl->cols+col];
1284}
1285
1286static void InterpolationTable_checkValidityOfData(InterpolationTable *tpl)
1287{
1288 size_t i = 0;
1289 size_t maxSize = tpl->colWise ? tpl->cols : tpl->rows;
1290 /* if we have only one row or column, return */
1291 if(maxSize == 1) return;
1292 /* else check the validity */
1293 for(i = 1; i < maxSize; ++i)
1294 if(InterpolationTable_getElt(tpl,i-1,0) > InterpolationTable_getElt(tpl,i,0))
1295 ModelicaFormatError("TimeTable: Column with time variable not monotonous: %g >= %g.", InterpolationTable_getElt(tpl,i-1,0),InterpolationTable_getElt(tpl,i,0));
1296}
1297
1298
1299/*
1300 interpolation 2D
1301*/
1302static InterpolationTable2D* InterpolationTable2D_init(int ipoType, const char* tableName,
1303 const char* fileName, const double *table,
1304 int tableDim1, int tableDim2, int colWise)
1305{
1306 size_t size = tableDim1*tableDim2;
1307 InterpolationTable2D *tpl = 0;
1308 tpl = (InterpolationTable2D*)calloc(1,sizeof(InterpolationTable2D));
1309 if (!tpl) {
1310 ModelicaFormatError("Not enough memory for Table: %s",tableName);
1311 }
1312 else
1313 {
1314 if (!((0 < ipoType) & (ipoType < 3))) {
1315 ModelicaFormatError("Unknown interpolation Type %d for Table %s from file %s!",ipoType,tableName,fileName);
1316 }
1317 tpl->rows = tableDim1;
1318 tpl->cols = tableDim2;
1319 tpl->colWise = colWise;
1320 tpl->ipoType = ipoType;
1321
1322 tpl->tablename = copyTableNameFile(tableName);
1323 tpl->filename = copyTableNameFile(fileName);
1324
1325 if(fileName && strncmp("NoName",fileName,6) != 0)
1326 {
1327 openFile(fileName,tableName,&(tpl->rows),&(tpl->cols),&(tpl->data));
1328 tpl->own_data = 1;
1329 } else {
1330#ifndef COPY_ARRAYS
1331 if (!table) {
1332 ModelicaFormatError("Not enough memory for Table: %s",tableName);
1333 }
1334 tpl->data = *(double**)((void*)&table);
1335#else
1336 size_t i;
1337 tpl->data = (double*)malloc(size*sizeof(double));
1338 if (!tpl->data) {
1339 ModelicaFormatError("Not enough memory for Table: %s",tableName);
1340 }
1341 tpl->own_data = 1;
1342
1343 for(i=0;i<size;i++)
1344 {
1345 tpl->data[i] = table[i];
1346 }
1347#endif
1348}
1349 }
1350 /* check if table is valid */
1351 InterpolationTable2D_checkValidityOfData(tpl);
1352 return tpl;
1353}
1354
1355static void InterpolationTable2D_deinit(InterpolationTable2D *table)
1356{
1357 if(table)
1358 {
1359 if(table->own_data)
1360 free(table->data);
1361 free(table);
1362 }
1363}
1364
1365static double InterpolationTable2D_akime(double* tx, double* ty, size_t tlen, double x)
1366{
1367 double x1,x2,x3,y1,y2,y3,a,b,yd0,yd1,t,pd_li,pd_re,g0,g1,h0,h1,cden,t1,t2,t3;
1368 size_t index=0;
1369 if (!(tlen>0)) {
1370 ModelicaFormatError("InterpolationTable2D_akime called with empty table!");
1371 }
1372 /* smooth interpolation with Akima Splines such that der(y) is continuous */
1373 if((tlen < 4) | (x < tx[2]) | (x > tx[tlen-3]))
1374 {
1375 double c;
1376 if(tlen < 3)
1377 {
1378 if(tlen < 2)
1379 {
1380 return ty[0];
1381 }
1382 /* Linear Interpolation */
1383 return ((tx[1] - x)*ty[0] + (x - tx[0])*ty[1]) / (tx[1]-tx[0]);
1384 }
1385 /* parable interpolation */
1386 if(x > tx[tlen-3])
1387 {
1388 x1 = tx[tlen-3];
1389 x2 = tx[tlen-2];
1390 x3 = tx[tlen-1];
1391 y1 = ty[tlen-3];
1392 y2 = ty[tlen-2];
1393 y3 = ty[tlen-1];
1394 }
1395 else
1396 {
1397 x1 = tx[0];
1398 x2 = tx[1];
1399 x3 = tx[2];
1400 y1 = ty[0];
1401 y2 = ty[1];
1402 y3 = ty[2];
1403 }
1404
1405 cden = (x1-x2)*(x1-x3)*(x2-x3);
1406 t1 = x1*(y2-y3);
1407 t2 = x2*(y3-y1);
1408 t3 = x3*(y1-y2);
1409 a =-(t1+t2+t3)/cden;
1410 b = (x1*t1+x2*t2+x3*t3)/cden;
1411 c = (x1*x1*(x2*y3-x3*y2)+x1*(x3*x3*y2-x2*x2*y3)+x2*x3*y1*(x2-x3))/cden;
1412
1413 return x*(a*x + b) + c;
1414 }
1415
1416 /* get index in table */
1417 for(index = 1; index < tlen-1; index++)
1418 if(tx[index] > x) break;
1419
1420 if(index > 2)
1421 {
1422 if(index < tlen - 2)
1423 {
1424 double a1, a2;
1425 double q[5] = {0};
1426 int i;
1427 /* calc */
1428 int pos = 0;
1429 for(i = -2; i < 3; ++i)
1430 {
1431 q[pos] = (ty[index+i]-ty[index+i-1])/(tx[index+i]-tx[index+i-1]);
1432 pos = pos + 1;
1433 }
1434
1435 a1 = fabs(q[3]-q[2]);
1436 a2 = fabs(q[1]-q[0]);
1437 if(a1+a2 == 0)
1438 yd0 = (q[1] + q[2])/2;
1439 else
1440 yd0 = (q[1]*a1 + q[2]*a2)/(a1+a2);
1441 a1 = fabs(q[4]-q[3]);
1442 a2 = fabs(q[2]-q[1]);
1443 if(a1+a2 == 0)
1444 yd1 = (q[2] + q[3])/2;
1445 else
1446 yd1 = (q[2]*a1 + q[3]*a2)/(a1+a2);
1447 }
1448 else
1449 {
1450 x1 = tx[tlen-3];
1451 x2 = tx[tlen-2];
1452 x3 = tx[tlen-1];
1453 y1 = ty[tlen-3];
1454 y2 = ty[tlen-2];
1455 y3 = ty[tlen-1];
1456
1457 cden = (x1-x2)*(x1-x3)*(x2-x3);
1458 t1 = x1*(y2-y3);
1459 t2 = x2*(y3-y1);
1460 t3 = x3*(y1-y2);
1461 a =-(t1+t2+t3)/cden;
1462 b = (x1*t1+x2*t2+x3*t3)/cden;
1463
1464 if(index < tlen - 1)
1465 {
1466 yd0 = 2*a*x1 - b;
1467 yd1 = 2*a*x2 - b;
1468 }
1469 else
1470 {
1471 yd0 = 2*a*x2 - b;
1472 yd1 = 2*a*x3 - b;
1473 }
1474 }
1475 }
1476 else
1477 {
1478 x1 = tx[0];
1479 x2 = tx[1];
1480 x3 = tx[2];
1481 y1 = ty[0];
1482 y2 = ty[1];
1483 y3 = tx[2];
1484
1485 cden = (x1-x2)*(x1-x3)*(x2-x3);
1486 t1 = x1*(y2-y3);
1487 t2 = x2*(y3-y1);
1488 t3 = x3*(y1-y2);
1489 a =-(t1+t2+t3)/cden;
1490 b = (x1*t1+x2*t2+x3*t3)/cden;
1491
1492 if(index > 0)
1493 {
1494 yd0 = 2*a*x2 - b;
1495 yd1 = 2*a*x3 - b;
1496 }
1497 else
1498 {
1499 yd0 = 2*a*x1 - b;
1500 yd1 = 2*a*x2 - b;
1501 }
1502 }
1503 t = (x-tx[index-1])/(tx[index]-tx[index-1]);
1504
1505 pd_li = (tx[index] - tx[index-1])*yd0;
1506 pd_re = (tx[index] - tx[index-1])*yd1;
1507
1508 g0 = 0.5-1.5*(t-0.5)+2*pow(t-0.5,3);
1509 g1 = 1-g0;
1510 h0 = t*pow((t-1),2);
1511 h1 = t*t*(t-1);
1512
1513 return ty[index-1]*g0+ty[index]*g1+pd_li*h0+pd_re*h1;
1514}
1515
1516static double InterpolationTable2D_interpolate(InterpolationTable2D *table, double x1, double x2)
1517{
1518 size_t i, j, start;
1519 double f_1, f_2;
1520 double tx[6];
1521 double ty[6];
1522 size_t tlen=0;
1523 if(table->colWise)
1524 {
1525 double tmp = x1;
1526 x1 = x2;
1527 x2 = tmp;
1528 }
1529
1530 /* if out of boundary, use first or last two points for x2 */
1531 if(table->cols == 2)
1532 {
1533 if(table->rows == 2)
1534 {
1535 /*
1536 If the table has only one element, the table value is returned,
1537 independent of the value of the input signal.
1538 */
1539 return InterpolationTable2D_getElt(table,1,1);
1540 }
1541 /* find interval corresponding x1 */
1542 for(i = 2; i < table->rows; ++i)
1543 if(InterpolationTable2D_getElt(table,i,0) >= x1) break;
1544 if((table->ipoType == 2) && (table->rows > 3))
1545 {
1546 /* smooth interpolation with Akima Splines such that der(y) is continuous */
1547 tlen=0;
1548 if(i < 4)
1549 start = 1;
1550 else
1551 start = i-3;
1552 for(j = start; (j < table->rows) & (j < i+3); ++j)
1553 {
1554 tx[tlen] = InterpolationTable2D_getElt(table,j,0);
1555 ty[tlen] = InterpolationTable2D_getElt(table,j,1);
1556 tlen++;
1557 }
1558 return InterpolationTable2D_akime(tx,ty,tlen,x1);
1559 }
1560 /* Liniear Interpolation */
1561 f_2 = InterpolationTable2D_getElt(table,i,1) - InterpolationTable2D_getElt(table,i-1,1);
1562 return InterpolationTable2D_linInterpolate(x1,InterpolationTable2D_getElt(table,i-1,0),InterpolationTable2D_getElt(table,i,0),0,f_2);
1563 }
1564 if(table->rows == 2)
1565 {
1566 /* find interval corresponding x2 */
1567 for(j = 2; j < table->cols; ++j)
1568 if(InterpolationTable2D_getElt(table,0,j) >= x2) break;
1569
1570 if((table->ipoType == 2) && (table->cols > 3))
1571 {
1572 /* smooth interpolation with Akima Splines such that der(y) is continuous */
1573 tlen=0;
1574 if(j < 4)
1575 start = 1;
1576 else
1577 start = j-3;
1578 for(i = start; (i < table->cols) & (i < j+3); ++i)
1579 {
1580 tx[tlen] = InterpolationTable2D_getElt(table,0,i);
1581 ty[tlen] = InterpolationTable2D_getElt(table,1,i);
1582 tlen++;
1583 }
1584 return InterpolationTable2D_akime(tx,ty,tlen,x2);
1585 }
1586 f_2 = InterpolationTable2D_getElt(table,1,j) - InterpolationTable2D_getElt(table,1,j-1);
1587 return InterpolationTable2D_linInterpolate(x2,InterpolationTable2D_getElt(table,0,j-1),InterpolationTable2D_getElt(table,0,j),0,f_2);
1588 }
1589
1590 /* find intervals corresponding x1 and x2 */
1591 for(i = 2; i < table->rows-1; ++i)
1592 if(InterpolationTable2D_getElt(table,i,0) >= x1) break;
1593 for(j = 2; j < table->cols-1; ++j)
1594 if(InterpolationTable2D_getElt(table,0,j) >= x2) break;
1595
1596 if((table->ipoType == 2) && (table->rows != 3) && (table->cols != 3) )
1597 {
1598 size_t k, l, starte, telen;
1599 double te[6];
1600 /* smooth interpolation with Akima Splines such that der(y) is continuous */
1601
1602 /* interpolate rows */
1603 if(i < 4)
1604 start = 1;
1605 else
1606 start = i-3;
1607 if(j < 4)
1608 starte = 1;
1609 else
1610 starte = j-3;
1611 tlen=0;
1612 for(k = start; (k < table->rows) & (k < i+3); ++k)
1613 {
1614 tx[tlen] = InterpolationTable2D_getElt(table,k,0);
1615 tlen++;
1616 }
1617 telen=0;
1618 for(l = starte; (l < table->cols) & (l < j+3); ++l)
1619 {
1620 tlen=0;
1621 for(k = start; (k < table->rows) & (k < i+3); ++k)
1622 {
1623 ty[tlen] = InterpolationTable2D_getElt(table,k,l);
1624 tlen++;
1625 }
1626 te[telen] = InterpolationTable2D_akime(tx,ty,tlen,x1);
1627 telen++;
1628 }
1629 telen=0;
1630 for(k = starte; (k < table->cols) & (k < j+3); ++k)
1631 {
1632 tx[telen] = InterpolationTable2D_getElt(table,0,k);
1633 telen++;
1634 }
1635 return InterpolationTable2D_akime(tx,te,telen,x2);
1636 }
1637
1638 /* bilinear interpolation */
1639 f_1 = InterpolationTable2D_linInterpolate(x1,InterpolationTable2D_getElt(table,i-1,0),InterpolationTable2D_getElt(table,i,0),InterpolationTable2D_getElt(table,i-1,j-1),InterpolationTable2D_getElt(table,i,j-1));
1640 f_2 = InterpolationTable2D_linInterpolate(x1,InterpolationTable2D_getElt(table,i-1,0),InterpolationTable2D_getElt(table,i,0),InterpolationTable2D_getElt(table,i-1,j),InterpolationTable2D_getElt(table,i,j));
1641 return InterpolationTable2D_linInterpolate(x2,InterpolationTable2D_getElt(table,0,j-1),InterpolationTable2D_getElt(table,0,j),f_1,f_2);
1642}
1643
1644static char InterpolationTable2D_compare(InterpolationTable2D *tpl, const char* fname, const char* tname, const double* table)
1645{
1646 if( (fname == NULL((void*)0) || tname == NULL((void*)0)) || ((strncmp("NoName",fname,6) == 0 && strncmp("NoName",tname,6) == 0)) )
1647 {
1648 /* table passed as memory location */
1649 return (tpl->data == table);
1650 }
1651 else
1652 {
1653 /* table loaded from file */
1654 return ((!strncmp(tpl->filename,fname,6)) && (!strncmp(tpl->tablename,tname,6)));
1655 }
1656 return 0;
1657}
1658
1659static double InterpolationTable2D_linInterpolate(double x, double x_1, double x_2, double f_1, double f_2)
1660{
1661 return ((x_2 - x)*f_1 + (x - x_1)*f_2) / (x_2-x_1);
1662}
1663
1664static const double InterpolationTable2D_getElt(InterpolationTable2D *tpl, size_t row, size_t col)
1665{
1666 if (!(row < tpl->rows && col < tpl->cols)) {
1667 ModelicaFormatError("In Table: %s from File: %s with Size[%lu,%lu] try to get Element[%lu,%lu] out of range!", tpl->tablename, tpl->filename, (unsigned long)tpl->rows, (unsigned long)tpl->cols, (unsigned long)row, (unsigned long)col);
1668 }
1669 return tpl->data[row*tpl->cols+col];
1670}
1671
1672static void InterpolationTable2D_checkValidityOfData(InterpolationTable2D *tpl)
1673{
1674 size_t i = 0;
1675 /* check if table has values */
1676 if (!((tpl->rows > 1) && (tpl->cols > 1))) {
1677 ModelicaFormatError("Table %s from file %s has no data!", tpl->tablename, tpl->filename);
1678 }
1679 /* check that first row and column are strictly monotonous */
1680 for(i=2; i < tpl->rows; ++i)
1681 {
1682 if(InterpolationTable2D_getElt(tpl,i-1,0) >= InterpolationTable2D_getElt(tpl,i,0))
1683 ModelicaFormatError("Table: %s independent variable u1 not strictly \
1684 monotonous: %g >= %g.",tpl->tablename, InterpolationTable2D_getElt(tpl,i-1,0), InterpolationTable2D_getElt(tpl,i,0));
1685 }
1686 for(i=2; i < tpl->cols; ++i)
1687 {
1688 if(InterpolationTable2D_getElt(tpl,0,i-1) >= InterpolationTable2D_getElt(tpl,0,i))
1689 ModelicaFormatError("Table: %s independent variable u2 not strictly \
1690 monotonous: %g >= %g.",tpl->tablename, InterpolationTable2D_getElt(tpl,0,i-1), InterpolationTable2D_getElt(tpl,0,i));
1691 }
1692}
1693
1694/* Start of public interface and wrappers for old tables (MSL 2.x ~ 3.2) */
1695
1696#ifndef MODELICA_TABLES_H
1697#define MODELICA_TABLES_H
1698
1699/* Definition of interface to external functions for table computation
1700 in the Modelica Standard Library:
1701
1702 Modelica.Blocks.Sources.CombiTimeTable
1703 Modelica.Blocks.Tables.CombiTable1D
1704 Modelica.Blocks.Tables.CombiTable1Ds
1705 Modelica.Blocks.Tables.CombiTable2D
1706
1707
1708 Release Notes:
1709 Jan. 27, 2008: by Martin Otter.
1710 Implemented a first version
1711
1712 Copyright (C) 2008, Modelica Association and DLR.
1713
1714 The content of this section of the file is free software; it can be redistributed
1715 and/or modified under the terms of the Modelica License 2, see the
1716 license conditions and the accompanying disclaimer in file
1717 Modelica/ModelicaLicense2.html or in Modelica.UsersGuide.ModelicaLicense2.
1718*/
1719
1720
1721/* A table can be defined in the following ways when initializing the table:
1722
1723 (1) Explicitly supplied in the argument list
1724 (= table is "NoName" or has only blanks AND
1725 fileName is "NoName" or has only blanks).
1726
1727 (2) Read from a file (tableName, fileName have to be supplied).
1728
1729 Tables may be linearly interpolated or the first derivative may be continuous.
1730 In the second case, Akima-Splines are used
1731 (algorithm 433 of ACM, http://portal.acm.org/citation.cfm?id=355605)
1732*/
1733
1734extern int ModelicaTables_CombiTimeTable_init(
1735 const char* tableName,
1736 const char* fileName,
1737 double const* table, int nRow, int nColumn,
1738 double startTime,
1739 int smoothness,
1740 int extrapolation);
1741 /* Initialize 1-dim. table where first column is time
1742
1743 -> tableName : Name of table.
1744 -> fileName : Name of file.
1745 -> table : If tableName="NoName" or has only blanks AND
1746 fileName ="NoName" or has only blanks, then
1747 this pointer points to a 2-dim. array (row-wise storage)
1748 in the Modelica environment that holds this matrix.
1749 -> nRow : Number of rows of table
1750 -> nColumn : Number of columns of table
1751 -> startTime : Output = offset for time < startTime
1752 -> smoothness: Interpolation type
1753 = 1: linear
1754 = 2: continuous first derivative
1755 <- RETURN : ID of internal memory of table.
1756 */
1757
1758extern void ModelicaTables_CombiTimeTable_close(int tableID);
1759 /* Close table and free allocated memory */
1760
1761
1762extern double ModelicaTables_CombiTimeTable_minimumTime(int tableID);
1763 /* Return minimum time defined in table (= table[1,1]) */
1764
1765
1766extern double ModelicaTables_CombiTimeTable_maximumTime(int tableID);
1767 /* Return maximum time defined in table (= table[end,1]) */
1768
1769
1770extern double ModelicaTables_CombiTimeTable_interpolate(int tableID, int icol, double u);
1771 /* Interpolate in table
1772
1773 -> tableID: Pointer to table defined with ModelicaTables_CombiTimeTable_init
1774 -> icol : Column to interpolate
1775 -> u : Abscissa value (time)
1776 <- RETURN : Ordinate value
1777 */
1778
1779
1780
1781extern int ModelicaTables_CombiTable1D_init(
1782 const char* tableName,
1783 const char* fileName,
1784 double const* table, int nRow, int nColumn,
1785 int smoothness);
1786 /* Initialize 1-dim. table defined by matrix, where first column
1787 is x-axis and further columns of matrix are interpolated
1788
1789 -> tableName : Name of table.
1790 -> fileName : Name of file.
1791 -> table : If tableName="NoName" or has only blanks AND
1792 fileName ="NoName" or has only blanks, then
1793 this pointer points to a 2-dim. array (row-wise storage)
1794 in the Modelica environment that holds this matrix.
1795 -> nRow : Number of rows of table
1796 -> nColumn : Number of columns of table
1797 -> smoothness: Interpolation type
1798 = 1: linear
1799 = 2: continuous first derivative
1800 <- RETURN : ID of internal memory of table.
1801 */
1802
1803extern void ModelicaTables_CombiTable1D_close(int tableID);
1804 /* Close table and free allocated memory */
1805
1806extern double ModelicaTables_CombiTable1D_interpolate(int tableID, int icol, double u);
1807 /* Interpolate in table
1808
1809 -> tableID: Pointer to table defined with ModelicaTables_CombiTable1D_init
1810 -> icol : Column to interpolate
1811 -> u : Abscissa value
1812 <- RETURN : Ordinate value
1813 */
1814
1815
1816
1817extern int ModelicaTables_CombiTable2D_init(
1818 const char* tableName,
1819 const char* fileName,
1820 double const* table, int nRow, int nColumn,
1821 int smoothness);
1822 /* Initialize 2-dim. table defined by matrix, where first column
1823 is x-axis, first row is y-axis and the matrix elements are the
1824 z-values.
1825 table[2:end,1 ]: Values of x-axis
1826 [1 ,2:end]: Values of y-axis
1827 [2:end,2:end]: Values of z-axis
1828
1829 -> tableName : Name of table.
1830 -> fileName : Name of file.
1831 -> table : If tableName="NoName" or has only blanks AND
1832 fileName ="NoName" or has only blanks, then
1833 this pointer points to a 2-dim. array (row-wise storage)
1834 in the Modelica environment that holds this matrix.
1835 -> nRow : Number of rows of table
1836 -> nColumn : Number of columns of table
1837 -> smoothness: Interpolation type
1838 = 1: linear
1839 = 2: continuous first derivative
1840 <- RETURN : ID of internal memory of table.
1841 */
1842
1843extern void ModelicaTables_CombiTable2D_close(int tableID);
1844 /* Close table and free allocated memory */
1845
1846extern double ModelicaTables_CombiTable2D_interpolate(int tableID, double u1, double u2);
1847 /* Interpolate in table
1848
1849 -> tableID: Pointer to table defined with ModelicaTables_CombiTable1D_init
1850 -> u1 : x-axis value
1851 -> u2 : y-axis value
1852 <- RETURN : y-axis value
1853 */
1854
1855
1856#endif /* MODELICA_TABLES */
1857
1858int ModelicaTables_CombiTimeTable_init(const char* tableName, const char* fileName,
1859 double const *table, int nRow, int nColumn,
1860 double startTime, int smoothness,
1861 int extrapolation)
1862{
1863 return omcTableTimeIni(startTime, startTime, smoothness, extrapolation,
1864 tableName, fileName, table, nRow, nColumn, 0);
1865}
1866
1867void ModelicaTables_CombiTimeTable_close(int tableID)
1868{
1869 omcTableTimeIpoClose(tableID);
1870};
1871
1872double ModelicaTables_CombiTimeTable_interpolate(int tableID, int icol, double u)
1873{
1874 return omcTableTimeIpo(tableID,icol,u);
1875}
1876
1877double ModelicaTables_CombiTimeTable_minimumTime(int tableID)
1878{
1879 return omcTableTimeTmin(tableID);
1880}
1881
1882double ModelicaTables_CombiTimeTable_maximumTime(int tableID)
1883{
1884 return omcTableTimeTmax(tableID);
1885}
1886
1887int ModelicaTables_CombiTable1D_init(const char* tableName, const char* fileName,
1888 double const *table, int nRow, int nColumn,
1889 int smoothness)
1890{
1891 return omcTableTimeIni(*table, *table, smoothness, 2 /* extrapolate based on two first/last values */, tableName, fileName, table, nRow, nColumn, 0);
1892}
1893
1894void ModelicaTables_CombiTable1D_close(int tableID)
1895{
1896 omcTableTimeIpoClose(tableID);
1897};
1898
1899double ModelicaTables_CombiTable1D_interpolate(int tableID, int icol, double u) {
1900 return omcTableTimeIpo(tableID,icol,u);
1901}
1902
1903int ModelicaTables_CombiTable2D_init(const char* tableName, const char* fileName,
1904 double const *table, int nRow, int nColumn,
1905 int smoothness)
1906{
1907 return omcTable2DIni(smoothness,tableName,fileName,table,nRow,nColumn,0);
1908}
1909
1910void ModelicaTables_CombiTable2D_close(int tableID)
1911{
1912 omcTable2DIpoClose(tableID);
1913};
1914
1915double ModelicaTables_CombiTable2D_interpolate(int tableID, double u1, double u2)
1916{
1917 return omcTable2DIpo(tableID, u1, u2);
1918}