openmodelicainterest  

CSV Table reader

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
------------------------------------------------