fmu2.cpp
1 /*
2  * This file is part of CasADi.
3  *
4  * CasADi -- A symbolic framework for dynamic optimization.
5  * Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl,
6  * KU Leuven. All rights reserved.
7  * Copyright (C) 2011-2014 Greg Horn
8  *
9  * CasADi is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 3 of the License, or (at your option) any later version.
13  *
14  * CasADi is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with CasADi; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 
26 #include "fmu2.hpp"
27 #include "fmu_function.hpp"
28 #include "dae_builder_internal.hpp"
29 
30 namespace casadi {
31 
32 // Memory object
33 struct Fmu2Memory : public FmuMemory {
34  Fmu2::Value aux_value;
35  // Scratch space for evaluation dance (Simulink workaround)
36  std::vector<double> derivate_dump;
37  // Constructor
38  explicit Fmu2Memory(const FmuFunction& self) : FmuMemory(self) {}
39 };
40 
41 int Fmu2::init_mem(FmuMemory* mem) const {
42  if (FmuInternal::init_mem(mem)) return 1;
43  auto *m = static_cast<Fmu2Memory*>(mem);
45  m->aux_value.v_real.resize(vn_aux_real_.size());
46  m->aux_value.v_integer.resize(vn_aux_integer_.size());
47  m->aux_value.v_boolean.resize(vn_aux_boolean_.size());
48  m->aux_value.v_string.resize(vn_aux_string_.size());
49  // Allocate scratch space for evaluation dance
50  if (do_evaluation_dance_) m->derivate_dump.resize(nx_);
51  return 0;
52 }
53 
55  return new Fmu2Memory(f);
56 }
57 
58 void Fmu2::free_mem(void *mem) const {
59  delete static_cast<Fmu2Memory*>(mem);
60 }
61 
63 }
64 
65 std::string Fmu2::dll_infix() {
66 #if defined(_WIN32)
67  // Windows system
68 #ifdef _WIN64
69  return "win64";
70 #else
71  return "win32";
72 #endif
73 #elif defined(__APPLE__)
74  // OSX
75  return sizeof(void*) == 4 ? "darwin32" : "darwin64";
76 #else
77  // Linux
78  return sizeof(void*) == 4 ? "linux32" : "linux64";
79 #endif
80 }
81 
82 void Fmu2::init(const DaeBuilderInternal* dae) {
83  // Initialize base classes
84  FmuInternal::init(dae);
85 
86  // Add prefix to resource location, cf. FMI specification 2.0.5, section 2.1.5
87  resource_loc_ = "file://" + resource_loc_;
88 
89  // Collect input and parameter values
90  vr_real_.clear();
91  vr_integer_.clear();
92  vr_boolean_.clear();
93  vr_string_.clear();
94  init_real_.clear();
95  init_integer_.clear();
96  init_boolean_.clear();
97  init_string_.clear();
98  for (size_t i = 0; i < dae->n_variables(); ++i) {
99  const Variable& v = dae->variable(i);
100  casadi_assert(v.numel == 1, "Vector variable support not implemented");
101  // Skip if the wrong type
102  if (v.causality != Causality::PARAMETER && v.causality != Causality::INPUT) continue;
103  // Variable has not been set - keep default value
104  if (!v.is_set()) continue;
105  // Value reference
106  fmi2ValueReference vr = v.value_reference;
107  // Get value
108  switch (to_fmi2(v.type)) {
109  case TypeFmi2::REAL:
110  init_real_.push_back(static_cast<fmi2Real>(v.value.front()));
111  vr_real_.push_back(vr);
112  break;
113  case TypeFmi2::INTEGER:
114  case TypeFmi2::ENUM:
115  init_integer_.push_back(static_cast<fmi2Integer>(v.value.front()));
116  vr_integer_.push_back(vr);
117  break;
118  case TypeFmi2::BOOLEAN:
119  init_boolean_.push_back(static_cast<fmi2Boolean>(v.value.front()));
120  vr_boolean_.push_back(vr);
121  break;
122  case TypeFmi2::STRING:
123  init_string_.push_back(v.stringvalue);
124  vr_string_.push_back(vr);
125  break;
126  default:
127  casadi_warning("Ignoring " + v.name + ", type: " + to_string(v.type));
128  }
129  }
130 
131  // Collect auxilliary variables
132  vn_aux_real_.clear();
133  vn_aux_integer_.clear();
134  vn_aux_boolean_.clear();
135  vn_aux_string_.clear();
136  vr_aux_real_.clear();
137  vr_aux_integer_.clear();
138  vr_aux_boolean_.clear();
139  vr_aux_string_.clear();
140  for (auto&& s : aux_) {
141  const Variable& v = dae->variable(s);
142  // Convert to expected type
143  fmi2ValueReference vr = v.value_reference;
144  // Sort by type
145  switch (to_fmi2(v.type)) {
146  case TypeFmi2::REAL:
147  // Real
148  vn_aux_real_.push_back(v.name);
149  vr_aux_real_.push_back(vr);
150  break;
151  case TypeFmi2::INTEGER:
152  case TypeFmi2::ENUM:
153  // Integer or enum
154  vn_aux_integer_.push_back(v.name);
155  vr_aux_integer_.push_back(vr);
156  break;
157  case TypeFmi2::BOOLEAN:
158  // Boolean
159  vn_aux_boolean_.push_back(v.name);
160  vr_aux_boolean_.push_back(vr);
161  break;
162  case TypeFmi2::STRING:
163  // String
164  vn_aux_string_.push_back(v.name);
165  vr_aux_string_.push_back(vr);
166  break;
167  default:
168  casadi_warning("Ignoring " + v.name + ", type: " + to_string(v.type));
169  }
170  }
171 }
172 
175  aux_value_.v_real.resize(vn_aux_real_.size());
176  aux_value_.v_integer.resize(vn_aux_integer_.size());
177  aux_value_.v_boolean.resize(vn_aux_boolean_.size());
178  aux_value_.v_string.resize(vn_aux_string_.size());
179 
180  // Recursive call
182 }
183 
185  instantiate_ = load_function<fmi2InstantiateTYPE>("fmi2Instantiate");
186  free_instance_ = load_function<fmi2FreeInstanceTYPE>("fmi2FreeInstance");
187  reset_ = load_function<fmi2ResetTYPE>("fmi2Reset");
188  setup_experiment_ = load_function<fmi2SetupExperimentTYPE>("fmi2SetupExperiment");
189  enter_initialization_mode_ = load_function<fmi2EnterInitializationModeTYPE>(
190  "fmi2EnterInitializationMode");
191  exit_initialization_mode_ = load_function<fmi2ExitInitializationModeTYPE>(
192  "fmi2ExitInitializationMode");
193  enter_continuous_time_mode_ = load_function<fmi2EnterContinuousTimeModeTYPE>(
194  "fmi2EnterContinuousTimeMode");
195  get_derivatives_ = load_function<fmi2GetDerivativesTYPE>("fmi2GetDerivatives");
196  set_time_ = load_function<fmi2SetTimeTYPE>("fmi2SetTime");
197  get_real_ = load_function<fmi2GetRealTYPE>("fmi2GetReal");
198  set_real_ = load_function<fmi2SetRealTYPE>("fmi2SetReal");
199  get_integer_ = load_function<fmi2GetIntegerTYPE>("fmi2GetInteger");
200  set_integer_ = load_function<fmi2SetIntegerTYPE>("fmi2SetInteger");
201  get_boolean_ = load_function<fmi2GetBooleanTYPE>("fmi2GetBoolean");
202  set_boolean_ = load_function<fmi2SetBooleanTYPE>("fmi2SetBoolean");
203  get_string_ = load_function<fmi2GetStringTYPE>("fmi2GetString");
204  set_string_ = load_function<fmi2SetStringTYPE>("fmi2SetString");
207  load_function<fmi2GetDirectionalDerivativeTYPE>("fmi2GetDirectionalDerivative");
208  }
209  new_discrete_states_ = load_function<fmi2NewDiscreteStatesTYPE>("fmi2NewDiscreteStates");
210 
211  // Callback functions
212  functions_.logger = logger;
213  functions_.allocateMemory = calloc;
214  functions_.freeMemory = free;
215  functions_.stepFinished = nullptr;
216  functions_.componentEnvironment = nullptr;
217 }
218 
219 void Fmu2::logger(fmi2ComponentEnvironment componentEnvironment,
220  fmi2String instanceName,
221  fmi2Status status,
222  fmi2String category,
223  fmi2String message, ...) {
224  // Variable number of arguments
225  va_list args;
226  va_start(args, message);
227  // Static & dynamic buffers
228  char buf[256];
229  size_t buf_sz = sizeof(buf);
230  char* buf_dyn = nullptr;
231  // Try to print with a small buffer
232  int n = vsnprintf(buf, buf_sz, message, args);
233  // Need a larger buffer?
234  if (n > buf_sz) {
235  buf_sz = n + 1;
236  buf_dyn = new char[buf_sz];
237  n = vsnprintf(buf_dyn, buf_sz, message, args);
238  }
239  // Print buffer content
240  if (n >= 0) {
241  uout() << "[" << instanceName << ":" << category << "] "
242  << (buf_dyn ? buf_dyn : buf) << std::endl;
243  }
244  // Cleanup
245  delete[] buf_dyn;
246  va_end(args);
247  // Throw error if failure
248  casadi_assert(n>=0, "Print failure while processing '" + std::string(message) + "'");
249 }
250 
251 void* Fmu2::instantiate() const {
252  // Instantiate FMU
253  fmi2String instanceName = instance_name_.c_str();
254  fmi2Type fmuType = fmi2ModelExchange;
255  fmi2String fmuGUID = instantiation_token_.c_str();
256  fmi2String fmuResourceLocation = resource_loc_.c_str();
257  fmi2Boolean visible = fmi2False;
258  fmi2Component c = instantiate_(instanceName, fmuType, fmuGUID, fmuResourceLocation,
259  &functions_, visible, logging_on_);
260  if (c == nullptr) casadi_error("fmi2Instantiate failed");
261 
262  // Call fmi2SetupExperiment
263  fmi2Status status = setup_experiment_(c, fmutol_ > 0, fmutol_, 0., fmi2True, 1.);
264  casadi_assert(status == fmi2OK, "fmi2SetupExperiment failed");
265 
266  return c;
267 }
268 
269 void Fmu2::free_instance(void* instance) const {
270  if (free_instance_) {
271  auto *c = static_cast<fmi2Component>(instance);
272  free_instance_(c);
273  } else {
274  casadi_warning("No free_instance function pointer available");
275  }
276 }
277 
278 int Fmu2::reset(void* instance) {
279  auto *c = static_cast<fmi2Component>(instance);
280  fmi2Status status = reset_(c);
281  if (status != fmi2OK) {
282  casadi_warning("fmi2Reset failed");
283  return 1;
284  }
285  return 0;
286 }
287 
288 int Fmu2::enter_initialization_mode(void* instance) const {
289  auto *c = static_cast<fmi2Component>(instance);
290  fmi2Status status = enter_initialization_mode_(c);
291  if (status != fmi2OK) {
292  casadi_warning("fmi2EnterInitializationMode failed: " + str(status));
293  return 1;
294  }
295  return 0;
296 }
297 
298 int Fmu2::exit_initialization_mode(void* instance) const {
299  auto *c = static_cast<fmi2Component>(instance);
300  fmi2Status status = exit_initialization_mode_(c);
301  if (status != fmi2OK) {
302  casadi_warning("fmi2ExitInitializationMode failed");
303  return 1;
304  }
305  return 0;
306 }
307 
308 int Fmu2::enter_continuous_time_mode(void* instance) const {
309  auto *c = static_cast<fmi2Component>(instance);
310  fmi2Status status = enter_continuous_time_mode_(c);
311  if (status != fmi2OK) {
312  casadi_warning("fmi2EnterContinuousTimeMode failed");
313  return 1;
314  }
315  return 0;
316 }
317 
318 int Fmu2::get_derivatives(void* instance, double* derivatives, size_t nx) const {
319  auto *c = static_cast<fmi2Component>(instance);
320  fmi2Status status = get_derivatives_(c, derivatives, nx);
321  if (status != fmi2OK) {
322  casadi_warning("fmi2GetDerivatives failed");
323  return 1;
324  }
325  return 0;
326 }
327 
328 int Fmu2::update_discrete_states(void* instance, EventMemory* eventmem) const {
329  auto *c = static_cast<fmi2Component>(instance);
330  // Return arguments in FMI types
331  fmi2EventInfo eventInfo;
332  eventInfo.newDiscreteStatesNeeded = fmi2False;
333  eventInfo.terminateSimulation = fmi2False;
334  eventInfo.nominalsOfContinuousStatesChanged = fmi2False;
335  eventInfo.valuesOfContinuousStatesChanged = fmi2False;
336  eventInfo.nextEventTimeDefined = fmi2False;
337  eventInfo.nextEventTime = 0.0;
338  // Call FMU
339  fmi2Status status = new_discrete_states_(c, &eventInfo);
340  // Pass to event iteration memory
341  eventmem->discrete_states_need_update = eventInfo.newDiscreteStatesNeeded;
342  eventmem->terminate_simulation = eventInfo.terminateSimulation;
343  eventmem->nominals_of_continuous_states_changed = eventInfo.nominalsOfContinuousStatesChanged;
344  eventmem->values_of_continuous_states_changed = eventInfo.valuesOfContinuousStatesChanged;
345  eventmem->next_event_time_defined = eventInfo.nextEventTimeDefined;
346  eventmem->next_event_time = eventInfo.nextEventTime;
347  return status != fmi2OK;
348 }
349 
350 int Fmu2::set_time(void* instance, double t) const {
351  fmi2Status status = set_time_(instance, t);
352  return status != fmi2OK;
353 }
354 
355 int Fmu2::set_real(void* instance, const unsigned int* vr, size_t n_vr,
356  const double* values, size_t n_values) const {
357  casadi_assert(n_vr == n_values, "Vector-valued variables not supported in FMI 2");
358 
359  fmi2Status status = set_real_(instance, vr, n_vr, values);
360  return status != fmi2OK;
361 }
362 
363 int Fmu2::get_real(void* instance, const unsigned int* vr, size_t n_vr,
364  double* values, size_t n_values, FmuMemory* mem) const {
365  casadi_assert(n_vr == n_values, "Vector-valued variables not supported in FMI 2");
366  if (do_evaluation_dance_ && mem) {
367  auto *m = static_cast<Fmu2Memory*>(mem);
368  // Dummy call to trigger rtOneStep
369  fmi2Status status = get_real_(instance, nullptr, 0, nullptr);
370  if (status != fmi2OK) return 1;
371  // Dummy call to trigger computation of derivatives, possibly read later via get_real
372  status = get_derivatives_(instance, get_ptr(m->derivate_dump), nx_);
373  if (status != fmi2OK) return 1;
374  }
375 
376  fmi2Status status = get_real_(instance, vr, n_vr, values);
377  return status != fmi2OK;
378 }
379 
380 int Fmu2::get_directional_derivative(void* instance, const unsigned int* vr_out, size_t n_out,
381  const unsigned int* vr_in, size_t n_in, const double* seed, size_t n_seed,
382  double* sensitivity, size_t n_sensitivity) const {
383  // Consistency checks
384  casadi_assert(n_in == n_seed, "Vector-valued variables not supported in FMI 2");
385  casadi_assert(n_out == n_sensitivity, "Vector-valued variables not supported in FMI 2");
386  // Quick return if zero dimension
387  if (n_in == 0 || n_out == 0) return 0;
388  // No directional derivatives w.r.t. automatically added independent variable
389  if (has_independent_ && n_in > 0 && *vr_in == static_cast<unsigned int>(-1)) {
390  n_in--;
391  vr_in++;
392  n_seed--;
393  seed++;
394  // Quick return if now zero dimension
395  if (n_in == 0) {
396  std::fill(sensitivity, sensitivity + n_sensitivity, 0.0);
397  return 0;
398  }
399  }
400  // Retrieve from FMU and return
401  fmi2Status status = get_directional_derivative_(instance, vr_out, n_out, vr_in, n_in,
402  seed, sensitivity);
403  return status != fmi2OK;
404 }
405 
406 int Fmu2::set_values(void* instance) const {
407  auto *c = static_cast<fmi2Component>(instance);
408  // Pass real values before initialization
409  if (!vr_real_.empty()) {
410  fmi2Status status = set_real_(c, get_ptr(vr_real_), vr_real_.size(), get_ptr(init_real_));
411  if (status != fmi2OK) {
412  casadi_warning("fmi2SetReal failed");
413  return 1;
414  }
415  }
416  // Pass integer values before initialization (also enums)
417  if (!vr_integer_.empty()) {
418  fmi2Status status = set_integer_(c, get_ptr(vr_integer_), vr_integer_.size(),
420  if (status != fmi2OK) {
421  casadi_warning("fmi2SetInteger failed");
422  return 1;
423  }
424  }
425  // Pass boolean values before initialization
426  if (!vr_boolean_.empty()) {
427  fmi2Status status = set_boolean_(c, get_ptr(vr_boolean_), vr_boolean_.size(),
429  if (status != fmi2OK) {
430  casadi_warning("fmi2SetBoolean failed");
431  return 1;
432  }
433  }
434  // Pass string values before initialization
435  for (size_t k = 0; k < vr_string_.size(); ++k) {
436  fmi2ValueReference vr = vr_string_[k];
437  fmi2String value = init_string_[k].c_str();
438  fmi2Status status = set_string_(c, &vr, 1, &value);
439  if (status != fmi2OK) {
440  casadi_error("fmi2SetString failed for value reference " + str(vr));
441  }
442  }
443  // Successful return
444  return 0;
445 }
446 
447 int Fmu2::get_aux_impl(void* instance, Value& aux_value) const {
448  auto *c = static_cast<fmi2Component>(instance);
449  // Get real auxilliary variables
450  if (!vr_aux_real_.empty()) {
451  fmi2Status status = get_real_(c, get_ptr(vr_aux_real_), vr_aux_real_.size(),
452  get_ptr(aux_value.v_real));
453  if (status != fmi2OK) {
454  casadi_warning("fmi2GetReal failed");
455  return 1;
456  }
457  }
458  // Get integer/enum auxilliary variables
459  if (!vr_aux_integer_.empty()) {
460  fmi2Status status = get_integer_(c, get_ptr(vr_aux_integer_), vr_aux_integer_.size(),
461  get_ptr(aux_value.v_integer));
462  if (status != fmi2OK) {
463  casadi_warning("fmi2GetInteger failed");
464  return 1;
465  }
466  }
467  // Get boolean auxilliary variables
468  if (!vr_aux_boolean_.empty()) {
469  fmi2Status status = get_boolean_(c, get_ptr(vr_aux_boolean_), vr_aux_boolean_.size(),
470  get_ptr(aux_value.v_boolean));
471  if (status != fmi2OK) {
472  casadi_warning("fmi2GetBoolean failed");
473  return 1;
474  }
475  }
476  // Get string auxilliary variables
477  for (size_t k = 0; k < vr_aux_string_.size(); ++k) {
478  fmi2ValueReference vr = vr_aux_string_[k];
479  fmi2String value = aux_value.v_string.at(k).c_str();
480  fmi2Status status = set_string_(c, &vr, 1, &value);
481  if (status != fmi2OK) {
482  casadi_error("fmi2GetString failed for value reference " + str(vr));
483  }
484  }
485  // Successful return
486  return 0;
487 }
488 
489 int Fmu2::get_aux(void* instance) {
490  return get_aux_impl(instance, aux_value_);
491 }
492 
494  const std::vector<std::string>& name_in, const InputStruct* in) const {
495  Value& v = static_cast<Fmu2Memory*>(m)->aux_value;
496  get_aux_impl(m->instance, v);
497  // Collect auxilliary variables
498  Dict aux;
499  // Real
500  for (size_t k = 0; k < vn_aux_real_.size(); ++k) {
501  aux[vn_aux_real_[k]] = static_cast<double>(v.v_real[k]);
502  }
503  // Integer
504  for (size_t k = 0; k < vn_aux_integer_.size(); ++k) {
505  aux[vn_aux_integer_[k]] = static_cast<casadi_int>(v.v_integer[k]);
506  }
507  // Boolean
508  for (size_t k = 0; k < vn_aux_boolean_.size(); ++k) {
509  aux[vn_aux_boolean_[k]] = static_cast<bool>(v.v_boolean[k]);
510  }
511  // String
512  for (size_t k = 0; k < vn_aux_string_.size(); ++k) {
513  aux[vn_aux_string_[k]] = v.v_string[k];
514  }
515  // Copy to stats
516  (*stats)["aux"] = aux;
517  // Loop over input variables
518  for (size_t k = 0; k < name_in.size(); ++k) {
519  // Only consider regular inputs
520  if (in[k].type == InputType::REG) {
521  // Get the indices
522  const std::vector<size_t>& iind = ired_.at(in[k].ind);
523  // Collect values
524  std::vector<double> v(iind.size());
525  for (size_t i = 0; i < v.size(); ++i) v[i] = value_in_.at(iind[i]);
526  // Save to stats
527  (*stats)[name_in[k]] = v;
528  }
529  }
530 }
531 
532 Fmu2::Fmu2(const std::string& name,
533  const std::vector<std::string>& scheme_in,
534  const std::vector<std::string>& scheme_out,
535  const std::map<std::string, std::vector<size_t>>& scheme,
536  const std::vector<std::string>& aux)
537  : FmuInternal(name, scheme_in, scheme_out, scheme, aux) {
538  instantiate_ = nullptr;
539  free_instance_ = nullptr;
540  reset_ = nullptr;
541  setup_experiment_ = nullptr;
542  enter_initialization_mode_ = nullptr;
543  exit_initialization_mode_ = nullptr;
544  enter_continuous_time_mode_ = nullptr;
545  set_time_ = nullptr;
546  set_real_ = nullptr;
547  set_boolean_ = nullptr;
548  get_real_ = nullptr;
549  get_directional_derivative_ = nullptr;
550  new_discrete_states_ = nullptr;
551 }
552 
554  Fmu2* ret = new Fmu2(s);
555  ret->finalize();
556  return ret;
557 }
558 
560  instantiate_ = nullptr;
561  free_instance_ = nullptr;
562  reset_ = nullptr;
563  setup_experiment_ = nullptr;
564  enter_initialization_mode_ = nullptr;
565  exit_initialization_mode_ = nullptr;
566  enter_continuous_time_mode_ = nullptr;
567  set_real_ = nullptr;
568  set_boolean_ = nullptr;
569  get_real_ = nullptr;
570  get_directional_derivative_ = nullptr;
571  new_discrete_states_ = nullptr;
572 
573  s.version("Fmu2", 2);
574  s.unpack("Fmu2::vr_real", vr_real_);
575  s.unpack("Fmu2::vr_integer", vr_integer_);
576  s.unpack("Fmu2::vr_boolean", vr_boolean_);
577  s.unpack("Fmu2::vr_string", vr_string_);
578  s.unpack("Fmu2::init_real", init_real_);
579  s.unpack("Fmu2::init_integer", init_integer_);
580  s.unpack("Fmu2::init_boolean", init_boolean_);
581  s.unpack("Fmu2::init_string", init_string_);
582 
583  s.unpack("Fmu2::vn_aux_real", vn_aux_real_);
584  s.unpack("Fmu2::vn_aux_integer", vn_aux_integer_);
585  s.unpack("Fmu2::vn_aux_boolean", vn_aux_boolean_);
586  s.unpack("Fmu2::vn_aux_string", vn_aux_string_);
587  s.unpack("Fmu2::vr_aux_real", vr_aux_real_);
588  s.unpack("Fmu2::vr_aux_integer", vr_aux_integer_);
589  s.unpack("Fmu2::vr_aux_boolean", vr_aux_boolean_);
590  s.unpack("Fmu2::vr_aux_string", vr_aux_string_);
591 }
592 
593 
596 
597  s.version("Fmu2", 2);
598  s.pack("Fmu2::vr_real", vr_real_);
599  s.pack("Fmu2::vr_integer", vr_integer_);
600  s.pack("Fmu2::vr_boolean", vr_boolean_);
601  s.pack("Fmu2::vr_string", vr_string_);
602  s.pack("Fmu2::init_real", init_real_);
603  s.pack("Fmu2::init_integer", init_integer_);
604  s.pack("Fmu2::init_boolean", init_boolean_);
605  s.pack("Fmu2::init_string", init_string_);
606 
607  s.pack("Fmu2::vn_aux_real", vn_aux_real_);
608  s.pack("Fmu2::vn_aux_integer", vn_aux_integer_);
609  s.pack("Fmu2::vn_aux_boolean", vn_aux_boolean_);
610  s.pack("Fmu2::vn_aux_string", vn_aux_string_);
611  s.pack("Fmu2::vr_aux_real", vr_aux_real_);
612  s.pack("Fmu2::vr_aux_integer", vr_aux_integer_);
613  s.pack("Fmu2::vr_aux_boolean", vr_aux_boolean_);
614  s.pack("Fmu2::vr_aux_string", vr_aux_string_);
615 }
616 
617 } // namespace casadi
size_t n_variables() const
Length of variables array.
Variable & variable(size_t ind)
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
void version(const std::string &name, int v)
Interface to a binary FMU, adhering to FMI version 2.0.
Definition: fmu2.hpp:42
void free_instance(void *instance) const override
Definition: fmu2.cpp:269
std::vector< fmi2ValueReference > vr_string_
Definition: fmu2.hpp:82
void init(const DaeBuilderInternal *dae) override
Definition: fmu2.cpp:82
fmi2ExitInitializationModeTYPE * exit_initialization_mode_
Definition: fmu2.hpp:100
std::vector< fmi2Real > init_real_
Definition: fmu2.hpp:83
std::vector< fmi2ValueReference > vr_boolean_
Definition: fmu2.hpp:82
std::vector< fmi2Boolean > init_boolean_
Definition: fmu2.hpp:85
std::vector< std::string > vn_aux_integer_
Definition: fmu2.hpp:89
void load_functions() override
Definition: fmu2.cpp:184
~Fmu2() override
Destructor.
Definition: fmu2.cpp:62
int init_mem(FmuMemory *m) const override
Initalize memory block.
Definition: fmu2.cpp:41
fmi2CallbackFunctions functions_
Definition: fmu2.hpp:116
std::vector< std::string > vn_aux_string_
Definition: fmu2.hpp:89
fmi2SetupExperimentTYPE * setup_experiment_
Definition: fmu2.hpp:98
Fmu2(const std::string &name, const std::vector< std::string > &scheme_in, const std::vector< std::string > &scheme_out, const std::map< std::string, std::vector< size_t >> &scheme, const std::vector< std::string > &aux)
Definition: fmu2.cpp:532
std::vector< fmi2Integer > init_integer_
Definition: fmu2.hpp:84
int set_real(void *instance, const unsigned int *vr, size_t n_vr, const double *values, size_t n_values) const override
Definition: fmu2.cpp:355
fmi2EnterInitializationModeTYPE * enter_initialization_mode_
Definition: fmu2.hpp:99
fmi2InstantiateTYPE * instantiate_
Definition: fmu2.hpp:95
int get_real(void *instance, const unsigned int *vr, size_t n_vr, double *values, size_t n_values, FmuMemory *m=nullptr) const override
Definition: fmu2.cpp:363
fmi2GetIntegerTYPE * get_integer_
Definition: fmu2.hpp:108
fmi2SetTimeTYPE * set_time_
Definition: fmu2.hpp:103
fmi2GetBooleanTYPE * get_boolean_
Definition: fmu2.hpp:106
void serialize_body(SerializingStream &s) const override
Definition: fmu2.cpp:594
fmi2ResetTYPE * reset_
Definition: fmu2.hpp:97
int get_aux(void *instance) override
Definition: fmu2.cpp:489
fmi2SetBooleanTYPE * set_boolean_
Definition: fmu2.hpp:107
std::vector< std::string > vn_aux_real_
Definition: fmu2.hpp:89
int get_aux_impl(void *instance, Value &aux_value) const
Definition: fmu2.cpp:447
static Fmu2 * deserialize(DeserializingStream &s)
Definition: fmu2.cpp:553
void get_stats(FmuMemory *m, Dict *stats, const std::vector< std::string > &name_in, const InputStruct *in) const override
Get stats.
Definition: fmu2.cpp:493
int exit_initialization_mode(void *instance) const override
Definition: fmu2.cpp:298
fmi2SetStringTYPE * set_string_
Definition: fmu2.hpp:111
fmi2SetIntegerTYPE * set_integer_
Definition: fmu2.hpp:109
std::vector< fmi2ValueReference > vr_integer_
Definition: fmu2.hpp:82
fmi2SetRealTYPE * set_real_
Definition: fmu2.hpp:105
std::vector< std::string > vn_aux_boolean_
Definition: fmu2.hpp:89
int set_time(void *instance, double t) const override
Definition: fmu2.cpp:350
fmi2GetDirectionalDerivativeTYPE * get_directional_derivative_
Definition: fmu2.hpp:112
fmi2GetDerivativesTYPE * get_derivatives_
Definition: fmu2.hpp:102
int enter_initialization_mode(void *instance) const override
Definition: fmu2.cpp:288
void * instantiate() const override
Definition: fmu2.cpp:251
std::vector< fmi2ValueReference > vr_aux_string_
Definition: fmu2.hpp:90
std::vector< fmi2ValueReference > vr_aux_integer_
Definition: fmu2.hpp:90
FmuMemory * alloc_mem(const FmuFunction &f) const override
Create memory block.
Definition: fmu2.cpp:54
std::vector< fmi2ValueReference > vr_real_
Definition: fmu2.hpp:82
static std::string dll_infix()
Definition: fmu2.cpp:65
fmi2FreeInstanceTYPE * free_instance_
Definition: fmu2.hpp:96
fmi2EnterContinuousTimeModeTYPE * enter_continuous_time_mode_
Definition: fmu2.hpp:101
Value aux_value_
Definition: fmu2.hpp:126
void finalize() override
Definition: fmu2.cpp:173
fmi2NewDiscreteStatesTYPE * new_discrete_states_
Definition: fmu2.hpp:113
int reset(void *instance)
Definition: fmu2.cpp:278
int update_discrete_states(void *instance, EventMemory *eventmem) const override
Definition: fmu2.cpp:328
int enter_continuous_time_mode(void *instance) const override
Definition: fmu2.cpp:308
fmi2GetRealTYPE * get_real_
Definition: fmu2.hpp:104
std::vector< fmi2ValueReference > vr_aux_real_
Definition: fmu2.hpp:90
static void logger(fmi2ComponentEnvironment componentEnvironment, fmi2String instanceName, fmi2Status status, fmi2String category, fmi2String message,...)
Definition: fmu2.cpp:219
void free_mem(void *mem) const override
Free memory block.
Definition: fmu2.cpp:58
int set_values(void *instance) const override
Definition: fmu2.cpp:406
int get_directional_derivative(void *instance, const unsigned int *vr_out, size_t n_out, const unsigned int *vr_in, size_t n_in, const double *seed, size_t n_seed, double *sensitivity, size_t n_sensitivity) const override
Definition: fmu2.cpp:380
fmi2GetStringTYPE * get_string_
Definition: fmu2.hpp:110
std::vector< std::string > init_string_
Definition: fmu2.hpp:86
std::vector< fmi2ValueReference > vr_aux_boolean_
Definition: fmu2.hpp:90
int get_derivatives(void *instance, double *derivatives, size_t nx) const override
Definition: fmu2.cpp:318
Interface to binary FMU.
Definition: fmu_impl.hpp:61
std::string instantiation_token_
Definition: fmu_impl.hpp:324
virtual void finalize()
Definition: fmu.cpp:593
std::vector< std::vector< size_t > > ired_
Definition: fmu_impl.hpp:364
std::vector< std::string > aux_
Definition: fmu_impl.hpp:312
virtual void serialize_body(SerializingStream &s) const
Definition: fmu.cpp:1506
size_t n_in() const
Get the number of scheme inputs.
Definition: fmu_impl.hpp:130
std::string resource_loc_
Definition: fmu_impl.hpp:315
std::vector< double > value_in_
Definition: fmu_impl.hpp:361
virtual void init(const DaeBuilderInternal *dae)
Definition: fmu.cpp:453
size_t n_out() const
Get the number of scheme outputs.
Definition: fmu_impl.hpp:135
virtual int init_mem(FmuMemory *m) const
Initalize memory block.
Definition: fmu.cpp:1247
std::string instance_name_
Definition: fmu_impl.hpp:321
bool provides_directional_derivatives_
Definition: fmu_impl.hpp:333
Helper class for Serialization.
void version(const std::string &name, int v)
void pack(const Sparsity &e)
Serializes an object to the output stream.
The casadi namespace.
Definition: archiver.cpp:28
TypeFmi2 to_fmi2(Type v)
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
std::string to_string(TypeFmi2 v)
T * get_ptr(std::vector< T > &v)
Get a pointer to the data contained in the vector.
std::ostream & uout()
bool discrete_states_need_update
Definition: fmu_impl.hpp:39
bool next_event_time_defined
Definition: fmu_impl.hpp:43
double next_event_time
Definition: fmu_impl.hpp:44
bool nominals_of_continuous_states_changed
Definition: fmu_impl.hpp:41
bool values_of_continuous_states_changed
Definition: fmu_impl.hpp:42
std::vector< fmi2Boolean > v_boolean
Definition: fmu2.hpp:122
std::vector< fmi2Real > v_real
Definition: fmu2.hpp:120
std::vector< std::string > v_string
Definition: fmu2.hpp:123
std::vector< fmi2Integer > v_integer
Definition: fmu2.hpp:121
const FmuFunction & self
FmuMemory(const FmuFunction &self)
Holds expressions and meta-data corresponding to a physical quantity evolving in time.
std::vector< double > value
Numerical value (also for booleans, integers, enums)
std::string stringvalue
String value (if string-valued)
casadi_int numel
Number of elements - product of all dimensions.
std::string name
Name of the variable.