Define external functions with internal memory.
External functions may have internal memory reported between function calls. Within Modelica this memory is defined as instance of the predefined class ExternalObject according to the following rules:
A user-defined table may be defined in the following way as an ExternalObject (the table is read in a user-defined format from file and has memory for the last used table interval):
class MyTable extends ExternalObject; function constructor input String fileName = ""; input String tableName = ""; output MyTable table; external "C" table = initMyTable(fileName, tableName); end constructor; function destructor "Release storage of table" input MyTable table; external "C" closeMyTable(table); end destructor; end MyTable;
and used in the following way:
model test "Define a new table and interpolate in it" MyTable table=MyTable(fileName ="testTables.txt", tableName="table1"); // call initMyTable Real y; equation y = interpolateMyTable(table, time); end test;
This requires to provide the following Modelica function:
function interpolateMyTable "Interpolate in table" input MyTable table; input Real u; output Real y; external "C" y = interpolateMyTable(table, u); end interpolateTable;
The external C-functions may be defined in the following way:
typedef struct { /* User-defined data structure of the table */ double* array; /* nrow*ncolumn vector */ int nrow; /* number of rows */ int ncol; /* number of columns */ int type; /* interpolation type */ int lastIndex; /* last row index for search */ } MyTable; void* initMyTable(const char* fileName, const char* tableName) { MyTable* table = malloc(sizeof(MyTable)); if ( table == NULL ) ModelicaError("Not enough memory"); // read table from file and store all data in *table return (void*) table; } void closeMyTable(void* object) { /* Release table storage */ MyTable* table = (MyTable*) object; if ( object == NULL ) return; free(table->array); free(table); } double interpolateMyTable(void* object, double u) { MyTable* table = (MyTable*) object; double y; // Interpolate using "table" data (compute y) return y; }