MicroModelicaCCompiler  4.5.3
model_instance.cpp
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  This file is part of QSSModelInstance Solver.
4 
5  QSSModelInstance Solver is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  QSSModelInstance Solver is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with QSSModelInstance Solver. If not, see
17  <http://www.gnu.org/licenses/>.
18 
19  ******************************************************************************/
20 
21 #include <boost/optional/optional_io.hpp>
22 #include <utility>
23 
24 #include "model_instance.hpp"
25 
26 #include <ast/expression.hpp>
27 #include <deps/builders/eq_graph_builder.hpp>
28 #include <generator/macros.hpp>
29 #include <ir/annotation.hpp>
30 #include <ir/class.hpp>
31 #include <ir/equation.hpp>
32 #include <ir/event.hpp>
33 #include <ir/expression.hpp>
34 #include <ir/jacobian.hpp>
35 #include <ir/qss_model.hpp>
36 #include <ir/qss_model_deps.hpp>
37 #include <ir/statement.hpp>
38 #include <util/error.hpp>
39 #include <util/util.hpp>
40 #include <util/visitors/partial_eval_exp.hpp>
41 
42 namespace MicroModelica {
43 
44 namespace Generator {
45 
46 using namespace MicroModelica::IR;
47 using namespace MicroModelica::Util;
48 using namespace MicroModelica::Deps;
49 
50 ModelInstance::ModelInstance() : _model(), _flags(), _writer() {}
51 
52 ModelInstance::ModelInstance(Model &model, CompileFlags &flags, WriterPtr writer) : _model(model), _flags(flags), _writer(writer) {}
53 
54 void ModelInstance::include()
55 {
56  stringstream buffer;
57  buffer << "#include <stdlib.h>" << endl;
58  buffer << "#include <stdio.h>" << endl;
59  buffer << "#include <string.h>" << endl;
60  buffer << "#include <math.h>" << endl;
61  buffer << endl;
62  buffer << "#include \"" << _model.name() << ".h\"" << endl;
63  if (_model.externalFunctions()) {
64  buffer << "#include \"" << _model.name() << "_functions.h\"" << endl;
65  }
66  ImportTable imports = _model.imports();
68  for (string i = imports.begin(it); !imports.end(it); i = imports.next(it)) {
69  buffer << "#include \"" << Utils::instance().packageName(i) << ".h\"" << endl;
70  }
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;
76  buffer << endl;
77  _writer->write(buffer, WRITER::Include);
78 }
79 
80 void ModelInstance::allocateOutput()
81 {
82  stringstream buffer;
83  ModelAnnotation annot = _model.annotations();
84  string period = "NULL";
85  string indent = "";
86  int ssize = 0;
87  if (annot.commInterval() == "CI_Sampled") {
88  indent = _writer->indent(1);
89  list<double> sample = annot.sample();
90  ssize = sample.size();
91  period = "period";
92  buffer << indent << "double period[" << ssize << "];" << endl;
93  int n = 0;
94  for (list<double>::iterator i = sample.begin(); i != sample.end(); i++) {
95  buffer << indent << "period[" << n << "] = " << *i << ";" << endl;
96  }
97  }
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 << ",";
106  buffer << annot.initialTime() << ",";
107  buffer << annot.commInterval() << ",";
108  buffer << annot.storeData() << ",";
109  buffer << outputFunction << ");" << endl;
110  buffer << indent << "SD_output modelOutput = simulator->output;" << endl;
111  _writer->write(buffer, WRITER::Alloc_Output);
112 }
113 
114 void ModelInstance::configOutput()
115 {
116  if (!_model.outputNbr()) {
117  return;
118  }
119  stringstream buffer;
120  buffer << "SD_allocOutputMatrix(";
121  buffer << "modelOutput, ";
122  buffer << _model.stateNbr() << ", ";
123  buffer << _model.discreteNbr() << ");";
124  _writer->write(buffer, WRITER::Alloc_Output);
125  EquationTable outputs = _model.outputs();
127  FunctionPrinter fp;
128  for (Equation out = outputs.begin(it); !outputs.end(it); out = outputs.next(it)) {
129  assert(out.isValid());
130  Expression var = out.lhs();
131  if (out.isRHSReference()) {
132  var = out.rhs();
133  }
134  string tabs = "";
135  Option<Range> range = out.range();
136  if (range) {
137  buffer << range.get();
138  tabs = range->block();
139  }
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) << ");";
143  if (range) {
144  buffer << endl << range->end();
145  }
146  _writer->write(buffer, WRITER::Alloc_Output);
147  }
148 }
149 
150 void ModelInstance::output()
151 {
152  generateDef<OutputModelGen>(_model.outputs(), WRITER::Output, WRITER::Output_Simple, WRITER::Output_Generic);
153 }
154 
155 void ModelInstance::zeroCrossing()
156 {
157  generateDef<ZCModelGen>(zeroCrossingTable(_model.events()), WRITER::Zero_Crossing, WRITER::ZC_Simple, WRITER::ZC_Generic);
158 }
159 
160 void ModelInstance::handler()
161 {
162  EventTable events = _model.events();
164  VarSymbolTable symbols = _model.symbols();
165  stringstream buffer;
166  FunctionPrinter fp;
167  ModelConfig::instance().clearLocalSymbols();
168  for (Event event = events.begin(it); !events.end(it); event = events.next(it)) {
169  _writer->write(event.handler(EVENT::Positive), (event.hasRange() ? WRITER::Handler_Pos_Generic : WRITER::Handler_Pos_Simple));
170  _writer->write(event.handler(EVENT::Negative), (event.hasRange() ? WRITER::Handler_Neg_Generic : WRITER::Handler_Neg_Simple));
171  }
172  if (!_writer->isEmpty(WRITER::Handler_Pos_Generic)) {
173  _writer->write(ModelConfig::instance().localSymbols(), WRITER::Handler_Pos);
174  }
175  if (!_writer->isEmpty(WRITER::Handler_Neg_Generic)) {
176  _writer->write(ModelConfig::instance().localSymbols(), WRITER::Handler_Neg);
177  }
178  if (!_writer->isEmpty(WRITER::Handler_Pos_Simple)) {
179  _writer->write(fp.beginSwitch(), WRITER::Handler_Pos);
180  _writer->write(fp.endSwitch(), WRITER::Handler_Pos_Simple);
181  }
182  if (!_writer->isEmpty(WRITER::Handler_Neg_Simple)) {
183  _writer->write(fp.beginSwitch(), WRITER::Handler_Neg);
184  _writer->write(fp.endSwitch(), WRITER::Handler_Neg_Simple);
185  }
186 }
187 
188 void ModelInstance::configEvents()
189 {
190  EventTable events = _model.events();
192  for (Event event = events.begin(it); !events.end(it); event = events.next(it)) {
193  _writer->write(event.config(), WRITER::Init_Data);
194  }
195 }
196 
197 void ModelInstance::settings()
198 {
199  stringstream buffer;
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);
211  if (random_seed) {
212  buffer << "settings->random_seed = " << random_seed << ";";
213  _writer->print(buffer);
214  }
215 }
216 
217 void ModelInstance::header()
218 {
219  VarSymbolTable symbols = _model.symbols();
220  VarSymbolTable::iterator it;
221  stringstream buffer;
222  _writer->write("// Model data access macro.\n\n", WRITER::Model_Header);
223  Macros access_macro;
224  buffer << access_macro.modelAccess(_model.discreteNbr(), _model.algebraicNbr());
225  _writer->write(buffer, WRITER::Model_Header);
226  if (ModelConfig::instance().isQss()) {
227  _writer->write("// Coeff multipliers definition.\n\n", WRITER::Model_Header);
228  buffer << access_macro.coeffMultipliers(_model.annotations().order());
229  _writer->write(buffer, WRITER::Model_Header);
230  }
231  _writer->write("// Model Variables Macros\n\n", WRITER::Model_Header);
232  for (Variable var = symbols.begin(it); !symbols.end(it); var = symbols.next(it)) {
233  if (var.isModelVar()) {
234  Macros macros(_model, var);
235  buffer << "// Macros definition for variable: " << var.name() << endl;
236  buffer << macros << endl;
237  ;
238  }
239  }
240  _writer->write(buffer, WRITER::Model_Header);
241  if (symbols.parameters()) {
242  _writer->write("\n// Model Parameters Declaration\n\n", WRITER::Model_Header);
243  }
244  for (Variable var = symbols.begin(it); !symbols.end(it); var = symbols.next(it)) {
245  if (var.isParameter()) {
246  buffer << "// Macro for parameter: " << var.name() << endl;
247  buffer << var.declaration("__PAR__") << endl;
248  }
249  _writer->write(buffer, WRITER::Model_Header);
250  }
251  EquationTable derivatives = _model.derivatives();
253  if (derivatives.size()) {
254  _writer->write("\n// Derivative Equations Macros\n\n", WRITER::Model_Header);
255  }
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;
259  _writer->write(buffer, WRITER::Model_Header);
260  }
261  EquationTable algebraics = _model.algebraics();
262  if (algebraics.size()) {
263  _writer->write("\n// Algebraic Equations Macros\n\n", WRITER::Model_Header);
264  }
265  for (Equation e = algebraics.begin(eqit); !algebraics.end(eqit); e = algebraics.next(eqit)) {
266  buffer << "// Macros for algebraic equation: " << e.id() << endl;
267  buffer << e.macro() << endl;
268  _writer->write(buffer, WRITER::Model_Header);
269  }
270  EventTable events = _model.events();
271  if (events.size()) {
272  _writer->write("\n// Event Macros\n\n", WRITER::Model_Header);
273  }
275  for (Event e = events.begin(eit); !events.end(eit); e = events.next(eit)) {
276  buffer << "// Macros for event: " << e.id() << endl;
277  buffer << e.macro() << endl;
278  _writer->write(buffer, WRITER::Model_Header);
279  }
280  if (events.size()) {
281  if (ModelConfig::instance().isQss()) {
282  _writer->write("#define _zc(coeff) zc[coeff]", WRITER::Model_Header);
283  } else {
284  _writer->write("#define _zc zc[0]", WRITER::Model_Header);
285  }
286  }
287  EquationTable outputs = _model.outputs();
288  if (outputs.size()) {
289  _writer->write("\n// Output Equations Macros\n\n", WRITER::Model_Header);
290  }
291  for (Equation e = outputs.begin(eqit); !outputs.end(eqit); e = outputs.next(eqit)) {
292  buffer << "// Macros for output equation: " << e.id() << endl;
293  buffer << e.macro() << endl;
294  _writer->write(buffer, WRITER::Model_Header);
295  }
296  if (outputs.size()) {
297  _writer->write("#define _out out[0]", WRITER::Model_Header);
298  }
299  InputTable inputs = _model.inputs();
300  if (inputs.size()) {
301  _writer->write("\n// Input Matrix Macros\n\n", WRITER::Model_Header);
302  }
304  for (Input i = inputs.begin(iit); !inputs.end(iit); i = inputs.next(iit)) {
305  _writer->write(i.macro(), WRITER::Model_Header);
306  }
307  buffer << endl << "// Jacobian Macros definition. " << endl;
308  _writer->write(buffer, WRITER::Model_Header);
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;
313  _writer->write(buffer, WRITER::Model_Header);
314  buffer << "#define _c_index(i) (i-1)";
315  _writer->write(buffer, WRITER::Model_Header);
316  buffer << endl;
317  buffer << "#define _time t";
318  _writer->write(buffer, WRITER::Model_Header);
319 }
320 
321 string ModelInstance::componentDefinition(MODEL_INSTANCE::Component c)
322 {
323  string handler_q_param = (ModelConfig::instance().isQss()) ? ", double* q" : "";
324  switch (c) {
325  case MODEL_INSTANCE::Component::Model_Settings:
326  return "void MOD_settings(SD_simulationSettings settings)";
328  stringstream buffer;
329  buffer << "void MOD_definition(";
330  if (ModelConfig::instance().isQss()) {
331  buffer << "int idx, ";
332  }
333  buffer << "double *x, double *d, double *a, double t, double *dx)";
334  return buffer.str();
335  }
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, "
345  "double t)";
347  return "void MOD_handlerNeg(int idx, double *x" + handler_q_param +
348  ", double *d, double *a, "
349  "double t)";
351  return "void MOD_output(int idx, double *x, double *d, double *a, double "
352  "t, double *out)";
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)";
362  }
363  return "";
364 }
365 
366 void ModelInstance::initialCode()
367 {
368  StatementTable stms = _model.initialCode();
370  bool autonomous = true;
371  ModelConfig::instance().setLocalInitSymbols();
372  ModelConfig::instance().setInitialCode(true);
373  VarSymbolTable symbols = _model.symbols();
374  VarSymbolTable::iterator var_it;
375  for (Variable var = symbols.begin(var_it); !symbols.end(var_it); var = symbols.next(var_it)) {
376  if (var.isConstant()) {
377  continue;
378  }
379  _writer->write(var.initialization(), WRITER::Init_Code);
380  }
381  for (Statement stm = stms.begin(it); !stms.end(it); stm = stms.next(it)) {
382  _writer->write(stm, WRITER::Init_Code);
383  autonomous = autonomous && stm.autonomous();
384  }
385  if (!autonomous) {
386  stringstream initial_time;
387  initial_time << "int t = " << _model.annotations().initialTime() << ";";
388  ModelConfig::instance().addLocalSymbol(initial_time.str());
389  }
390  ModelConfig::instance().setInitialCode(false);
391  ModelConfig::instance().unsetLocalInitSymbols();
392 }
393 
394 void ModelInstance::inputs()
395 {
396  InputTable inputs = _model.inputs();
398  for (Input input = inputs.begin(it); !inputs.end(it); input = inputs.next(it)) {
399  _writer->write(input, WRITER::Input);
400  }
401 }
402 
403 string ModelInstance::allocateModel()
404 {
405  stringstream buffer;
406  buffer << "MOD_zeroCrossing, ";
407  buffer << "MOD_handlerPos, ";
408  buffer << "MOD_handlerNeg, ";
409  buffer << "MOD_jacobian";
410  return buffer.str();
411 }
412 
413 void ModelInstance::allocateVector(string name, int size) const
414 {
415  stringstream buffer;
416  if (size) {
417  buffer << "int* " << name << " = (int*) malloc(" << size << "*sizeof(int));" << endl;
418  _writer->write(buffer, WRITER::Prologue);
419  }
420 }
421 
422 void ModelInstance::freeVector(string name, int size) const
423 {
424  stringstream buffer;
425  if (size) {
426  buffer << "free(" << name << ");" << endl;
427  _writer->write(buffer, WRITER::Epilogue);
428  }
429 }
430 
431 void ModelInstance::allocateVectors() const
432 {
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());
438 }
439 
440 void ModelInstance::freeVectors() const
441 {
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());
447 }
448 
449 void ModelInstance::jacobian()
450 {
451  Jacobian jac;
452  ModelConfig::instance().clearLocalSymbols();
453  jac.build();
454  _writer->write("int row, row_t, eq_var, c_row, c_row_g;", WRITER::Jacobian);
455  _writer->write("int col, col_g, col_t;", WRITER::Jacobian);
456  _writer->write("int x_ind;", WRITER::Jacobian);
457  _writer->write("double aux;", WRITER::Jacobian);
458  _writer->write(ModelConfig::instance().localSymbols(), WRITER::Jacobian);
459  _writer->write("SD_cleanJacMatrices(dvdx);", WRITER::Jacobian);
460  _writer->write(jac.code(), WRITER::Jacobian);
461  // Add local variables to the initialization procedure prologue.
462  _writer->write("int row, eq_var, c_row;", WRITER::Prologue);
463  _writer->write("int x_ind;", WRITER::Prologue);
464 }
465 
466 void ModelInstance::generate()
467 {
468  include();
469  zeroCrossing();
470  handler();
471  output();
472  initialCode();
473  jacobian();
474  // Print generated Model Instance.
475  _writer->print(WRITER::Include);
476  _writer->print(componentDefinition(MODEL_INSTANCE::Component::Model_Settings));
477  _writer->beginBlock();
478  settings();
479  _writer->endBlock();
480  _writer->print(componentDefinition(MODEL_INSTANCE::Component::Model));
481  _writer->beginBlock();
482  _writer->print(WRITER::Model);
483  _writer->print(WRITER::Model_Simple);
484  _writer->print(WRITER::Model_Generic);
485  _writer->endBlock();
486  _writer->print(componentDefinition(MODEL_INSTANCE::Component::Zero_Crossing));
487  _writer->beginBlock();
488  _writer->print(WRITER::Zero_Crossing);
489  _writer->print(WRITER::ZC_Simple);
490  _writer->print(WRITER::ZC_Generic);
491  _writer->endBlock();
492  _writer->print(componentDefinition(MODEL_INSTANCE::Component::Handler_Pos));
493  _writer->beginBlock();
494  _writer->print(WRITER::Handler_Pos);
495  _writer->print(WRITER::Handler_Pos_Simple);
496  _writer->print(WRITER::Handler_Pos_Generic);
497  _writer->endBlock();
498  _writer->print(componentDefinition(MODEL_INSTANCE::Component::Handler_Neg));
499  _writer->beginBlock();
500  _writer->print(WRITER::Handler_Neg);
501  _writer->print(WRITER::Handler_Neg_Simple);
503  _writer->endBlock();
504  _writer->print(componentDefinition(MODEL_INSTANCE::Component::Output));
505  _writer->beginBlock();
506  _writer->print(WRITER::Output);
507  _writer->print(WRITER::Output_Simple);
508  _writer->print(WRITER::Output_Generic);
509  _writer->endBlock();
510  _writer->print(componentDefinition(MODEL_INSTANCE::Component::Jacobian));
511  _writer->beginBlock();
512  _writer->print(WRITER::Jacobian);
513  _writer->endBlock();
514  _writer->write(ModelConfig::instance().localInitSymbols(), WRITER::Prologue);
515 }
516 
517 /* QSSModelInstance Model Instance class. */
518 
519 QSSModelInstance::QSSModelInstance() : ModelInstance(), _model(), _flags(), _writer() {}
520 
522  : ModelInstance(model, flags, writer), _model(model), _flags(flags), _writer(writer)
523 {
524 }
525 
527 {
529 }
530 
532 {
534 }
535 
537 {
538  bool sym_diff = ModelConfig::instance().symDiff();
540  _writer->write("int idx;", WRITER::Model_Bdf);
541  _writer->write("int __bdf_it;", WRITER::Model_Bdf);
542  _writer->write("for(__bdf_it = 0; __bdf_it < nBDF; __bdf_it++) {", WRITER::Model_Bdf);
543  _writer->write("idx = BDFMap[__bdf_it];", WRITER::Model_Bdf);
545  _writer->write("}", WRITER::Model_Bdf_Generic);
546  ModelConfig::instance().setSymDiff(sym_diff);
547 }
548 
550 {
552  stringstream buffer;
553  buffer << "simulator->data = QSS_Data(" << _model.stateNbr() << ",";
554  buffer << _model.discreteNbr() << ",";
555  buffer << _model.eventNbr() << ",";
556  buffer << _model.inputNbr() << ",";
557  buffer << _model.algebraicNbr() << ",";
558  buffer << _model.derivatives().size() << ",";
559  buffer << _model.algebraics().size() << ",\"";
560  buffer << _model.name() << "\");" << endl;
561  buffer << "QSS_data modelData = simulator->data;" << endl;
562  buffer << "MODEL_DATA_ACCESS(modelData)" << endl;
563  _writer->write(buffer, WRITER::Prologue);
564 }
565 
567 {
568  stringstream buffer;
569  buffer << "simulator->model = QSS_Model(MOD_definition, ";
570  buffer << "MOD_dependencies, ";
571  buffer << ModelInstance::allocateModel();
572  buffer << ", MOD_BDF_definition);";
573  return buffer.str();
574 }
575 
577 {
578  stringstream buffer;
579  buffer << "simulator->time = QSS_Time(" << _model.stateNbr() << "," << _model.eventNbr() << "," << _model.inputNbr() << ","
580  << _model.annotations().initialTime() << "," << _model.annotations().scheduler() << ", NULL);" << endl;
581  _writer->write(buffer, WRITER::Init_Data);
582 }
583 
585 {
586  stringstream buffer;
588  const bool PARALLEL = _model.annotations().parallel();
589  allocateSolver();
590  allocateVectors();
591  freeVectors();
592  ModelDependencies deps = _model.dependencies();
593  // Initialize Solver Data Structures.
596  inputs();
597 
598  // Initialize Jacobian matrices.
600 
601  // Initialize Event Data Structures.
604 
610  if (PARALLEL) {
614  }
615  configEvents();
616  _writer->write("QSS_allocDataMatrix(modelData);", WRITER::Alloc_Data);
617  _writer->write("SD_setupJacMatrices(modelData->jac_matrices);", WRITER::Init_Data);
618  // Initialize Output Data Structures.
619  allocateOutput();
624  initTime();
625  configOutput();
626  allocateModel();
628 }
629 
631 
633 {
634  definition();
635  dependencies();
636  bdfDefinition();
640  _writer->beginBlock();
641  _writer->print(WRITER::Model_Deps);
644  _writer->endBlock();
646  _writer->beginBlock();
647  _writer->print(WRITER::Model_Bdf);
650  _writer->endBlock();
652  _writer->beginBlock();
653  _writer->print(WRITER::Prologue);
654  _writer->print(WRITER::Init_Code);
655  _writer->print(WRITER::Alloc_Data);
656  _writer->print(WRITER::Init_Data);
657  _writer->print(WRITER::Input);
660  _writer->print(allocateModel());
661  _writer->print(WRITER::Epilogue);
662  _writer->endBlock();
664  _writer->beginBlock();
665  _writer->endBlock();
666 }
667 
669 {
671  VarSymbolTable symbols = _model.symbols();
673  stringstream buffer;
674  buffer << endl;
675  buffer << "// Derivative Macros definition. " << endl;
676  _writer->write(buffer, WRITER::Model_Header);
677  for (Variable var = symbols.begin(it); !symbols.end(it); var = symbols.next(it)) {
678  if (var.isState()) {
679  Macros macros(_model, var);
680  buffer << "// Derivative definition for variable: " << var.name() << endl;
681  buffer << "#define _der" << var << macros.parameters() << " dx[coeff+1]";
682  _writer->write(buffer, WRITER::Model_Header);
683  }
684  }
685 }
686 
687 /* ClassicModelInstance Model Instance class. */
688 
690  : ModelInstance(model, flags, writer), _model(model), _flags(flags), _writer(writer)
691 {
692 }
693 
695 {
696  EquationTable derivatives = _model.derivatives();
697  EquationTable algebraics = _model.algebraics();
699  VarSymbolTable symbols = _model.symbols();
700  stringstream buffer;
702  for (Equation alg = algebraics.begin(it); !algebraics.end(it); alg = algebraics.next(it)) {
703  _writer->write(alg, WRITER::Model_Simple);
704  }
705  for (Equation der = derivatives.begin(it); !derivatives.end(it); der = derivatives.next(it)) {
706  _writer->write(der, WRITER::Model_Simple);
707  }
708  _writer->write(ModelConfig::instance().localSymbols(), WRITER::Model);
709 }
710 
712 {
713  stringstream buffer;
715  allocateSolver();
716  allocateVectors();
717  freeVectors();
718  ModelDependencies deps = _model.dependencies();
719  // Initialize Solver Data Structures.
722  configEvents();
723  inputs();
724  // Initialize Jacobian matrices.
726 
727  _writer->write("CLC_allocDataMatrix(modelData);", WRITER::Alloc_Data);
728  _writer->write("SD_setupJacMatrices(modelData->jac_matrices);", WRITER::Init_Data);
729 
730  // Initialize Output Data Structures.
731  allocateOutput();
736  configOutput();
737  allocateModel();
739 }
740 
742 {
744  stringstream buffer;
745  buffer << "simulator->data = CLC_Data(" << _model.stateNbr() << ",";
746  buffer << _model.discreteNbr() << ",";
747  buffer << _model.eventNbr() << ",";
748  buffer << _model.inputNbr() << ",";
749  buffer << _model.algebraicNbr() << ",";
750  buffer << _model.derivatives().size() << ",";
751  buffer << _model.algebraics().size() << ",\"";
752  buffer << _model.name() << "\");" << endl;
753  buffer << "CLC_data modelData = simulator->data;" << endl;
754  buffer << "MODEL_DATA_ACCESS(modelData)" << endl;
755  _writer->write(buffer, WRITER::Prologue);
756 }
757 
759 {
760  stringstream buffer;
761  buffer << "simulator->model = CLC_Model(MOD_definition, ";
762  buffer << ModelInstance::allocateModel();
763  buffer << ");";
764  return buffer.str();
765 }
766 
768 {
769  definition();
773  _writer->beginBlock();
774  _writer->print(WRITER::Prologue);
775  _writer->print(WRITER::Init_Code);
776  _writer->print(WRITER::Alloc_Data);
778  _writer->print(WRITER::Input);
781  _writer->print(allocateModel());
782  _writer->print(WRITER::Epilogue);
783  _writer->endBlock();
785  _writer->beginBlock();
786  _writer->endBlock();
787 }
788 
790 {
792  VarSymbolTable symbols = _model.symbols();
794  stringstream buffer;
795  buffer << endl;
796  buffer << "// Derivative Macros definition. " << endl;
797  _writer->write(buffer, WRITER::Model_Header);
798  for (Variable var = symbols.begin(it); !symbols.end(it); var = symbols.next(it)) {
799  if (var.isState()) {
800  stringstream buffer;
801  stringstream arguments;
802  Macros macros(_model, var);
803  arguments << macros.engineIndexArguments();
804  buffer << "// Derivative definition for variable: " << var.name() << endl;
805  buffer << "#define _der" << var << macros.parameters() << " dx[" << arguments.str() << "]";
806  _writer->write(buffer, WRITER::Model_Header);
807  }
808  }
809 }
810 
811 } // namespace Generator
812 } // namespace MicroModelica
MicroModelica::Generator::ModelInstance
Definition: model_instance.hpp:90
MicroModelica::Generator::MODEL_INSTANCE::Component
Component
Definition: model_instance.hpp:89
MicroModelica::IR::FunctionPrinter
Definition: helpers.hpp:147
MicroModelica::Generator::Generator::_writer
WriterPtr _writer
Definition: generator.hpp:103
MicroModelica::IR::EVENT::Positive
@ Positive
HND_POSITIVE.
Definition: event.hpp:102
ModelTable< std::string, std::string >
MicroModelica::Util
Definition: equation.hpp:44
ModelTable::begin
iterator begin()
Definition: table.hpp:68
MicroModelica::Generator::ModelInstance::inputs
void inputs()
Definition: model_instance.cpp:430
MicroModelica::IR::Model::algebraics
EquationTable algebraics()
Definition: class.hpp:190
MicroModelica::Util::VarSymbolTable
Definition: symbol_table.hpp:184
MicroModelica::Util::Variable
Definition: symbol_table.hpp:75
MicroModelica::IR::Jacobian
Definition: jacobian.hpp:105
MicroModelica::IR::ModelAnnotation::initialTime
double initialTime()
Definition: annotation.cpp:652
MicroModelica::Generator::ModelInstance::allocateModel
std::string allocateModel()
Definition: model_instance.cpp:439
MicroModelica::Generator::MODEL_INSTANCE::Component::QSS_Init
@ QSS_Init
MicroModelica::IR::Model::inputNbr
int inputNbr() const
Definition: class.hpp:182
MicroModelica::Generator::WRITER::ZC_Generic
@ ZC_Generic
Definition: writer.hpp:90
MicroModelica::Generator::WRITER::Model
@ Model
Definition: writer.hpp:79
MicroModelica::Generator::ClassicModelInstance::ClassicModelInstance
ClassicModelInstance(IR::Model &model, Util::CompileFlags &flags, WriterPtr writer)
Definition: model_instance.cpp:725
expression.hpp
MicroModelica::IR::Model::dependencies
Deps::ModelDependencies dependencies()
Definition: class.hpp:191
MicroModelica::Generator::WRITER::Handler_Neg
@ Handler_Neg
Definition: writer.hpp:94
MicroModelica::Generator::WRITER::Jacobian
@ Jacobian
Definition: writer.hpp:97
macros.hpp
MicroModelica::Generator::QSSModelInstance::QSSModelInstance
QSSModelInstance()
Definition: model_instance.cpp:555
MicroModelica::IR::FunctionPrinter::endSwitch
std::string endSwitch()
Definition: helpers.cpp:217
MicroModelica::Generator::WRITER::Model_Header
@ Model_Header
Definition: writer.hpp:103
MicroModelica::Util::CompileFlags
Definition: compile_flags.hpp:65
MicroModelica::Generator::WRITER::Handler_Neg_Simple
@ Handler_Neg_Simple
Definition: writer.hpp:95
event.hpp
MicroModelica::IR::Jacobian::build
void build()
Definition: jacobian.cpp:296
qss_model.hpp
MicroModelica::Generator::ClassicModelInstance::generate
void generate() override
Definition: model_instance.cpp:803
MicroModelica::IR::Model::algebraicNbr
int algebraicNbr() const
Definition: class.hpp:179
MicroModelica::Generator::QSSModelInstance::_model
IR::Model _model
Definition: model_instance.hpp:172
Option
Definition: util_types.hpp:32
MicroModelica::Generator::ClassicModelInstance::definition
void definition() override
Definition: model_instance.cpp:730
MicroModelica::IR::Model::symbols
Util::VarSymbolTable symbols() const
Definition: class.cpp:284
MicroModelica::Generator::WRITER::Alloc_Data
@ Alloc_Data
Definition: writer.hpp:72
MicroModelica::Generator::WRITER::Model_Deps_Generic
@ Model_Deps_Generic
Definition: writer.hpp:84
MicroModelica::Util::ModelConfig::setSymDiff
void setSymDiff(bool sym_diff)
Definition: model_config.hpp:118
MicroModelica::Generator::WRITER::Handler_Pos
@ Handler_Pos
Definition: writer.hpp:91
MicroModelica::Generator::QSSModelInstance::allocateSolver
void allocateSolver()
Definition: model_instance.cpp:585
MicroModelica::Generator::QSSModelInstance::allocateModel
std::string allocateModel()
Definition: model_instance.cpp:602
MicroModelica::Generator::ModelInstance::generate
virtual void generate()
Definition: model_instance.cpp:502
MicroModelica::Generator::WRITER::Model_Bdf_Generic
@ Model_Bdf_Generic
Definition: writer.hpp:87
MicroModelica::IR::zeroCrossingTable
EquationTable zeroCrossingTable(EventTable events)
Helper function to to generate a equation table for zero crossing equations.
Definition: event.cpp:182
MicroModelica::Util::ModelConfig::setLocalInitSymbols
void setLocalInitSymbols()
Definition: model_config.hpp:137
MicroModelica::Generator::WRITER::Handler_Pos_Generic
@ Handler_Pos_Generic
Definition: writer.hpp:93
MicroModelica::IR::Model::eventNbr
int eventNbr() const
Definition: class.hpp:184
MicroModelica::IR::Expression
Definition: expression.hpp:64
MicroModelica::Generator::ClassicModelInstance::_writer
WriterPtr _writer
Definition: model_instance.hpp:194
MicroModelica::Generator::QSSModelInstance::_writer
WriterPtr _writer
Definition: model_instance.hpp:174
ModelTable::end
iterator end()
Definition: table.hpp:70
MicroModelica::Deps
Definition: node_selector.cpp:44
MicroModelica::IR::ModelAnnotation
Definition: annotation.hpp:121
MicroModelica::Generator::WRITER::Model_Simple
@ Model_Simple
Definition: writer.hpp:80
MicroModelica::Generator::ModelInstance::allocateOutput
void allocateOutput()
Definition: model_instance.cpp:116
MicroModelica::Generator::ModelInstance::componentDefinition
std::string componentDefinition(MODEL_INSTANCE::Component c)
Definition: model_instance.cpp:357
MicroModelica::IR::Model::BDFDerivatives
EquationTable BDFDerivatives()
Definition: class.cpp:494
MicroModelica::Generator::QSSModelInstance::initTime
void initTime()
Definition: model_instance.cpp:612
MicroModelica::IR::Equation
Definition: equation.hpp:67
MicroModelica::Generator::WRITER::Output_Generic
@ Output_Generic
Definition: writer.hpp:100
MicroModelica::Generator::WRITER::Alloc_Output
@ Alloc_Output
Definition: writer.hpp:74
MicroModelica::IR::ModelAnnotation::sample
list< double > sample()
Definition: annotation.cpp:678
MicroModelica::IR::Event
Definition: event.hpp:84
equation.hpp
MicroModelica::IR::Model::derivatives
EquationTable derivatives()
Definition: class.hpp:188
MicroModelica::Generator::WRITER::ZC_Simple
@ ZC_Simple
Definition: writer.hpp:89
ModelTable< std::string, std::string >::iterator
std::map< std::string, std::string >::iterator iterator
Definition: table.hpp:61
MicroModelica::Util::ModelConfig::instance
static ModelConfig & instance()
Definition: model_config.hpp:87
MicroModelica::IR::Input
Definition: helpers.hpp:179
MicroModelica::Generator::WRITER::Output
@ Output
Definition: writer.hpp:98
MicroModelica::Util::ModelConfig::unsetLocalInitSymbols
void unsetLocalInitSymbols()
Definition: model_config.hpp:138
MicroModelica::Generator::Macros::engineIndexArguments
std::string engineIndexArguments() const
Definition: macros.cpp:90
MicroModelica::Generator::QSSModelInstance::initializeDataStructures
void initializeDataStructures() override
Definition: model_instance.cpp:620
MicroModelica::Generator::WRITER::Handler_Neg_Generic
@ Handler_Neg_Generic
Definition: writer.hpp:96
MicroModelica::Generator::Macros
Definition: macros.hpp:71
MicroModelica::Generator::Macros::coeffMultipliers
std::string coeffMultipliers(int order)
Definition: macros.cpp:255
MicroModelica::Generator::ModelInstance::ModelInstance
ModelInstance()
Definition: model_instance.cpp:86
MicroModelica::Generator::QSSModelInstance::bdfDefinition
void bdfDefinition()
Definition: model_instance.cpp:572
MicroModelica::IR::ModelAnnotation::commInterval
string commInterval()
Definition: annotation.cpp:676
MicroModelica::Generator::ModelInstance::allocateVectors
void allocateVectors() const
Definition: model_instance.cpp:467
MicroModelica::IR::FunctionPrinter::beginSwitch
std::string beginSwitch()
Definition: helpers.cpp:210
MicroModelica::Generator::WRITER::Handler_Pos_Simple
@ Handler_Pos_Simple
Definition: writer.hpp:92
MicroModelica::Generator::ModelInstance::initializeMatrix
void initializeMatrix(DM vdm, WRITER::Section alloc, WRITER::Section init, int size)
Definition: model_instance.hpp:120
MicroModelica::Generator::WRITER::Model_Deps
@ Model_Deps
Definition: writer.hpp:82
MicroModelica::Generator::Generator::_flags
Util::CompileFlags _flags
Definition: generator.hpp:101
MicroModelica::Generator::ClassicModelInstance::header
void header() override
Definition: model_instance.cpp:825
MicroModelica::IR::Jacobian::code
std::string code()
Definition: jacobian.cpp:310
MicroModelica::Generator::ClassicModelInstance::initializeDataStructures
void initializeDataStructures() override
Definition: model_instance.cpp:747
MicroModelica::IR::Index
Definition: index.hpp:92
MicroModelica::Generator::WRITER::Epilogue
@ Epilogue
Definition: writer.hpp:71
MicroModelica::Generator::QSSModelInstance::computationalGraph
Graph computationalGraph() override
Definition: model_instance.cpp:666
MicroModelica::Generator::ModelInstance::freeVectors
void freeVectors() const
Definition: model_instance.cpp:476
MicroModelica::IR::EVENT::Negative
@ Negative
HND_NEGATIVE.
Definition: event.hpp:103
MicroModelica::Generator::Macros::parameters
std::string parameters(MACROS::Offset offset=MACROS::Modelica) const
Definition: macros.cpp:39
MicroModelica::Generator::MODEL_INSTANCE::Component::Deps
@ Deps
model_instance.hpp
MicroModelica::Generator::QSSModelInstance::header
void header() override
Definition: model_instance.cpp:704
MicroModelica::IR::FunctionPrinter::outputVariableName
std::string outputVariableName(Expression exp, Option< Range > range)
Definition: helpers.cpp:401
MicroModelica
Definition: files.cpp:45
MicroModelica::Generator::ModelInstance::header
virtual void header()
Definition: model_instance.cpp:253
MicroModelica::Generator::ClassicModelInstance::allocateModel
std::string allocateModel()
Definition: model_instance.cpp:794
MicroModelica::Util::ModelConfig::symDiff
bool symDiff() const
Definition: model_config.hpp:119
MicroModelica::Generator::MODEL_INSTANCE::Component::CLC_Init
@ CLC_Init
MicroModelica::Generator::WRITER::Output_Simple
@ Output_Simple
Definition: writer.hpp:99
MicroModelica::IR::ModelAnnotation::storeData
string storeData()
Definition: annotation.cpp:662
MicroModelica::IR::Model::outputNbr
int outputNbr() const
Definition: class.hpp:183
MicroModelica::Generator::WRITER::Init_Output
@ Init_Output
Definition: writer.hpp:76
MicroModelica::IR::Model
Definition: class.hpp:160
MicroModelica::Generator::WRITER::Include
@ Include
Definition: writer.hpp:75
MicroModelica::Generator::WRITER::Model_Bdf_Simple
@ Model_Bdf_Simple
Definition: writer.hpp:86
MicroModelica::IR::ModelAnnotation::parallel
bool parallel()
Definition: annotation.cpp:700
MicroModelica::Generator::ClassicModelInstance::allocateSolver
void allocateSolver()
Definition: model_instance.cpp:777
MicroModelica::IR::Statement
Definition: statement.hpp:54
MicroModelica::Generator::WRITER::Model_Deps_Simple
@ Model_Deps_Simple
Definition: writer.hpp:83
MicroModelica::Generator::ModelInstance::configOutput
void configOutput()
Definition: model_instance.cpp:150
MicroModelica::Generator::MODEL_INSTANCE::Component::BdfModel
@ BdfModel
MicroModelica::Generator::QSSModelInstance::definition
void definition() override
Definition: model_instance.cpp:562
Graph
Definition: graph.hpp:30
MicroModelica::Util::VarSymbolTable::parameters
bool parameters() const
Definition: symbol_table.hpp:190
ModelTable::size
const int size() const
Definition: table.hpp:109
MicroModelica::Generator::WRITER::Prologue
@ Prologue
Definition: writer.hpp:70
MicroModelica::IR::Model::discreteNbr
int discreteNbr() const
Definition: class.hpp:181
MicroModelica::Generator::WRITER::Input
@ Input
Definition: writer.hpp:78
MicroModelica::Generator::ModelInstance::configEvents
void configEvents()
Definition: model_instance.cpp:224
MicroModelica::Generator::WRITER::Model_Generic
@ Model_Generic
Definition: writer.hpp:81
MicroModelica::IR::ModelAnnotation::scheduler
string scheduler()
Definition: annotation.cpp:680
annotation.hpp
MicroModelica::Generator::QSSModelInstance::dependencies
void dependencies()
Definition: model_instance.cpp:567
MicroModelica::IR::Model::annotations
ModelAnnotation annotations() const
Definition: class.hpp:177
MicroModelica::Generator::QSSModelInstance::generate
void generate() override
Definition: model_instance.cpp:668
jacobian.hpp
MicroModelica::IR
Definition: alg_usage.cpp:47
qss_model_deps.hpp
MicroModelica::Util::ModelConfig::clearLocalSymbols
void clearLocalSymbols()
Definition: model_config.hpp:136
MicroModelica::IR::Model::stateNbr
int stateNbr() const
Definition: class.hpp:180
MicroModelica::Generator::WRITER::Model_Bdf
@ Model_Bdf
Definition: writer.hpp:85
MicroModelica::Generator::WriterPtr
std::shared_ptr< Writer > WriterPtr
Definition: writer.hpp:146
MicroModelica::Generator::ClassicModelInstance::_model
IR::Model _model
Definition: model_instance.hpp:192
statement.hpp
MicroModelica::Generator::WRITER::Init_Code
@ Init_Code
Definition: writer.hpp:77
class.hpp
util.hpp
MicroModelica::Generator::Macros::modelAccess
std::string modelAccess(int discretes, int algebraics)
Definition: macros.cpp:234
MicroModelica::Generator::WRITER::Init_Data
@ Init_Data
Definition: writer.hpp:73
MicroModelica::Generator::WRITER::Zero_Crossing
@ Zero_Crossing
Definition: writer.hpp:88
error.hpp
ModelTable::next
Value next(iterator &it)
Definition: table.hpp:78
expression.hpp
MicroModelica::IR::Model::name
string name() const
Definition: class.hpp:165