Jorge Cardona
Fri, 30 Oct 2009 12:38:54 -0700
Hi, I made a little code that read a table in a csv format, and interpolate (linear) the data , and it can be used in models, i tried to use the CombiTable1D and CombiTableTime in Linux, and no one works for me, so, here is the Modelica code:
model Table1D
Real y;
Real u;
parameter Real offset=0;
parameter String fileName; // Bug 1116
function initTable
input String filename;
input Real offset;
output Integer key;
external "C"
annotation(Library="table1d.o", Include="#include \"table1d.h\"");
end initTable;
function interpolateTable
input Integer key;
input Real u;
output Real y;
external "C"
annotation(Library="table1d.o", Include="#include \"table1d.h\"");
end interpolateTable;
protected
Integer key;
equation
when initial() then
key = initTable(fileName,offset);
end when;
y = interpolateTable(key, u);
end Table1D;
table1.h:
#ifndef TABLE1D_H
#define TABLE1D_H
// Function that initiliaze the table lookup
int initTable(const char* filename, const double offset);
// Function that inerpolate the table lookup
double interpolateTable(const int key, const double u);
#endif
table1.c:
#include "table1d.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include <time.h>
int initTable(const char* filename, const double offset)
{
double u,y;
double **data = NULL;
// Open file
FILE* fd = fopen(filename,"r");
int n = 0;
while(fscanf(fd,"%lf,%lf",&u,&y)!=EOF){
data = (double**) realloc(data, (n+1)*sizeof(double*));
data[n] = (double*) calloc(2,sizeof(double));
data[n][0] = u - offset;
data[n][1] = y;
n++;
}
// Close file
close(fd);
srandom(time(NULL));
int key;
key = random();
int shmid;
shmid = shmget((key_t) key, sizeof(int) + 2 * n * sizeof(double),
0644 | IPC_CREAT | IPC_EXCL);
while((shmid < 0) && (errno == EEXIST)){
key = random();
shmid = shmget((key_t) key, sizeof(int) + 2 * n * sizeof(double),
0644 | IPC_CREAT | IPC_EXCL);
}
double *shdata;
int *shn;
shn = (int*) shmat(shmid, NULL, 0);
shn[0] = n;
shdata = (double*) (shn + 1);
int i;
for(i=0;i<n;i++){
shdata[2*i] = data[i][0];
shdata[2*i+1] = data[i][1];
}
shmdt(shn);
return key;
}
double interpolateTable(const int key, const double u)
{
int i;
int shmid;
shmid = shmget((key_t) key, sizeof(int), 0666);
if(shmid < 0) exit(0);
int *shn;
shn = (int*) shmat(shmid, NULL, 0);
if(shn==(int*)-1) exit(0);
int n;
n = shn[0];
shmdt(shn);
shmid = shmget((key_t) key, sizeof(int) + 2*n*sizeof(double), 0666);
if(shmid < 0) exit(0);
shn = (int*) shmat(shmid, NULL, 0);
if(shn==(int*)-1) exit(0);
double *data;
data = (double*) (shn + 1);
double val;
if(n==1){
// Constant function
val = data[1];
}
else if(u<=data[0]){
// u is less than min{u}
val = (data[3]-data[1])/(data[2]-data[0])*u + (data[1]*data[2] -
data[0]*data[3])/(data[2]-data[0]) ;
}else if(u > data[2*n-2]){
// us is grater than max{u}
val = ((data[2*n-1]-data[2*n-3])/(data[2*n-2]-data[2*n-4]))*u +
(data[2*n-3]*data[2*n-2] -
data[2*n-4]*data[2*n-1])/(data[2*n-2]-data[2*n-4]);
} else {
for(i=0;i<n-1;i++){
if(u<data[2*i+2]){
val = ((data[2*i+3]-data[2*i+1])/(data[2*i+2]-data[2*i]))*u +
(data[2*i+1]*data[2*i+2] -
data[2*i]*data[2*i+3])/(data[2*i+2]-data[2*i]);
break;
}
}
}
shmdt(shn);
return val;
}
As you can see i use shared memory to share the data that is read in
the initTable function, and the ask for it, it use a lot the system,
and the system cpu usage increase a lot on the simulation, but it work
pretty good, if you have a good idea to enhance this, please let me
know.
Bye.
--
Jorge Eduardo Cardona
jorgeecard...@gmail.com
jorgeecardona.blogspot.com
------------------------------------------------
Linux registered user #391186
Registered machine #291871
------------------------------------------------