Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 0.0% 0 / 0 / 729
Functions: 0.0% 0 / 0 / 56
Branches: 0.0% 0 / 0 / 478

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