2 Copyright (C) 2012 Modelon AB
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the BSD style license.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 FMILIB_License.txt file for more details.
12 You should have received a copy of the FMILIB_License.txt file
13 along with this program. If not, contact Modelon AB <http://www.modelon.com>.
18 #include <FMI2/fmi2_functions.h>
19 #include <FMI2/fmi2_enums.h>
21 const char* fmi2_naming_convention_to_string(fmi2_variable_naming_convension_enu_t convention) {
22 if(convention == fmi2_naming_enu_flat) return "flat";
23 if(convention == fmi2_naming_enu_structured) return "structured";
27 const char* fmi2_fmu_kind_to_string(fmi2_fmu_kind_enu_t kind) {
29 case fmi2_fmu_kind_me: return "ModelExchange";
30 case fmi2_fmu_kind_cs: return "CoSimulation";
31 case fmi2_fmu_kind_me_and_cs: return "ModelExchange and CoSimulation";
37 const char* fmi2_dependency_factor_kind_to_string(fmi2_dependency_factor_kind_enu_t fc) {
39 case fmi2_dependency_factor_kind_dependent: return "dependent";
40 case fmi2_dependency_factor_kind_constant: return "constant";
41 case fmi2_dependency_factor_kind_fixed: return "fixed";
42 case fmi2_dependency_factor_kind_tunable: return "tunable";
43 case fmi2_dependency_factor_kind_discrete: return "discrete";
46 return "illegal factor kind";
49 const char* fmi2_variability_to_string(fmi2_variability_enu_t v) {
51 case fmi2_variability_enu_constant: return "constant";
52 case fmi2_variability_enu_fixed: return "fixed";
53 case fmi2_variability_enu_tunable: return "tunable";
54 case fmi2_variability_enu_discrete: return "discrete";
55 case fmi2_variability_enu_continuous: return "continuous";
61 const char* fmi2_causality_to_string(fmi2_causality_enu_t c) {
63 case fmi2_causality_enu_input: return "input";
64 case fmi2_causality_enu_output: return "output";
65 case fmi2_causality_enu_parameter: return "parameter";
66 case fmi2_causality_enu_calculated_parameter: return "calculatedParameter";
67 case fmi2_causality_enu_local: return "local";
68 case fmi2_causality_enu_independent: return "independent";
74 const char* fmi2_status_to_string(fmi2_status_t status) {
78 case fmi2_status_warning:
80 case fmi2_status_discard:
82 case fmi2_status_error:
84 case fmi2_status_fatal:
86 case fmi2_status_pending:
93 const char* fmi2_base_type_to_string(fmi2_base_type_enu_t bt) {
95 case fmi2_base_type_real: return "Real";
96 case fmi2_base_type_int: return "Integer";
97 case fmi2_base_type_bool: return "Boolean";
98 case fmi2_base_type_str: return "String";
99 case fmi2_base_type_enum: return "Enumeration";
105 const char* fmi2_initial_to_string(fmi2_initial_enu_t ini) {
107 case fmi2_initial_enu_exact: return "exact";
108 case fmi2_initial_enu_approx: return "approx";
109 case fmi2_initial_enu_calculated: return "calculated";
115 fmi2_initial_enu_t initialDefaultsTable[fmi2_variability_enu_unknown][fmi2_causality_enu_unknown] = {
116 /* parameter calculated parameter, input output local independent */
117 /* constant */ {fmi2_initial_enu_unknown, fmi2_initial_enu_unknown, fmi2_initial_enu_unknown, fmi2_initial_enu_exact, fmi2_initial_enu_exact, fmi2_initial_enu_unknown},
118 /* fixed */ {fmi2_initial_enu_exact, fmi2_initial_enu_calculated, fmi2_initial_enu_approx, fmi2_initial_enu_calculated, fmi2_initial_enu_calculated, fmi2_initial_enu_unknown},
119 /* tunable */ {fmi2_initial_enu_exact, fmi2_initial_enu_calculated, fmi2_initial_enu_approx, fmi2_initial_enu_calculated, fmi2_initial_enu_calculated, fmi2_initial_enu_unknown},
120 /* discrete */ {fmi2_initial_enu_unknown, fmi2_initial_enu_unknown, fmi2_initial_enu_approx, fmi2_initial_enu_calculated, fmi2_initial_enu_calculated, fmi2_initial_enu_unknown},
121 /* continuous */{fmi2_initial_enu_unknown, fmi2_initial_enu_unknown, fmi2_initial_enu_approx, fmi2_initial_enu_calculated, fmi2_initial_enu_calculated, fmi2_initial_enu_calculated}
124 fmi2_initial_enu_t fmi2_get_default_initial(fmi2_variability_enu_t v, fmi2_causality_enu_t c) {
125 if((unsigned)v >= (unsigned)fmi2_variability_enu_unknown) return fmi2_initial_enu_unknown;
126 if((unsigned)c >= (unsigned)fmi2_causality_enu_unknown) return fmi2_initial_enu_unknown;
127 return initialDefaultsTable[v][c];
130 FMILIB_EXPORT fmi2_initial_enu_t fmi2_get_valid_initial(fmi2_variability_enu_t v, fmi2_causality_enu_t c, fmi2_initial_enu_t i) {
131 fmi2_initial_enu_t defaultInitial = fmi2_get_default_initial(v, c);
132 if( (defaultInitial == i) ||
133 ((unsigned)i >= (unsigned)fmi2_initial_enu_unknown) ||
134 (defaultInitial == fmi2_initial_enu_unknown))
135 return defaultInitial;
136 /* At this point we know that v, c & i are fine and that (defaultInitial != i)
137 Check the other allowed combinations: */
138 if(defaultInitial == fmi2_initial_enu_calculated) {
139 if(v >= fmi2_variability_enu_discrete) {
142 else if(i != fmi2_initial_enu_exact)
145 /* in all other cases the combination is not valid and default should be used */
146 return defaultInitial;
150 const char * fmi2_capability_to_string(fmi2_capabilities_enu_t id) {
151 #define FMI2_ME_CAPABILITIES_ENU_TO_STR(c) case fmi2_me_ ## c: return "me_"#c;
152 #define FMI2_CS_CAPABILITIES_ENU_TO_STR(c) case fmi2_cs_ ## c: return "cs_"#c;
154 FMI2_ME_CAPABILITIES(FMI2_ME_CAPABILITIES_ENU_TO_STR)
155 FMI2_CS_CAPABILITIES(FMI2_CS_CAPABILITIES_ENU_TO_STR)
161 const char * fmi2_SI_base_unit_to_string(fmi2_SI_base_units_enu_t id) {
162 #define FMI2_SI_BASE_UNIT_ENU_TO_STR(c) case fmi2_SI_base_unit_ ## c: return #c;
164 FMI2_SI_BASE_UNITS(FMI2_SI_BASE_UNIT_ENU_TO_STR)
170 /** \brief Convert a list of SI base unit exponents (corresponding to the IDs from fmi2_SI_base_units_enu_t)
171 to a string of the form kg*m^2/s^2.
173 \param exp An array of SI base units exponents.
174 \param bufSize Size of the buffer to store the string.
175 \param buf Buffer to store the string
176 \return Required size of the buffer to store the string including the terminating zero.
177 This most likely be under [8*fmi2_SI_base_units_Num]. If the return value is larger or equal
178 than bufSize than the string could not be fitted in the buffer.
180 size_t fmi2_SI_base_unit_exp_to_string(const int exp[fmi2_SI_base_units_Num], size_t bufSize, char buf[]){
182 int num_pos_exp = 0, num_neg_exp = 0; /* number of exponents */
184 char tmp[fmi2_SI_base_units_Num * 20]; /* tmp is always enough size */
185 if(bufSize) buf[0] = 0; /* just to prevent errors */
187 /* count the exponents */
188 for(i = 0; i < fmi2_SI_base_units_Num; i++) {
189 if(exp[i] == 0) continue;
195 if((num_neg_exp + num_pos_exp) == 0) { /* return "-" */
196 if (bufSize < 2) return 2;
201 if(num_pos_exp == 0) {
202 /* we start with "one over", i.e., 1 */
208 /* print positive exp */
209 for(i = 0; i < fmi2_SI_base_units_Num; i++) {
210 char* curp = tmp + len;
212 if(expi <= 0) continue;
218 strcpy(curp, fmi2_SI_base_unit_to_string((fmi2_SI_base_units_enu_t)i)) ;
226 sprintf(curp, "%d", expi); /*safe */
231 /* print negative exp */
232 if(num_neg_exp > 0) {
238 for(i = 0; i < fmi2_SI_base_units_Num; i++) {
239 char* curp = tmp + len;
241 if(expi >= 0) continue;
243 if(num_neg_exp > 0) {
248 strcpy(curp, fmi2_SI_base_unit_to_string((fmi2_SI_base_units_enu_t)i)) ;
256 sprintf(curp, "%d", expi); /*safe */
263 strncpy(buf, tmp, bufSize);
264 if(len < bufSize) buf[len] = 0;