Skip to content

Commit

Permalink
First import of sparse fmi runtime system.
Browse files Browse the repository at this point in the history
  • Loading branch information
James J. Nutaro committed Aug 14, 2014
1 parent 5dd1746 commit f7a7669
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 0 deletions.
87 changes: 87 additions & 0 deletions runtime/sfmi_runtime.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#include "sfmi_runtime.h"
#include <iostream>
using namespace std;
using namespace sfmi;

model_data::model_data(
int num_reals,
int num_ints,
int num_strs,
int num_bools):
Time(0),
real_vars(new fmi2Real[num_reals]),
int_vars(new fmi2Integer[num_ints]),
bool_vars(new fmi2Boolean[num_bools]),
str_vars(new string[num_strs])
{
}

void model_data::link(void* var, void(*func)(model_data*))
{
_input_info[var].push_back(func);
}

void model_data::link(void(*func)(model_data*),void* var)
{
_output_info[func].push_back(var);
}

void model_data::modify(void* var)
{
_modified_vars.insert(var);
}

model_data::~model_data()
{
delete [] real_vars;
delete [] int_vars;
delete [] bool_vars;
delete [] str_vars;
}

void model_data::update()
{
while (!(_modified_vars.empty()))
{
// Get the variable that was modified
set<void*>::iterator next_var = _modified_vars.begin();
void* var = *next_var;
// Remove it from the list of modified variables
_modified_vars.erase(next_var);
// Get the list of equations that have this variable as input
map<void*,list<void (*)(model_data*)> >::iterator map_iter =
_input_info.find(var);
// If there are any such equations, recalculate them
if (map_iter != _input_info.end())
{
// Get the list of equations
list<void (*)(model_data*)>& eqns = (*map_iter).second;
// Calculate each one
list<void (*)(model_data*)>::iterator eqns_iter = eqns.begin();
for (; eqns_iter != eqns.end(); eqns_iter++)
{
(*eqns_iter)(this);
// Get the variables that are modified by this eqn and put them into the modified list
map<void (*)(model_data*),list<void*> >::iterator map_iter_2 =
_output_info.find(*eqns_iter);
if (map_iter_2 != _output_info.end())
{
list<void*>& vars = (*map_iter_2).second;
list<void*>::iterator var_iter = vars.begin();
for (; var_iter != vars.end(); var_iter++)
_modified_vars.insert(*var_iter);
}
}
}
}
}

double sfmi::DIVISION_SIM(double num, double den, const char* den_name, int eq)
{
double result = num/den;
if (!isfinite(result))
{
cerr << "DIVISION BY ZERO! " << den_name << " = 0 in Eqn. " << eq << endl;
}
return result;
}
54 changes: 54 additions & 0 deletions runtime/sfmi_runtime.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#ifndef __sfmi_runtime_h_
#define __sfmi_runtime_h_
#include <cmath>
#include <set>
#include <map>
#include <list>
#include <string>
#include "fmi2TypesPlatform.h"

namespace sfmi
{

class model_data
{
public:
// Allocate data arrays and change management structures
model_data(
int num_reals,
int num_ints,
int num_strs,
int num_bools);

// Link an input variable to its function
void link(void* var, void(*func)(model_data*));
// Link a function its output variable
void link(void(*func)(model_data*),void* var);
// Indicate that a variable has been modified by a call to SetXXX
void modify(void* var);
// Perform updates for all modified variables
void update();
// Destroy data arrays and change management structures
~model_data();

// Data arrays
fmi2Real Time;
fmi2Real* real_vars;
fmi2Integer* int_vars;
fmi2Boolean* bool_vars;
std::string* str_vars;

private:
// Map from variable addresses to addresses of functions that have the variable for input
std::map<void*,std::list<void (*)(model_data*)> > _input_info;
// Map from addresses of functions to variables they modify
std::map<void (*)(model_data*),std::list<void*> > _output_info;
// List of variables that have been modified
std::set<void*> _modified_vars;
};

double DIVISION_SIM(double,double,const char* divisor,int);

};

#endif
Binary file added test/.Linsys_FMI.cpp.swp
Binary file not shown.
28 changes: 28 additions & 0 deletions test/Influenza.mo
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
model Influenza
// Parameters
parameter Real MortalityProb = 0.01;
parameter Real RecoveryTime = 3.0;
// In days
parameter Real MortalityTime = 1.0;
// In days
parameter Real TransmissionProb = 0.15;
parameter Real EncounterRate = 4;
// In days
// Start variables
Real Deceased(start = 0);
Real Recovered(start = 0);
Real Removed(start = 0);
Real Infectious(start = 0);
Real Susceptible(start = 499000);
Real Population;
Real R;
equation
Population = Recovered + Infectious + Susceptible;
R = (TransmissionProb * EncounterRate * Susceptible) / Population;
der(Removed) = (MortalityProb / MortalityTime + (1 - MortalityProb) / RecoveryTime) * Infectious;
der(Deceased) = MortalityProb * der(Removed);
der(Recovered) = (1 - MortalityProb) * der(Removed);
der(Susceptible) = -R * Infectious;
der(Infectious) = -der(Removed) + R * Infectious + (1+sin(4*time/365));
end Influenza;

Binary file added test/Linsys.fmu
Binary file not shown.
9 changes: 9 additions & 0 deletions test/Linsys.mo
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
model Linsys
parameter Real [2,2] A = { { -0.5, 0.0 }, { 0.0, -1.0 } };
Real [2] x;
equation
der(x) = A*x;
initial equation
x[1] = 1.0;
x[2] = 2.0;
end Linsys;
6 changes: 6 additions & 0 deletions test/Test1.mo
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
model Test1
Real x (start = 1.0);
parameter Real a = -1.0;
equation
der(x) = a*x;
end Test1;
10 changes: 10 additions & 0 deletions test/all_tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
filenames="
/home/nutarojj/Code/openmodelica/trunk/testsuite/openmodelica/fmi/ModelExchange/HelloFMIWorld.mo
Test1.mo
Linsys.mo
"
for f in $filenames;
do
bash fmu_check.sh $f
done

13 changes: 13 additions & 0 deletions test/fmu_check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
rm -rf binaries
rm -f *.fmu
export MODELICAPATH="${HOME}/Code/openmodelica/libraries/Modelica 3.2.1"
omc +s +simCodeTarget=sfmi $1 Modelica
modelFile=$(exec basename $1 | sed 's/\.mo//')
g++ -Wall -g -c -fPIC -I../FMI_for_ModelExchange_and_CoSimulation_v2.0 -o sfmi_runtime.o ../runtime/sfmi_runtime.cpp
g++ -Wall -g -c -fPIC -I../FMI_for_ModelExchange_and_CoSimulation_v2.0 -I../runtime -o ${modelFile}_FMI.o ${modelFile}_FMI.cpp
g++ -shared -Wl,-soname,${modelFile}.so -o ${modelFile}.so sfmi_runtime.o ${modelFile}_FMI.o
mkdir binaries
mkdir binaries/linux64
mv ${modelFile}.so binaries/linux64
zip -r ${modelFile}.fmu modelDescription.xml binaries
fmuCheck.linux64 -l 5 -f ${modelFile}.fmu > ${modelFile}.dat

0 comments on commit f7a7669

Please sign in to comment.