27 #include "fmu_function.hpp"
28 #include "dae_builder_internal.hpp"
33 struct Fmu2Memory :
public FmuMemory {
34 Fmu2::Value aux_value;
36 explicit Fmu2Memory(
const FmuFunction&
self) :
FmuMemory(
self) {}
41 auto m =
static_cast<Fmu2Memory*
>(mem);
51 return new Fmu2Memory(f);
55 delete static_cast<Fmu2Memory*
>(mem);
69 #elif defined(__APPLE__)
71 return sizeof(
void*) == 4 ?
"darwin32" :
"darwin64";
74 return sizeof(
void*) == 4 ?
"linux32" :
"linux64";
93 casadi_assert(v.
numel == 1,
"Vector variable support not implemented");
133 for (
auto&& s :
aux_) {
178 instantiate_ = load_function<fmi2InstantiateTYPE>(
"fmi2Instantiate");
179 free_instance_ = load_function<fmi2FreeInstanceTYPE>(
"fmi2FreeInstance");
180 reset_ = load_function<fmi2ResetTYPE>(
"fmi2Reset");
181 setup_experiment_ = load_function<fmi2SetupExperimentTYPE>(
"fmi2SetupExperiment");
183 "fmi2EnterInitializationMode");
185 "fmi2ExitInitializationMode");
187 "fmi2EnterContinuousTimeMode");
188 get_derivatives_ = load_function<fmi2GetDerivativesTYPE>(
"fmi2GetDerivatives");
189 set_time_ = load_function<fmi2SetTimeTYPE>(
"fmi2SetTime");
190 get_real_ = load_function<fmi2GetRealTYPE>(
"fmi2GetReal");
191 set_real_ = load_function<fmi2SetRealTYPE>(
"fmi2SetReal");
192 get_integer_ = load_function<fmi2GetIntegerTYPE>(
"fmi2GetInteger");
193 set_integer_ = load_function<fmi2SetIntegerTYPE>(
"fmi2SetInteger");
194 get_boolean_ = load_function<fmi2GetBooleanTYPE>(
"fmi2GetBoolean");
195 set_boolean_ = load_function<fmi2SetBooleanTYPE>(
"fmi2SetBoolean");
196 get_string_ = load_function<fmi2GetStringTYPE>(
"fmi2GetString");
197 set_string_ = load_function<fmi2SetStringTYPE>(
"fmi2SetString");
200 load_function<fmi2GetDirectionalDerivativeTYPE>(
"fmi2GetDirectionalDerivative");
213 fmi2String instanceName,
216 fmi2String message, ...) {
219 va_start(args, message);
222 size_t buf_sz =
sizeof(buf);
223 char* buf_dyn =
nullptr;
225 int n = vsnprintf(buf, buf_sz, message, args);
229 buf_dyn =
new char[buf_sz];
230 n = vsnprintf(buf_dyn, buf_sz, message, args);
234 uout() <<
"[" << instanceName <<
":" << category <<
"] "
235 << (buf_dyn ? buf_dyn : buf) << std::endl;
241 casadi_assert(n>=0,
"Print failure while processing '" + std::string(message) +
"'");
247 fmi2Type fmuType = fmi2ModelExchange;
250 fmi2Boolean visible = fmi2False;
251 fmi2Component c =
instantiate_(instanceName, fmuType, fmuGUID, fmuResourceLocation,
253 if (c == 0) casadi_error(
"fmi2Instantiate failed");
257 casadi_assert(status == fmi2OK,
"fmi2SetupExperiment failed");
264 auto c =
static_cast<fmi2Component
>(instance);
267 casadi_warning(
"No free_instance function pointer available");
272 auto c =
static_cast<fmi2Component
>(instance);
273 fmi2Status status =
reset_(c);
274 if (status != fmi2OK) {
275 casadi_warning(
"fmi2Reset failed");
282 auto c =
static_cast<fmi2Component
>(instance);
284 if (status != fmi2OK) {
285 casadi_warning(
"fmi2EnterInitializationMode failed: " +
str(status));
292 auto c =
static_cast<fmi2Component
>(instance);
294 if (status != fmi2OK) {
295 casadi_warning(
"fmi2ExitInitializationMode failed");
302 auto c =
static_cast<fmi2Component
>(instance);
304 if (status != fmi2OK) {
305 casadi_warning(
"fmi2EnterContinuousTimeMode failed");
312 auto c =
static_cast<fmi2Component
>(instance);
314 if (status != fmi2OK) {
315 casadi_warning(
"fmi2GetDerivatives failed");
322 auto c =
static_cast<fmi2Component
>(instance);
324 fmi2EventInfo eventInfo;
325 eventInfo.newDiscreteStatesNeeded = fmi2False;
326 eventInfo.terminateSimulation = fmi2False;
327 eventInfo.nominalsOfContinuousStatesChanged = fmi2False;
328 eventInfo.valuesOfContinuousStatesChanged = fmi2False;
329 eventInfo.nextEventTimeDefined = fmi2False;
330 eventInfo.nextEventTime = 0.0;
340 return status != fmi2OK;
344 const double* values,
size_t n_values)
const {
345 casadi_assert(n_vr == n_values,
"Vector-valued variables not supported in FMI 2");
350 fmi2Status status =
set_time_(instance, *values);
351 if (status != fmi2OK)
return 1;
359 fmi2Status status =
set_real_(instance, vr, n_vr, values);
360 return status != fmi2OK;
364 double* values,
size_t n_values)
const {
365 casadi_assert(n_vr == n_values,
"Vector-valued variables not supported in FMI 2");
368 fmi2Status status =
get_real_(instance,
nullptr, 0,
nullptr);
369 if (status != fmi2OK)
return 1;
371 static thread_local std::vector<double> derivate_dump;
372 if (derivate_dump.size() <
nx_) derivate_dump.resize(
nx_);
375 if (status != fmi2OK)
return 1;
377 fmi2Status status =
get_real_(instance, vr, n_vr, values);
378 return status != fmi2OK;
382 const unsigned int* vr_in,
size_t n_in,
const double* seed,
size_t n_seed,
383 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");
388 return status != fmi2OK;
392 auto c =
static_cast<fmi2Component
>(instance);
396 if (status != fmi2OK) {
397 casadi_warning(
"fmi2SetReal failed");
405 if (status != fmi2OK) {
406 casadi_warning(
"fmi2SetInteger failed");
414 if (status != fmi2OK) {
415 casadi_warning(
"fmi2SetBoolean failed");
420 for (
size_t k = 0; k <
vr_string_.size(); ++k) {
423 fmi2Status status =
set_string_(c, &vr, 1, &value);
424 if (status != fmi2OK) {
425 casadi_error(
"fmi2SetString failed for value reference " +
str(vr));
433 auto c =
static_cast<fmi2Component
>(instance);
438 if (status != fmi2OK) {
439 casadi_warning(
"fmi2GetReal failed");
447 if (status != fmi2OK) {
448 casadi_warning(
"fmi2GetInteger failed");
456 if (status != fmi2OK) {
457 casadi_warning(
"fmi2GetBoolean failed");
464 fmi2String value = aux_value.
v_string.at(k).c_str();
465 fmi2Status status =
set_string_(c, &vr, 1, &value);
466 if (status != fmi2OK) {
467 casadi_error(
"fmi2GetString failed for value reference " +
str(vr));
479 const std::vector<std::string>& name_in,
const InputStruct* in)
const {
480 Value& v =
static_cast<Fmu2Memory*
>(m)->aux_value;
501 (*stats)[
"aux"] = aux;
503 for (
size_t k = 0; k < name_in.size(); ++k) {
507 const std::vector<size_t>& iind =
ired_.at(in[k].ind);
509 std::vector<double> v(iind.size());
510 for (
size_t i = 0; i < v.size(); ++i) v[i] =
value_in_.at(iind[i]);
512 (*stats)[name_in[k]] = v;
518 const std::vector<std::string>& scheme_in,
519 const std::vector<std::string>& scheme_out,
520 const std::map<std::string, std::vector<size_t>>& scheme,
521 const std::vector<std::string>& aux)
522 :
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_
int get_real(void *instance, const unsigned int *vr, size_t n_vr, double *values, size_t n_values) const override
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_
fmi2GetIntegerTYPE * get_integer_
fmi2SetTimeTYPE * set_time_
fmi2GetBooleanTYPE * get_boolean_
void serialize_body(SerializingStream &s) const override
int get_aux(void *instance) override
std::string system_infix() const 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_
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_
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
std::vector< unsigned int > vr_in_
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