MicroModelicaCCompiler  4.5.3
user_def_matrix.cpp
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  This file is part of QSS Solver.
4 
5  QSS 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  QSS 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 QSS Solver. If not, see <http://www.gnu.org/licenses/>.
17 
18  ******************************************************************************/
19 
20 #include <assert.h>
21 #include <string>
22 
23 #include <util/model_config.hpp>
24 #include <ir/user_def_matrix.hpp>
25 #include <util/error.hpp>
26 #include <util/visitors/convert_output_range.hpp>
27 
28 namespace MicroModelica {
29 using namespace Util;
30 namespace IR {
31 
32 template <typename Config, typename N>
33 UserDefMatrix<Config, N>::UserDefMatrix(Config matrix_config) : _model_matrix_def(), _access_vector(), _matrix_config(matrix_config)
34 {
35 }
36 
37 template <typename Config, typename N>
39 {
40  printMatrix(MATRIX::Alloc, MATRIX::Normal);
41  printMatrix(MATRIX::Alloc, MATRIX::Transpose);
42  printMatrix(MATRIX::Init, MATRIX::Normal);
43  printMatrix(MATRIX::Init, MATRIX::Transpose);
44 }
45 
46 template <typename Config, typename N>
48 {
49  stringstream buffer;
50  string component = _matrix_config.component[0];
51  bool use_component = _matrix_config.use_component[mode];
52  if (method == MATRIX::Init) {
53  component = _matrix_config.component[1];
54  }
55  if (!component.empty() && use_component) {
56  buffer << "." << component;
57  }
58  return buffer.str();
59 }
60 
61 template <typename Config, typename N>
62 AST_Expression UserDefMatrix<Config, N>::transformExp(AST_Expression exp)
63 {
64  assert(exp->expressionType() == EXPCOMPREF);
65  AST_Expression_ComponentReference comp_ref = exp->getAsComponentReference();
66  string comp_ref_name = comp_ref->name();
67  Option<Variable> var = ModelConfig::instance().lookup(comp_ref_name);
68  if (var) {
69  return exp;
70  }
71  AST_Expression_ComponentReference new_var = newAST_Expression_ComponentReference();
74  string event_var_name;
75  for (Event ev = events.begin(ev_it); !events.end(ev_it); ev = events.next(ev_it)) {
76  if (ev.compareEventID(comp_ref_name)) {
77  event_var_name = ev.zeroCrossing().LHSVariable()->name();
78  break;
79  }
80  }
81  if (event_var_name.empty()) {
82  Error::instance().add(exp->lineNum(), EM_IR | EM_WRONG_EXP, ER_Fatal, "Wrong Event ID %s.", comp_ref_name);
83  }
84  if (comp_ref->hasIndexes()) {
85  AST_ExpressionList indexes = comp_ref->firstIndex();
86  AST_ExpressionListIterator exp_it;
87  AST_ExpressionList new_indexes = newAST_ExpressionList();
88  foreach (exp_it, indexes) {
89  new_indexes = AST_ListAppend(new_indexes, current_element(exp_it));
90  }
91  new_var = AST_Expression_ComponentReference_Add(new_var, newAST_String(event_var_name), new_indexes);
92  } else {
93  new_var = AST_Expression_ComponentReference_Add(new_var, newAST_String(event_var_name), newAST_ExpressionList());
94  }
95  return new_var;
96 }
97 
98 template <typename Config, typename N>
100 {
101  string matrix = _matrix_config.names[method + mode];
102  string access = _matrix_config.access[mode];
103  stringstream code;
104  for (auto entry_def : _matrix_config.user_def) {
105  int entry_id = entry_def.first;
106  AST_ExpressionList entry_infs = entry_def.second;
107  AST_ExpressionListIterator exp_it;
108  foreach (exp_it, entry_infs) {
109  AST_Expression exp = current_element(exp_it);
110  N node = _matrix_config.selector.getNode(entry_id);
111  Option<Range> range;
112  Index ife_idx;
113  Index ifr_idx;
114  if (exp->expressionType() == EXPOUTPUT) {
115  AST_Expression_Output matrix_exps = exp->getAsOutput();
116  AST_ExpressionList matrix_entry = matrix_exps->expressionList();
117  AST_ExpressionListIterator matrix_entry_it;
118  if (matrix_entry->size() != 2) {
119  Error::instance().add(exp->lineNum(), EM_IR | EM_WRONG_EXP, ER_Fatal, "Wrong user defined matrix expression");
120  }
121  bool first_exp = true;
122  ConvertOutputRange convert;
123  AST_Expression matrix_exp = nullptr;
124  foreach (matrix_entry_it, matrix_entry) {
125  if (first_exp) {
126  matrix_exp = current_element(matrix_entry_it);
127  first_exp = false;
128  } else {
129  assert(current_element(matrix_entry_it)->expressionType() == EXPBRACKET);
130  AST_Expression_Bracket range_def = current_element(matrix_entry_it)->getAsBracket();
131  AST_ExpressionList ranges = range_def->ranges();
132  AST_ExpressionListIterator range_it;
133  foreach (range_it, ranges) {
134  convert.apply(current_element(range_it));
135  }
136  range = convert.range();
137  }
138  }
139  ife_idx = Index(Expression(transformExp(matrix_exp)));
140  ife_idx = ife_idx.replace(range);
141  } else if (exp->expressionType() == EXPCOMPREF) {
142  AST_Expression_ComponentReference comp_ref = exp->getAsComponentReference();
143  ife_idx = Index(Expression(transformExp(comp_ref)));
144  range = node.range();
145  if (range) {
146  range->replace(ife_idx);
147  }
148  } else {
149  Error::instance().add(exp->lineNum(), EM_IR | EM_WRONG_EXP, ER_Fatal, "Wrong user defined matrix expression");
150  }
151  ifr_idx = Index(_matrix_config.selector.exp(node));
152  ifr_idx = ifr_idx.replace();
153  ife_idx = ife_idx.replace();
154 
155  if (range) {
156  const bool GENERATE_RANGE_INDEX = false;
157  const bool C_INDEX = false;
158  const bool CONVERT_PARAMS = true;
159  code << range->print(GENERATE_RANGE_INDEX, C_INDEX, CONVERT_PARAMS);
160  code << range->block();
161  }
162  if (method == MATRIX::Alloc) {
163  code << _matrix_config.container << matrix << "[" << ifr_idx << "]" << component(MATRIX::Alloc, mode) << "++;" << endl;
164  } else {
165  code << _matrix_config.container << matrix << "[" << ifr_idx << "]" << component(MATRIX::Init, mode) << "[" << access << "["
166  << ifr_idx << "]++] = " << ife_idx << ";" << endl;
167  }
168  if (range) {
169  code << range->end() << endl;
170  }
171  }
172  }
173  if (method == MATRIX::Alloc) {
174  _model_matrix_def.alloc[mode] = code.str();
175  } else {
176  _model_matrix_def.init[mode] = code.str();
177  }
178 }
179 
180 template <typename Config, typename N>
181 ModelMatrixDef UserDefMatrix<Config, N>::def()
182 {
183  return _model_matrix_def;
184 }
185 
186 template <typename Config, typename N>
187 std::vector<std::string> UserDefMatrix<Config, N>::accessVector()
188 {
189  return _access_vector;
190 }
191 
192 template class UserDefMatrix<MATRIX::EQMatrixConfig, Equation>;
193 
194 template class UserDefMatrix<MATRIX::EVMatrixConfig, Event>;
195 
196 } // namespace IR
197 } // namespace MicroModelica
MicroModelica::Util::ModelConfig::lookup
Option< Variable > lookup(std::string var_name)
Definition: model_config.hpp:125
EXPOUTPUT
@ EXPOUTPUT
Definition: ast_types.hpp:182
MicroModelica::Util::Error::instance
static Error & instance()
Definition: error.hpp:128
MicroModelica::IR::MATRIX::Normal
@ Normal
Definition: model_matrix_gen.hpp:103
ModelTable< int, Event >
ModelTable::begin
iterator begin()
Definition: table.hpp:68
EXPCOMPREF
@ EXPCOMPREF
Definition: ast_types.hpp:165
MicroModelica::IR::UserDefMatrix::UserDefMatrix
UserDefMatrix(Config matrix_config)
Definition: user_def_matrix.cpp:50
MicroModelica::Util::ModelConfig::events
IR::EventTable events() const
Definition: model_config.hpp:141
Option
Definition: util_types.hpp:32
MicroModelica::Util::ER_Fatal
@ ER_Fatal
ER_Fatal.
Definition: error.hpp:123
MicroModelica::IR::UserDefMatrix::printMatrix
void printMatrix(MATRIX::Method method, MATRIX::Mode mode)
Definition: user_def_matrix.cpp:116
MicroModelica::IR::UserDefMatrix::def
ModelMatrixDef def()
Definition: user_def_matrix.cpp:198
AST_Expression_ComponentReference_Add
AST_Expression_ComponentReference AST_Expression_ComponentReference_Add(AST_Expression_ComponentReference cr, AST_String s, AST_ExpressionList subs)
Definition: ast_builder.cpp:236
model_config.hpp
MicroModelica::IR::MATRIX::Method
Method
Definition: model_matrix_gen.hpp:88
MicroModelica::IR::MATRIX::Transpose
@ Transpose
Definition: model_matrix_gen.hpp:103
ModelTable::end
iterator end()
Definition: table.hpp:70
MicroModelica::IR::UserDefMatrix::transformExp
AST_Expression transformExp(AST_Expression exp)
Definition: user_def_matrix.cpp:79
MicroModelica::IR::UserDefMatrix::component
string component(MATRIX::Method method, MATRIX::Mode mode) const
Definition: user_def_matrix.cpp:64
MicroModelica::IR::UserDefMatrix::accessVector
std::vector< std::string > accessVector()
Definition: user_def_matrix.cpp:204
MicroModelica::IR::Event
Definition: event.hpp:84
AST_ListAppend
list< T1 > * AST_ListAppend(list< T1 > *l, T1 e)
Definition: ast_types.hpp:240
MicroModelica::Util::Error::add
void add(int pos, unsigned int code, ER_Type t, const std::string message,...)
Definition: error.cpp:42
user_def_matrix.hpp
ModelTable< int, Event >::iterator
std::map< int, Event >::iterator iterator
Definition: table.hpp:61
MicroModelica::Util::ModelConfig::instance
static ModelConfig & instance()
Definition: model_config.hpp:87
MicroModelica::IR::MATRIX::Mode
Mode
Definition: model_matrix_gen.hpp:86
newAST_Expression_ComponentReference
AST_Expression_ComponentReference newAST_Expression_ComponentReference()
Definition: ast_builder.cpp:222
EM_IR
#define EM_IR
Definition: error.hpp:66
MicroModelica
Definition: files.cpp:45
EXPBRACKET
@ EXPBRACKET
Definition: ast_types.hpp:186
EM_WRONG_EXP
#define EM_WRONG_EXP
Definition: error.hpp:77
newAST_ExpressionList
AST_ExpressionList newAST_ExpressionList(AST_Expression e)
Definition: ast_builder.cpp:132
MicroModelica::IR::UserDefMatrix::compute
void compute()
Definition: user_def_matrix.cpp:55
current_element
#define current_element(it)
Definition: ast_types.hpp:34
MicroModelica::IR::MATRIX::Alloc
@ Alloc
Definition: model_matrix_gen.hpp:88
MicroModelica::IR::MATRIX::Init
@ Init
Definition: model_matrix_gen.hpp:88
error.hpp
ModelTable::next
Value next(iterator &it)
Definition: table.hpp:78
newAST_String
AST_String newAST_String(string s)
Definition: ast_builder.cpp:57