27 #include "fmu_function.hpp"
28 #include "dae_builder_internal.hpp"
33 struct Fmu2Memory :
public FmuMemory {
34 Fmu2::Value aux_value;
36 std::vector<double> derivate_dump;
38 explicit Fmu2Memory(
const FmuFunction&
self) :
FmuMemory(
self) {}
43 auto *m =
static_cast<Fmu2Memory*
>(mem);
55 return new Fmu2Memory(f);
59 delete static_cast<Fmu2Memory*
>(mem);
73 #elif defined(__APPLE__)
75 return sizeof(
void*) == 4 ?
"darwin32" :
"darwin64";
78 return sizeof(
void*) == 4 ?
"linux32" :
"linux64";
100 casadi_assert(v.
numel == 1,
"Vector variable support not implemented");
104 if (!v.
is_set())
continue;
140 for (
auto&& s :
aux_) {
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");
190 "fmi2EnterInitializationMode");
192 "fmi2ExitInitializationMode");
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");
220 fmi2String instanceName,
223 fmi2String message, ...) {
226 va_start(args, message);
229 size_t buf_sz =
sizeof(buf);
230 char* buf_dyn =
nullptr;
232 int n = vsnprintf(buf, buf_sz, message, args);
236 buf_dyn =
new char[buf_sz];
237 n = vsnprintf(buf_dyn, buf_sz, message, args);
241 uout() <<
"[" << instanceName <<
":" << category <<
"] "
242 << (buf_dyn ? buf_dyn : buf) << std::endl;
248 casadi_assert(n>=0,
"Print failure while processing '" + std::string(message) +
"'");
254 fmi2Type fmuType = fmi2ModelExchange;
257 fmi2Boolean visible = fmi2False;
258 fmi2Component c =
instantiate_(instanceName, fmuType, fmuGUID, fmuResourceLocation,
260 if (c ==
nullptr) casadi_error(
"fmi2Instantiate failed");
264 casadi_assert(status == fmi2OK,
"fmi2SetupExperiment failed");
271 auto *c =
static_cast<fmi2Component
>(instance);
274 casadi_warning(
"No free_instance function pointer available");
279 auto *c =
static_cast<fmi2Component
>(instance);
280 fmi2Status status =
reset_(c);
281 if (status != fmi2OK) {
282 casadi_warning(
"fmi2Reset failed");
289 auto *c =
static_cast<fmi2Component
>(instance);
291 if (status != fmi2OK) {
292 casadi_warning(
"fmi2EnterInitializationMode failed: " +
str(status));
299 auto *c =
static_cast<fmi2Component
>(instance);
301 if (status != fmi2OK) {
302 casadi_warning(
"fmi2ExitInitializationMode failed");
309 auto *c =
static_cast<fmi2Component
>(instance);
311 if (status != fmi2OK) {
312 casadi_warning(
"fmi2EnterContinuousTimeMode failed");
319 auto *c =
static_cast<fmi2Component
>(instance);
321 if (status != fmi2OK) {
322 casadi_warning(
"fmi2GetDerivatives failed");
329 auto *c =
static_cast<fmi2Component
>(instance);
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;
347 return status != fmi2OK;
351 fmi2Status status =
set_time_(instance, t);
352 return status != fmi2OK;
356 const double* values,
size_t n_values)
const {
357 casadi_assert(n_vr == n_values,
"Vector-valued variables not supported in FMI 2");
359 fmi2Status status =
set_real_(instance, vr, n_vr, values);
360 return status != fmi2OK;
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");
367 auto *m =
static_cast<Fmu2Memory*
>(mem);
369 fmi2Status status =
get_real_(instance,
nullptr, 0,
nullptr);
370 if (status != fmi2OK)
return 1;
373 if (status != fmi2OK)
return 1;
376 fmi2Status status =
get_real_(instance, vr, n_vr, values);
377 return status != fmi2OK;
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 {
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");
396 std::fill(sensitivity, sensitivity + n_sensitivity, 0.0);
403 return status != fmi2OK;
407 auto *c =
static_cast<fmi2Component
>(instance);
411 if (status != fmi2OK) {
412 casadi_warning(
"fmi2SetReal failed");
420 if (status != fmi2OK) {
421 casadi_warning(
"fmi2SetInteger failed");
429 if (status != fmi2OK) {
430 casadi_warning(
"fmi2SetBoolean failed");
435 for (
size_t k = 0; k <
vr_string_.size(); ++k) {
438 fmi2Status status =
set_string_(c, &vr, 1, &value);
439 if (status != fmi2OK) {
440 casadi_error(
"fmi2SetString failed for value reference " +
str(vr));
448 auto *c =
static_cast<fmi2Component
>(instance);
453 if (status != fmi2OK) {
454 casadi_warning(
"fmi2GetReal failed");
462 if (status != fmi2OK) {
463 casadi_warning(
"fmi2GetInteger failed");
471 if (status != fmi2OK) {
472 casadi_warning(
"fmi2GetBoolean failed");
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));
494 const std::vector<std::string>& name_in,
const InputStruct* in)
const {
495 Value& v =
static_cast<Fmu2Memory*
>(m)->aux_value;
516 (*stats)[
"aux"] = aux;
518 for (
size_t k = 0; k < name_in.size(); ++k) {
522 const std::vector<size_t>& iind =
ired_.at(in[k].ind);
524 std::vector<double> v(iind.size());
525 for (
size_t i = 0; i < v.size(); ++i) v[i] =
value_in_.at(iind[i]);
527 (*stats)[name_in[k]] = v;
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) {
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.
void free_instance(void *instance) const override
std::vector< fmi2ValueReference > vr_string_
void init(const DaeBuilderInternal *dae) override
fmi2ExitInitializationModeTYPE * exit_initialization_mode_
std::vector< fmi2Real > init_real_
std::vector< fmi2ValueReference > vr_boolean_
std::vector< fmi2Boolean > init_boolean_
std::vector< std::string > vn_aux_integer_
void load_functions() override
~Fmu2() override
Destructor.
int init_mem(FmuMemory *m) const override
Initalize memory block.
fmi2CallbackFunctions functions_
std::vector< std::string > vn_aux_string_
fmi2SetupExperimentTYPE * setup_experiment_
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)
std::vector< fmi2Integer > init_integer_
int set_real(void *instance, const unsigned int *vr, size_t n_vr, const double *values, size_t n_values) const override
fmi2EnterInitializationModeTYPE * enter_initialization_mode_
fmi2InstantiateTYPE * instantiate_
int get_real(void *instance, const unsigned int *vr, size_t n_vr, double *values, size_t n_values, FmuMemory *m=nullptr) const override
fmi2GetIntegerTYPE * get_integer_
fmi2SetTimeTYPE * set_time_
fmi2GetBooleanTYPE * get_boolean_
void serialize_body(SerializingStream &s) const override
int get_aux(void *instance) override
fmi2SetBooleanTYPE * set_boolean_
std::vector< std::string > vn_aux_real_
int get_aux_impl(void *instance, Value &aux_value) const
static Fmu2 * deserialize(DeserializingStream &s)
void get_stats(FmuMemory *m, Dict *stats, const std::vector< std::string > &name_in, const InputStruct *in) const override
Get stats.
int exit_initialization_mode(void *instance) const override
fmi2SetStringTYPE * set_string_
fmi2SetIntegerTYPE * set_integer_
std::vector< fmi2ValueReference > vr_integer_
fmi2SetRealTYPE * set_real_
std::vector< std::string > vn_aux_boolean_
int set_time(void *instance, double t) const override
fmi2GetDirectionalDerivativeTYPE * get_directional_derivative_
fmi2GetDerivativesTYPE * get_derivatives_
int enter_initialization_mode(void *instance) const override
void * instantiate() const override
std::vector< fmi2ValueReference > vr_aux_string_
std::vector< fmi2ValueReference > vr_aux_integer_
FmuMemory * alloc_mem(const FmuFunction &f) const override
Create memory block.
std::vector< fmi2ValueReference > vr_real_
static std::string dll_infix()
fmi2FreeInstanceTYPE * free_instance_
fmi2EnterContinuousTimeModeTYPE * enter_continuous_time_mode_
fmi2NewDiscreteStatesTYPE * new_discrete_states_
int reset(void *instance)
int update_discrete_states(void *instance, EventMemory *eventmem) const override
int enter_continuous_time_mode(void *instance) const override
fmi2GetRealTYPE * get_real_
std::vector< fmi2ValueReference > vr_aux_real_
static void logger(fmi2ComponentEnvironment componentEnvironment, fmi2String instanceName, fmi2Status status, fmi2String category, fmi2String message,...)
void free_mem(void *mem) const override
Free memory block.
int set_values(void *instance) const override
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
fmi2GetStringTYPE * get_string_
std::vector< std::string > init_string_
std::vector< fmi2ValueReference > vr_aux_boolean_
int get_derivatives(void *instance, double *derivatives, size_t nx) const override
std::string instantiation_token_
std::vector< std::vector< size_t > > ired_
std::vector< std::string > aux_
virtual void serialize_body(SerializingStream &s) const
size_t n_in() const
Get the number of scheme inputs.
bool do_evaluation_dance_
std::string resource_loc_
std::vector< double > value_in_
virtual void init(const DaeBuilderInternal *dae)
size_t n_out() const
Get the number of scheme outputs.
virtual int init_mem(FmuMemory *m) const
Initalize memory block.
std::string instance_name_
bool provides_directional_derivatives_
Helper class for Serialization.
void version(const std::string &name, int v)
void pack(const Sparsity &e)
Serializes an object to the output stream.
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.
bool discrete_states_need_update
bool terminate_simulation
bool next_event_time_defined
bool nominals_of_continuous_states_changed
bool values_of_continuous_states_changed
std::vector< fmi2Boolean > v_boolean
std::vector< fmi2Real > v_real
std::vector< std::string > v_string
std::vector< fmi2Integer > v_integer
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.
unsigned int value_reference