21 #include <boost/optional/optional_io.hpp>
27 #include <deps/builders/eq_graph_builder.hpp>
40 #include <util/visitors/partial_eval_exp.hpp>
52 ModelInstance::ModelInstance(
Model &model,
CompileFlags &flags,
WriterPtr writer) : _model(model), _flags(flags), _writer(writer) {}
54 void ModelInstance::include()
57 buffer <<
"#include <stdlib.h>" << endl;
58 buffer <<
"#include <stdio.h>" << endl;
59 buffer <<
"#include <string.h>" << endl;
60 buffer <<
"#include <math.h>" << endl;
62 buffer <<
"#include \"" << _model.name() <<
".h\"" << endl;
63 if (_model.externalFunctions()) {
64 buffer <<
"#include \"" << _model.name() <<
"_functions.h\"" << endl;
68 for (
string i = imports.
begin(it); !imports.
end(it); i = imports.
next(it)) {
69 buffer <<
"#include \"" << Utils::instance().packageName(i) <<
".h\"" << endl;
71 buffer <<
"#include <common/utils.h>" << endl;
72 buffer <<
"#include <common/model.h>" << endl;
73 buffer <<
"#include <common/commands.h>" << endl;
74 buffer <<
"#include <qss/qss_model.h>" << endl;
75 buffer <<
"#include <classic/classic_model.h>" << endl;
80 void ModelInstance::allocateOutput()
84 string period =
"NULL";
88 indent = _writer->indent(1);
89 list<double> sample = annot.
sample();
90 ssize = sample.size();
92 buffer << indent <<
"double period[" << ssize <<
"];" << endl;
94 for (list<double>::iterator i = sample.begin(); i != sample.end(); i++) {
95 buffer << indent <<
"period[" << n <<
"] = " << *i <<
";" << endl;
98 string outputFunction = (_model.outputNbr() ?
"MOD_output" :
"NULL");
99 buffer << indent <<
"simulator->output = SD_Output(\"";
100 buffer << _model.name() <<
"\",";
101 buffer << _model.outputNbr() <<
",";
102 buffer << _model.discreteNbr() <<
",";
103 buffer << _model.stateNbr() <<
",";
104 buffer << period <<
",";
105 buffer << ssize <<
",";
109 buffer << outputFunction <<
");" << endl;
110 buffer << indent <<
"SD_output modelOutput = simulator->output;" << endl;
114 void ModelInstance::configOutput()
116 if (!_model.outputNbr()) {
120 buffer <<
"SD_allocOutputMatrix(";
121 buffer <<
"modelOutput, ";
122 buffer << _model.stateNbr() <<
", ";
123 buffer << _model.discreteNbr() <<
");";
129 assert(out.isValid());
131 if (out.isRHSReference()) {
137 buffer << range.get();
138 tabs = range->block();
140 PartialEvalExp partial_eval;
141 Expression out_index_exp = partial_eval.apply(out.lhs().expression());
142 buffer << tabs <<
"sprintf(modelOutput->variable[" <<
Index(out_index_exp) <<
"].name, " << fp.
outputVariableName(var, range) <<
");";
144 buffer << endl << range->end();
150 void ModelInstance::output()
155 void ModelInstance::zeroCrossing()
160 void ModelInstance::handler()
167 ModelConfig::instance().clearLocalSymbols();
188 void ModelInstance::configEvents()
197 void ModelInstance::settings()
200 buffer <<
"settings->debug = " << _flags.debug() <<
";";
201 _writer->print(buffer);
202 buffer <<
"settings->parallel = ";
203 buffer << (_model.annotations().parallel() ?
"TRUE" :
"FALSE") <<
";";
204 _writer->print(buffer);
205 buffer <<
"settings->hybrid = ";
206 buffer << (_model.eventNbr() ?
"TRUE" :
"FALSE") <<
";";
207 _writer->print(buffer);
208 buffer <<
"settings->method = " <<
static_cast<int>(_model.annotations().solver()) <<
";";
209 _writer->print(buffer);
210 int random_seed = _model.annotations().getAnnotation(IntegerAnnotations::RandomSeed);
212 buffer <<
"settings->random_seed = " << random_seed <<
";";
213 _writer->print(buffer);
217 void ModelInstance::header()
220 VarSymbolTable::iterator it;
224 buffer << access_macro.
modelAccess(_model.discreteNbr(), _model.algebraicNbr());
226 if (ModelConfig::instance().isQss()) {
233 if (var.isModelVar()) {
234 Macros macros(_model, var);
235 buffer <<
"// Macros definition for variable: " << var.name() << endl;
236 buffer << macros << endl;
245 if (var.isParameter()) {
246 buffer <<
"// Macro for parameter: " << var.name() << endl;
247 buffer << var.declaration(
"__PAR__") << endl;
256 for (
Equation e = derivatives.
begin(eqit); !derivatives.
end(eqit); e = derivatives.
next(eqit)) {
257 buffer <<
"// Macros for equation: " << e.id() << endl;
258 buffer << e.macro() << endl;
262 if (algebraics.
size()) {
266 buffer <<
"// Macros for algebraic equation: " << e.id() << endl;
267 buffer << e.macro() << endl;
276 buffer <<
"// Macros for event: " << e.id() << endl;
277 buffer << e.macro() << endl;
281 if (ModelConfig::instance().isQss()) {
288 if (outputs.
size()) {
292 buffer <<
"// Macros for output equation: " << e.id() << endl;
293 buffer << e.macro() << endl;
296 if (outputs.
size()) {
307 buffer << endl <<
"// Jacobian Macros definition. " << endl;
309 buffer <<
"#define _assign_jac(r, val) \\" << endl;
310 buffer <<
" col_t = dvdx->df_dx_t->size[r] + dvdx->df_dx_t->index[r][0]; \\" << endl;
311 buffer <<
" dvdx->df_dx_t->index[r][0]++; \\" << endl;
312 buffer <<
" jac[col_t] = val;" << endl;
314 buffer <<
"#define _c_index(i) (i-1)";
317 buffer <<
"#define _time t";
323 string handler_q_param = (ModelConfig::instance().isQss()) ?
", double* q" :
"";
325 case MODEL_INSTANCE::Component::Model_Settings:
326 return "void MOD_settings(SD_simulationSettings settings)";
329 buffer <<
"void MOD_definition(";
330 if (ModelConfig::instance().isQss()) {
331 buffer <<
"int idx, ";
333 buffer <<
"double *x, double *d, double *a, double t, double *dx)";
336 case MODEL_INSTANCE::Component::Deps:
337 return "void MOD_dependencies(int idx, double *x, double *d, double *a, "
338 "double t, double *dx, int *map)";
340 return "void MOD_zeroCrossing(int idx, double *x, double *d, double *a, "
341 "double t, double *zc)";
343 return "void MOD_handlerPos(int idx, double *x" + handler_q_param +
344 ", double *d, double *a, "
347 return "void MOD_handlerNeg(int idx, double *x" + handler_q_param +
348 ", double *d, double *a, "
351 return "void MOD_output(int idx, double *x, double *d, double *a, double "
354 return "void MOD_jacobian(double *x, double *d, double *a, double t, "
355 "SD_jacMatrices dvdx, double *jac)";
356 case MODEL_INSTANCE::Component::BdfModel:
357 return "void MOD_BDF_definition(double *x, double *d, double *a, double t, double *dx, int *BDFMap, int nBDF)";
358 case MODEL_INSTANCE::Component::CLC_Init:
359 return "void CLC_initializeDataStructs(CLC_simulator simulator)";
360 case MODEL_INSTANCE::Component::QSS_Init:
361 return "void QSS_initializeDataStructs(QSS_simulator simulator)";
366 void ModelInstance::initialCode()
370 bool autonomous =
true;
371 ModelConfig::instance().setLocalInitSymbols();
372 ModelConfig::instance().setInitialCode(
true);
374 VarSymbolTable::iterator var_it;
376 if (var.isConstant()) {
383 autonomous = autonomous && stm.autonomous();
386 stringstream initial_time;
387 initial_time <<
"int t = " << _model.annotations().initialTime() <<
";";
388 ModelConfig::instance().addLocalSymbol(initial_time.str());
390 ModelConfig::instance().setInitialCode(
false);
391 ModelConfig::instance().unsetLocalInitSymbols();
394 void ModelInstance::inputs()
403 string ModelInstance::allocateModel()
406 buffer <<
"MOD_zeroCrossing, ";
407 buffer <<
"MOD_handlerPos, ";
408 buffer <<
"MOD_handlerNeg, ";
409 buffer <<
"MOD_jacobian";
413 void ModelInstance::allocateVector(
string name,
int size)
const
417 buffer <<
"int* " << name <<
" = (int*) malloc(" << size <<
"*sizeof(int));" << endl;
422 void ModelInstance::freeVector(
string name,
int size)
const
426 buffer <<
"free(" << name <<
");" << endl;
431 void ModelInstance::allocateVectors()
const
433 allocateVector(
"algebraics", _model.algebraicNbr());
434 allocateVector(
"states", _model.stateNbr());
435 allocateVector(
"discretes", _model.discreteNbr());
436 allocateVector(
"events", _model.eventNbr());
437 allocateVector(
"outputs", _model.outputNbr());
440 void ModelInstance::freeVectors()
const
442 freeVector(
"algebraics", _model.algebraicNbr());
443 freeVector(
"states", _model.stateNbr());
444 freeVector(
"discretes", _model.discreteNbr());
445 freeVector(
"events", _model.eventNbr());
446 freeVector(
"outputs", _model.outputNbr());
449 void ModelInstance::jacobian()
452 ModelConfig::instance().clearLocalSymbols();
454 _writer->write(
"int row, row_t, eq_var, c_row, c_row_g;",
WRITER::Jacobian);
466 void ModelInstance::generate()
476 _writer->print(componentDefinition(MODEL_INSTANCE::Component::Model_Settings));
477 _writer->beginBlock();
481 _writer->beginBlock();
487 _writer->beginBlock();
493 _writer->beginBlock();
499 _writer->beginBlock();
505 _writer->beginBlock();
511 _writer->beginBlock();
514 _writer->write(ModelConfig::instance().localInitSymbols(),
WRITER::Prologue);
519 QSSModelInstance::QSSModelInstance() :
ModelInstance(), _model(), _flags(), _writer() {}
553 buffer <<
"simulator->data = QSS_Data(" <<
_model.
stateNbr() <<
",";
561 buffer <<
"QSS_data modelData = simulator->data;" << endl;
562 buffer <<
"MODEL_DATA_ACCESS(modelData)" << endl;
569 buffer <<
"simulator->model = QSS_Model(MOD_definition, ";
570 buffer <<
"MOD_dependencies, ";
572 buffer <<
", MOD_BDF_definition);";
675 buffer <<
"// Derivative Macros definition. " << endl;
680 buffer <<
"// Derivative definition for variable: " << var.name() << endl;
681 buffer <<
"#define _der" << var << macros.
parameters() <<
" dx[coeff+1]";
745 buffer <<
"simulator->data = CLC_Data(" <<
_model.
stateNbr() <<
",";
753 buffer <<
"CLC_data modelData = simulator->data;" << endl;
754 buffer <<
"MODEL_DATA_ACCESS(modelData)" << endl;
761 buffer <<
"simulator->model = CLC_Model(MOD_definition, ";
796 buffer <<
"// Derivative Macros definition. " << endl;
801 stringstream arguments;
804 buffer <<
"// Derivative definition for variable: " << var.name() << endl;
805 buffer <<
"#define _der" << var << macros.
parameters() <<
" dx[" << arguments.str() <<
"]";