]> gerrit.simantics Code Review - simantics/fmil.git/blobdiff - org.simantics.fmil.core/native/FMILibrary/src/Util/src/FMI2/fmi2_enums.c
Add FMILibrary-2.0.3 to org.simantics.fmil.core\native.
[simantics/fmil.git] / org.simantics.fmil.core / native / FMILibrary / src / Util / src / FMI2 / fmi2_enums.c
diff --git a/org.simantics.fmil.core/native/FMILibrary/src/Util/src/FMI2/fmi2_enums.c b/org.simantics.fmil.core/native/FMILibrary/src/Util/src/FMI2/fmi2_enums.c
new file mode 100644 (file)
index 0000000..07159a1
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+    Copyright (C) 2012 Modelon AB
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the BSD style license.
+
+     This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    FMILIB_License.txt file for more details.
+
+    You should have received a copy of the FMILIB_License.txt file
+    along with this program. If not, contact Modelon AB <http://www.modelon.com>.
+*/
+#include <assert.h>
+#include <stdio.h>
+
+#include <FMI2/fmi2_functions.h>
+#include <FMI2/fmi2_enums.h>
+
+const char* fmi2_naming_convention_to_string(fmi2_variable_naming_convension_enu_t convention) {
+    if(convention == fmi2_naming_enu_flat) return "flat";
+    if(convention == fmi2_naming_enu_structured) return "structured";
+    return "Unknown";
+}
+
+const char* fmi2_fmu_kind_to_string(fmi2_fmu_kind_enu_t kind) {
+    switch (kind) {
+    case fmi2_fmu_kind_me: return "ModelExchange";
+    case fmi2_fmu_kind_cs: return "CoSimulation";
+    case fmi2_fmu_kind_me_and_cs: return "ModelExchange and CoSimulation";
+       default: break;
+    }
+    return "Unknown";
+}
+
+const char* fmi2_dependency_factor_kind_to_string(fmi2_dependency_factor_kind_enu_t fc) {
+       switch(fc) {
+       case fmi2_dependency_factor_kind_dependent: return "dependent";
+       case fmi2_dependency_factor_kind_constant: return "constant";
+       case fmi2_dependency_factor_kind_fixed: return "fixed";
+       case fmi2_dependency_factor_kind_tunable: return "tunable";
+       case fmi2_dependency_factor_kind_discrete: return "discrete";
+       default:break;
+       }
+       return "illegal factor kind";
+}
+
+const char* fmi2_variability_to_string(fmi2_variability_enu_t v) {
+    switch(v) {
+    case fmi2_variability_enu_constant: return "constant";
+    case fmi2_variability_enu_fixed: return "fixed";
+    case fmi2_variability_enu_tunable: return "tunable";
+    case fmi2_variability_enu_discrete: return "discrete";
+    case fmi2_variability_enu_continuous: return "continuous";
+       default: break;
+    }
+    return "Unknown";
+}
+
+const char* fmi2_causality_to_string(fmi2_causality_enu_t c) {
+    switch(c) {
+    case fmi2_causality_enu_input: return "input";
+    case fmi2_causality_enu_output: return "output";
+    case fmi2_causality_enu_parameter: return "parameter";
+    case fmi2_causality_enu_calculated_parameter: return "calculatedParameter";
+    case fmi2_causality_enu_local: return "local";
+    case fmi2_causality_enu_independent: return "independent";
+       default: break;
+    };
+    return "Unknown";
+}
+
+const char* fmi2_status_to_string(fmi2_status_t status) {
+       switch(status) {
+       case fmi2_status_ok:
+               return "OK";
+       case fmi2_status_warning:
+               return "Warning";
+       case fmi2_status_discard:
+               return "Discard";
+       case fmi2_status_error:
+               return "Error";
+       case fmi2_status_fatal:
+               return "Fatal";
+       case fmi2_status_pending:
+               return "Pending";
+       default: break;
+       }
+       return "Undefined";
+}
+
+const char* fmi2_base_type_to_string(fmi2_base_type_enu_t bt) {
+    switch(bt) {
+    case fmi2_base_type_real: return "Real";
+    case fmi2_base_type_int: return "Integer";
+    case fmi2_base_type_bool: return "Boolean";
+    case fmi2_base_type_str: return "String";
+    case fmi2_base_type_enum: return "Enumeration";
+       default: break;
+    }
+    return "Error";
+}
+
+const char* fmi2_initial_to_string(fmi2_initial_enu_t ini) {
+       switch (ini) {
+       case fmi2_initial_enu_exact: return "exact";
+       case fmi2_initial_enu_approx: return "approx";
+       case fmi2_initial_enu_calculated: return "calculated";
+               default: break;
+       }
+       return "Undefined";
+}
+
+fmi2_initial_enu_t initialDefaultsTable[fmi2_variability_enu_unknown][fmi2_causality_enu_unknown] = {
+       /*              parameter                  calculated parameter,        input                     output                       local                        independent */
+       /* 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},
+       /* 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},
+       /* 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},
+       /* 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},
+       /* 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}
+};
+
+fmi2_initial_enu_t fmi2_get_default_initial(fmi2_variability_enu_t v, fmi2_causality_enu_t c) {
+       if((unsigned)v >= (unsigned)fmi2_variability_enu_unknown) return fmi2_initial_enu_unknown;
+       if((unsigned)c >= (unsigned)fmi2_causality_enu_unknown) return fmi2_initial_enu_unknown;
+       return initialDefaultsTable[v][c];
+}
+
+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) {
+       fmi2_initial_enu_t defaultInitial = fmi2_get_default_initial(v, c);
+       if( (defaultInitial == i) ||
+               ((unsigned)i >= (unsigned)fmi2_initial_enu_unknown) ||
+               (defaultInitial == fmi2_initial_enu_unknown))
+               return defaultInitial;
+       /*  At this point we know that v, c & i are fine and that (defaultInitial != i) 
+               Check the other allowed combinations: */
+       if(defaultInitial == fmi2_initial_enu_calculated) {
+               if(v >= fmi2_variability_enu_discrete) {
+                       return i;
+               }
+               else if(i != fmi2_initial_enu_exact)
+                       return i;
+       }
+       /* in all other cases the combination is not valid and default should be used */
+       return defaultInitial;
+}
+
+
+const char * fmi2_capability_to_string(fmi2_capabilities_enu_t id) {
+#define FMI2_ME_CAPABILITIES_ENU_TO_STR(c) case fmi2_me_ ## c: return "me_"#c;
+#define FMI2_CS_CAPABILITIES_ENU_TO_STR(c) case fmi2_cs_ ## c: return "cs_"#c;
+       switch (id) {
+       FMI2_ME_CAPABILITIES(FMI2_ME_CAPABILITIES_ENU_TO_STR)
+       FMI2_CS_CAPABILITIES(FMI2_CS_CAPABILITIES_ENU_TO_STR)
+       default: break;
+       }
+       return "Unknown";
+}
+
+const char * fmi2_SI_base_unit_to_string(fmi2_SI_base_units_enu_t id) {
+#define FMI2_SI_BASE_UNIT_ENU_TO_STR(c) case fmi2_SI_base_unit_ ## c: return #c;
+       switch(id) {
+               FMI2_SI_BASE_UNITS(FMI2_SI_BASE_UNIT_ENU_TO_STR)
+       default: break;
+       }
+       return "unknown";
+}
+
+/** \brief Convert a list of SI base unit exponents (corresponding to the IDs from  fmi2_SI_base_units_enu_t)
+       to a string of the form kg*m^2/s^2.
+
+       \param exp An array of SI base units exponents.
+       \param bufSize Size of the buffer to store the string. 
+       \param buf Buffer to store the string
+       \return Required size of the buffer to store the string including the terminating zero.
+               This most likely be under [8*fmi2_SI_base_units_Num]. If the return value is larger or equal 
+               than bufSize than the string could not be fitted in the buffer. 
+*/
+size_t fmi2_SI_base_unit_exp_to_string(const int exp[fmi2_SI_base_units_Num], size_t bufSize, char buf[]){
+       int i = 0;
+       int num_pos_exp = 0, num_neg_exp = 0; /* number of exponents */
+       size_t len = 0;
+       char tmp[fmi2_SI_base_units_Num * 20]; /* tmp is always enough size */
+       if(bufSize) buf[0] = 0; /* just to prevent errors */
+
+       /* count the exponents */
+       for(i = 0; i < fmi2_SI_base_units_Num; i++) {
+               if(exp[i] == 0) continue;
+               if(exp[i] < 0) 
+                       num_neg_exp ++;
+               else
+                       num_pos_exp ++;
+       }
+       if((num_neg_exp + num_pos_exp) == 0) { /* return "-" */ 
+                if (bufSize < 2) return 2;
+                buf[0] = '-';
+                buf[1] = 0;
+                return 2;
+       }
+       if(num_pos_exp == 0) {
+               /* we start with "one over", i.e., 1 */
+               tmp[0] = '1';
+               len = 1;
+       }
+       else {
+               len = 0;
+               /* print positive exp */
+               for(i = 0; i < fmi2_SI_base_units_Num; i++) {
+                       char* curp = tmp + len;
+                       int expi = exp[i];
+                       if(expi <= 0)  continue;
+                       if(len) {
+                               *curp = '*';
+                               curp++; len++;
+                       }
+
+                       strcpy(curp, fmi2_SI_base_unit_to_string((fmi2_SI_base_units_enu_t)i)) ;
+                       len += strlen(curp);
+                       curp = tmp + len;
+
+                       if(expi > 1) {
+                               *curp = '^';
+                               curp++; len++;
+
+                               sprintf(curp, "%d", expi); /*safe */
+                               len += strlen(curp);
+                       }
+               }
+       }
+       /* print negative exp */
+       if(num_neg_exp > 0) {
+               tmp[len++] = '/';
+               if(num_neg_exp > 1)
+                       tmp[len++] = '(';
+               num_neg_exp = 0;
+
+               for(i = 0; i < fmi2_SI_base_units_Num; i++) {
+                       char* curp = tmp + len;
+                       int expi = exp[i];
+                       if(expi >= 0)  continue;
+                       expi = -expi;
+                       if(num_neg_exp > 0) {
+                               *curp = '*';
+                               curp++; len++;
+                       }
+                       num_neg_exp++;
+                       strcpy(curp, fmi2_SI_base_unit_to_string((fmi2_SI_base_units_enu_t)i)) ;
+                       len += strlen(curp);
+                       curp = tmp + len;
+
+                       if(expi > 1) {
+                               *curp = '^';
+                               curp++; len++;
+
+                               sprintf(curp, "%d", expi); /*safe */
+                               len += strlen(curp);
+                       }
+               }
+               if(num_neg_exp > 1)
+                       tmp[len++] = ')';
+       }
+       strncpy(buf, tmp, bufSize);
+    if(len < bufSize) buf[len] = 0;
+       return len + 1;
+}