Browse Source

forgot to add these files

Cláudio Gomes 4 years ago
parent
commit
df05b5ed12

+ 17 - 0
SemanticAdaptationForFMI/Experiments/hierarchical_fmu/fmu20/fmu/cs/mass_spring_damper_hierarchical/documentation/_main.html

@@ -0,0 +1,17 @@
+<html>
+<head>
+<title>Documentation for mass_spring_damper.fmu</title>
+<style type="text/css">
+  html { font-family: Verdana, Arial, Helvetica, sans-serif; }
+  h1   { color: #000066; }
+</style>
+</head>
+<body>
+<h1>mass_spring_damper_hierarchical.fmu</h1>
+This FMU implements a wrapper of the mass_spring_damper.fmu, hereby denoted as internal FMU.
+The wrapper runs the internal FMU 10 times for each requested time step.
+The input comming into the wrapper is kept the same to the internal FMU.
+The last output of the internal fmu is the one that is sent to the output of the wrapper.
+</body>
+</html>
+

BIN
SemanticAdaptationForFMI/Experiments/hierarchical_fmu/fmu20/fmu/cs/mass_spring_damper_hierarchical/model.png


+ 66 - 0
SemanticAdaptationForFMI/Experiments/hierarchical_fmu/fmu20/fmu/cs/mass_spring_damper_hierarchical/modelDescription.xml

@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<fmiModelDescription
+  fmiVersion="2.0"
+  modelName="mass_spring_damper_hierarchical"
+  guid="{ae8ba062-ad27-4bfb-8ce5-54c82e9d7e35}"
+  numberOfEventIndicators="0">
+
+<CoSimulation
+  modelIdentifier="mass_spring_damper_hierarchical"
+  canHandleVariableCommunicationStepSize="true"/>
+
+<LogCategories>
+  <Category name="logAll"/>
+  <Category name="logError"/>
+  <Category name="logFmiCall"/>
+  <Category name="logEvent"/>
+</LogCategories>
+
+<ModelVariables>
+  <!-- Index for next variable = 1 -->
+  <ScalarVariable name="x" valueReference="0" description="the only state"
+                  causality="local" variability="continuous" initial="exact">
+    <Real start="1" />
+  </ScalarVariable>
+  <!-- Index for next variable = 2 -->
+  <ScalarVariable name="der(x)" valueReference="1" description="time derivative of x" causality="local" variability="continuous" initial="exact">
+    <Real derivative="1" start="0"/>
+  </ScalarVariable>
+  <!-- Index for next variable = 3 -->
+  <ScalarVariable name="der(der(x))" valueReference="2" description="time derivative of der(x)" causality="local" variability="continuous" initial="calculated">
+    <Real derivative="2"/>
+  </ScalarVariable>
+  <!-- Index for next variable = 4 -->
+  <ScalarVariable name="F_in" valueReference="3" description="Force input"
+                  causality="input" variability="continuous">
+    <Real start="0" />
+  </ScalarVariable>
+  <!-- Index for next variable = 5 -->
+  <ScalarVariable name="k" valueReference="4"
+                  causality="parameter" variability="fixed" initial="exact">
+    <Real start="1"/>
+  </ScalarVariable>
+  <!-- Index for next variable = 6 -->
+  <ScalarVariable name="c" valueReference="5"
+                  causality="parameter" variability="fixed" initial="exact">
+    <Real start="1"/>
+  </ScalarVariable>
+  <!-- Index for next variable = 7 -->
+  <ScalarVariable name="m" valueReference="6"
+                  causality="parameter" variability="fixed" initial="exact">
+    <Real start="1"/>
+  </ScalarVariable>
+</ModelVariables>
+
+<ModelStructure>
+  <Derivatives>
+    <Unknown index="2" />
+  </Derivatives>
+  <InitialUnknowns>
+    <Unknown index="1"/>
+    <Unknown index="2"/>
+    <Unknown index="3"/>
+  </InitialUnknowns>
+</ModelStructure>
+
+</fmiModelDescription>

+ 714 - 0
SemanticAdaptationForFMI/Experiments/hierarchical_fmu/fmu20/fmu/cs/mass_spring_damper_hierarchical/sources/fmuTemplate.c

@@ -0,0 +1,714 @@
+/* ---------------------------------------------------------------------------*
+ * fmuTemplate.c
+ * Implementation of the FMI interface based on functions and macros to
+ * be defined by the includer of this file. 
+ * If FMI_COSIMULATION is defined, this implements "FMI for Co-Simulation 2.0",
+ * otherwise "FMI for Model Exchange 2.0".
+ * The "FMI for Co-Simulation 2.0", implementation assumes that exactly the
+ * following capability flags are set to fmi2True:
+ *    canHandleVariableCommunicationStepSize, i.e. fmi2DoStep step size can vary
+ * and all other capability flags are set to default, i.e. to fmi2False or 0.
+ *
+ * Revision history
+ *  07.03.2014 initial version released in FMU SDK 2.0.0
+ *  02.04.2014 allow modules to request termination of simulation, better time
+ *             event handling, initialize() moved from fmi2EnterInitialization to
+ *             fmi2ExitInitialization, correct logging message format in fmi2DoStep.
+ *  10.04.2014 use FMI 2.0 headers that prefix function and types names with 'fmi2'.
+ *  13.06.2014 when fmi2setDebugLogging is called with 0 categories, set all
+ *             categories to loggingOn value.
+ *  09.07.2014 track all states of Model-exchange and Co-simulation and check
+ *             the allowed calling sequences, explicit isTimeEvent parameter for
+ *             eventUpdate function of the model, lazy computation of computed values.
+ *
+ * Author: Adrian Tirea
+ * Copyright QTronic GmbH. All rights reserved.
+ * ---------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef max
+#define max(a,b) ((a)>(b) ? (a) : (b))
+#endif
+
+// ---------------------------------------------------------------------------
+// Private helpers used below to validate function arguments
+// ---------------------------------------------------------------------------
+
+static fmi2Boolean invalidNumber(ModelInstance *comp, const char *f, const char *arg, int n, int nExpected) {
+    if (n != nExpected) {
+        comp->state = modelError;
+        FILTERED_LOG(comp, fmi2Error, LOG_ERROR, "%s: Invalid argument %s = %d. Expected %d.", f, arg, n, nExpected)
+        return fmi2True;
+    }
+    return fmi2False;
+}
+
+static fmi2Boolean invalidState(ModelInstance *comp, const char *f, int statesExpected) {
+    if (!comp)
+        return fmi2True;
+    if (!(comp->state & statesExpected)) {
+        comp->state = modelError;
+        FILTERED_LOG(comp, fmi2Error, LOG_ERROR, "%s: Illegal call sequence.", f)
+        return fmi2True;
+    }
+    return fmi2False;
+}
+
+static fmi2Boolean nullPointer(ModelInstance* comp, const char *f, const char *arg, const void *p) {
+    if (!p) {
+        comp->state = modelError;
+        FILTERED_LOG(comp, fmi2Error, LOG_ERROR, "%s: Invalid argument %s = NULL.", f, arg)
+        return fmi2True;
+    }
+    return fmi2False;
+}
+
+static fmi2Boolean vrOutOfRange(ModelInstance *comp, const char *f, fmi2ValueReference vr, int end) {
+    if (vr >= end) {
+        FILTERED_LOG(comp, fmi2Error, LOG_ERROR, "%s: Illegal value reference %u.", f, vr)
+        comp->state = modelError;
+        return fmi2True;
+    }
+    return fmi2False;
+}
+
+static fmi2Status unsupportedFunction(fmi2Component c, const char *fName, int statesExpected) {
+    ModelInstance *comp = (ModelInstance *)c;
+    fmi2CallbackLogger log = comp->functions->logger;
+    if (invalidState(comp, fName, statesExpected))
+        return fmi2Error;
+    FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, fName);
+    FILTERED_LOG(comp, fmi2Error, LOG_ERROR, "%s: Function not implemented.", fName)
+    return fmi2Error;
+}
+
+fmi2Status setString(fmi2Component comp, fmi2ValueReference vr, fmi2String value) {
+    return fmi2SetString(comp, &vr, 1, &value);
+}
+
+// ---------------------------------------------------------------------------
+// Private helpers logger
+// ---------------------------------------------------------------------------
+
+// return fmi2True if logging category is on. Else return fmi2False.
+fmi2Boolean isCategoryLogged(ModelInstance *comp, int categoryIndex) {
+    if (categoryIndex < NUMBER_OF_CATEGORIES
+        && (comp->logCategories[categoryIndex] || comp->logCategories[LOG_ALL])) {
+        return fmi2True;
+    }
+    return fmi2False;
+}
+
+// ---------------------------------------------------------------------------
+// FMI functions
+// ---------------------------------------------------------------------------
+fmi2Component fmi2Instantiate(fmi2String instanceName, fmi2Type fmuType, fmi2String fmuGUID,
+                            fmi2String fmuResourceLocation, const fmi2CallbackFunctions *functions,
+                            fmi2Boolean visible, fmi2Boolean loggingOn) {
+    // ignoring arguments: fmuResourceLocation, visible
+    ModelInstance *comp;
+    if (!functions->logger) {
+        return NULL;
+    }
+
+    if (!functions->allocateMemory || !functions->freeMemory) {
+        functions->logger(functions->componentEnvironment, instanceName, fmi2Error, "error",
+                "fmi2Instantiate: Missing callback function.");
+        return NULL;
+    }
+    if (!instanceName || strlen(instanceName) == 0) {
+        functions->logger(functions->componentEnvironment, "?", fmi2Error, "error",
+                "fmi2Instantiate: Missing instance name.");
+        return NULL;
+    }
+    if (!fmuGUID || strlen(fmuGUID) == 0) {
+        functions->logger(functions->componentEnvironment, instanceName, fmi2Error, "error",
+                "fmi2Instantiate: Missing GUID.");
+        return NULL;
+    }
+    if (strcmp(fmuGUID, MODEL_GUID)) {
+        functions->logger(functions->componentEnvironment, instanceName, fmi2Error, "error",
+                "fmi2Instantiate: Wrong GUID %s. Expected %s.", fmuGUID, MODEL_GUID);
+        return NULL;
+    }
+    comp = (ModelInstance *)functions->allocateMemory(1, sizeof(ModelInstance));
+    if (comp) {
+        int i;
+        comp->r = (fmi2Real *)   functions->allocateMemory(NUMBER_OF_REALS,    sizeof(fmi2Real));
+        comp->i = (fmi2Integer *)functions->allocateMemory(NUMBER_OF_INTEGERS, sizeof(fmi2Integer));
+        comp->b = (fmi2Boolean *)functions->allocateMemory(NUMBER_OF_BOOLEANS, sizeof(fmi2Boolean));
+        comp->s = (fmi2String *) functions->allocateMemory(NUMBER_OF_STRINGS,  sizeof(fmi2String));
+        comp->isPositive = (fmi2Boolean *)functions->allocateMemory(NUMBER_OF_EVENT_INDICATORS,
+            sizeof(fmi2Boolean));
+        comp->instanceName = (char *)functions->allocateMemory(1 + strlen(instanceName), sizeof(char));
+        comp->GUID = (char *)functions->allocateMemory(1 + strlen(fmuGUID), sizeof(char));
+		
+        // set all categories to on or off. fmi2SetDebugLogging should be called to choose specific categories.
+        for (i = 0; i < NUMBER_OF_CATEGORIES; i++) {
+            comp->logCategories[i] = loggingOn;
+        }
+    }
+    if (!comp || !comp->r || !comp->i || !comp->b || !comp->s || !comp->isPositive
+        || !comp->instanceName || !comp->GUID) {
+
+        functions->logger(functions->componentEnvironment, instanceName, fmi2Error, "error",
+            "fmi2Instantiate: Out of memory.");
+        return NULL;
+    }
+    comp->time = 0; // overwrite in fmi2SetupExperiment, fmi2SetTime
+    strcpy((char *)comp->instanceName, (char *)instanceName);
+    comp->type = fmuType;
+    strcpy((char *)comp->GUID, (char *)fmuGUID);
+    comp->functions = functions;
+    comp->componentEnvironment = functions->componentEnvironment;
+    comp->loggingOn = loggingOn;
+    comp->state = modelInstantiated;
+	instantiate(comp);  // to be implemented by the includer of this file
+    setStartValues(comp); // to be implemented by the includer of this file
+    comp->isDirtyValues = fmi2True; // because we just called setStartValues
+    comp->isNewEventIteration = fmi2False;
+	
+    comp->eventInfo.newDiscreteStatesNeeded = fmi2False;
+    comp->eventInfo.terminateSimulation = fmi2False;
+    comp->eventInfo.nominalsOfContinuousStatesChanged = fmi2False;
+    comp->eventInfo.valuesOfContinuousStatesChanged = fmi2False;
+    comp->eventInfo.nextEventTimeDefined = fmi2False;
+    comp->eventInfo.nextEventTime = 0;
+
+    FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "fmi2Instantiate: GUID=%s", fmuGUID)
+
+    return comp;
+}
+
+fmi2Status fmi2SetupExperiment(fmi2Component c, fmi2Boolean toleranceDefined, fmi2Real tolerance,
+                            fmi2Real startTime, fmi2Boolean stopTimeDefined, fmi2Real stopTime) {
+    // ignore arguments: stopTimeDefined, stopTime
+    ModelInstance *comp = (ModelInstance *)c;
+    if (invalidState(comp, "fmi2SetupExperiment", MASK_fmi2SetupExperiment))
+        return fmi2Error;
+	
+	FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, ">fmi2SetupExperiment: toleranceDefined=%d tolerance=%g",
+        toleranceDefined, tolerance)
+	
+	fmi2Status status = setupExperiment(comp, toleranceDefined, tolerance, startTime, stopTimeDefined, stopTime); // to be implemented by includer.
+	
+    comp->time = startTime;
+	
+	FILTERED_LOG(comp, status, LOG_FMI_CALL, "<fmi2SetupExperiment",
+        toleranceDefined, tolerance)
+	
+    return status;
+}
+
+fmi2Status fmi2EnterInitializationMode(fmi2Component c) {
+    ModelInstance *comp = (ModelInstance *)c;
+    if (invalidState(comp, "fmi2EnterInitializationMode", MASK_fmi2EnterInitializationMode))
+        return fmi2Error;
+	
+	fmi2Status status = enterInitializationMode(comp); // to be implemented by includer.
+	
+    FILTERED_LOG(comp, status, LOG_FMI_CALL, "fmi2EnterInitializationMode")
+	
+	comp->state = modelInitializationMode;		
+	
+    return status;
+}
+
+fmi2Status fmi2ExitInitializationMode(fmi2Component c) {
+    ModelInstance *comp = (ModelInstance *)c;
+    if (invalidState(comp, "fmi2ExitInitializationMode", MASK_fmi2ExitInitializationMode))
+        return fmi2Error;
+	
+	fmi2Status status = exitInitializationMode(comp); // to be implemented by includer.
+	
+    FILTERED_LOG(comp, status, LOG_FMI_CALL, "fmi2ExitInitializationMode")
+
+    // if values were set and no fmi2GetXXX triggered update before,
+    // ensure calculated values are updated now
+    if (comp->isDirtyValues) {
+        calculateValues(comp);
+        comp->isDirtyValues = fmi2False;
+    }
+
+    if (comp->type == fmi2ModelExchange) {
+        comp->state = modelEventMode;
+        comp->isNewEventIteration = fmi2True;
+    }
+    else comp->state = modelStepComplete;
+    return status;
+}
+
+fmi2Status fmi2Terminate(fmi2Component c) {
+    ModelInstance *comp = (ModelInstance *)c;
+    if (invalidState(comp, "fmi2Terminate", MASK_fmi2Terminate))
+        return fmi2Error;
+	
+	fmi2Status status = terminate(comp); // to be implemented by includer.
+	
+    FILTERED_LOG(comp, status, LOG_FMI_CALL, "fmi2Terminate")
+
+    comp->state = modelTerminated;
+    return status;
+}
+
+fmi2Status fmi2Reset(fmi2Component c) {
+    ModelInstance* comp = (ModelInstance *)c;
+    if (invalidState(comp, "fmi2Reset", MASK_fmi2Reset))
+        return fmi2Error;
+    FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "fmi2Reset")
+
+    comp->state = modelInstantiated;
+	fmi2Status status = reset(comp); // to be implemented by includer.
+    setStartValues(comp); // to be implemented by the includer of this file
+    comp->isDirtyValues = fmi2True; // because we just called setStartValues
+    return status;
+}
+
+void fmi2FreeInstance(fmi2Component c) {
+    ModelInstance *comp = (ModelInstance *)c;
+    if (!comp) return;
+    if (invalidState(comp, "fmi2FreeInstance", MASK_fmi2FreeInstance))
+        return;
+	
+	fmi2Status status = freeInstance(comp);
+	
+    FILTERED_LOG(comp, status, LOG_FMI_CALL, "fmi2FreeInstance")
+	
+    if (comp->r) comp->functions->freeMemory(comp->r);
+    if (comp->i) comp->functions->freeMemory(comp->i);
+    if (comp->b) comp->functions->freeMemory(comp->b);
+    if (comp->s) {
+        int i;
+        for (i = 0; i < NUMBER_OF_STRINGS; i++){
+            if (comp->s[i]) comp->functions->freeMemory((void *)comp->s[i]);
+        }
+        comp->functions->freeMemory((void *)comp->s);
+    }
+    if (comp->isPositive) comp->functions->freeMemory(comp->isPositive);
+    if (comp->instanceName) comp->functions->freeMemory((void *)comp->instanceName);
+    if (comp->GUID) comp->functions->freeMemory((void *)comp->GUID);
+    comp->functions->freeMemory(comp);
+}
+
+// ---------------------------------------------------------------------------
+// FMI functions: class methods not depending of a specific model instance
+// ---------------------------------------------------------------------------
+
+const char* fmi2GetVersion() {
+    return fmi2Version;
+}
+
+const char* fmi2GetTypesPlatform() {
+    return fmi2TypesPlatform;
+}
+
+// ---------------------------------------------------------------------------
+// FMI functions: logging control, setters and getters for Real, Integer,
+// Boolean, String
+// ---------------------------------------------------------------------------
+
+fmi2Status fmi2SetDebugLogging(fmi2Component c, fmi2Boolean loggingOn, size_t nCategories, const fmi2String categories[]) {
+    // ignore arguments: nCategories, categories
+    int i, j;
+    ModelInstance *comp = (ModelInstance *)c;
+    if (invalidState(comp, "fmi2SetDebugLogging", MASK_fmi2SetDebugLogging))
+        return fmi2Error;
+    comp->loggingOn = loggingOn;
+    FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "fmi2SetDebugLogging")
+	
+	FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "Resetting all %u categories", nCategories)
+    // reset all categories
+    for (j = 0; j < NUMBER_OF_CATEGORIES; j++) {
+        comp->logCategories[j] = fmi2False;
+    }
+	
+	FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "Categories reset")
+    
+    if (nCategories == 0) {
+        // no category specified, set all categories to have loggingOn value
+		FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "No category specified, so all of the become active.")
+		
+        for (j = 0; j < NUMBER_OF_CATEGORIES; j++) {
+            comp->logCategories[j] = loggingOn;
+        }
+    } else {
+        // set specific categories on
+		FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "Categories specified. Activating them.")
+		
+        for (i = 0; i < nCategories; i++) {
+            fmi2Boolean categoryFound = fmi2False;
+            for (j = 0; j < NUMBER_OF_CATEGORIES; j++) {
+                if (strcmp(logCategoriesNames[j], categories[i]) == 0) {
+                    comp->logCategories[j] = loggingOn;
+                    categoryFound = fmi2True;
+                    break;
+                }
+            }
+            if (!categoryFound) {
+                comp->functions->logger(comp->componentEnvironment, comp->instanceName, fmi2Warning,
+                    logCategoriesNames[LOG_ERROR],
+                    "logging category '%s' is not supported by model", categories[i]);
+            }
+        }
+    }
+
+    FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "fmi2SetDebugLogging")
+    return fmi2OK;
+}
+
+fmi2Status fmi2GetReal (fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2Real value[]) {
+    int i;
+    ModelInstance *comp = (ModelInstance *)c;
+    if (invalidState(comp, "fmi2GetReal", MASK_fmi2GetReal))
+        return fmi2Error;
+    if (nvr > 0 && nullPointer(comp, "fmi2GetReal", "vr[]", vr))
+        return fmi2Error;
+    if (nvr > 0 && nullPointer(comp, "fmi2GetReal", "value[]", value))
+        return fmi2Error;
+    if (nvr > 0 && comp->isDirtyValues) {
+        calculateValues(comp);
+        comp->isDirtyValues = fmi2True;
+    }
+#if NUMBER_OF_REALS > 0
+    for (i = 0; i < nvr; i++) {
+        if (vrOutOfRange(comp, "fmi2GetReal", vr[i], NUMBER_OF_REALS))
+            return fmi2Error;
+        value[i] = getReal(comp, vr[i]); // to be implemented by the includer of this file
+
+        FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "fmi2GetReal: #r%u# = %.16g", vr[i], value[i])
+    }
+#endif
+    return fmi2OK;
+}
+
+fmi2Status fmi2GetInteger(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2Integer value[]) {
+    int i;
+    ModelInstance *comp = (ModelInstance *)c;
+    if (invalidState(comp, "fmi2GetInteger", MASK_fmi2GetInteger))
+        return fmi2Error;
+    if (nvr > 0 && nullPointer(comp, "fmi2GetInteger", "vr[]", vr))
+            return fmi2Error;
+    if (nvr > 0 && nullPointer(comp, "fmi2GetInteger", "value[]", value))
+            return fmi2Error;
+    if (nvr > 0 && comp->isDirtyValues) {
+        calculateValues(comp);
+        comp->isDirtyValues = fmi2False;
+    }
+    for (i = 0; i < nvr; i++) {
+        if (vrOutOfRange(comp, "fmi2GetInteger", vr[i], NUMBER_OF_INTEGERS))
+            return fmi2Error;
+        value[i] = comp->i[vr[i]];
+        FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "fmi2GetInteger: #i%u# = %d", vr[i], value[i])
+    }
+    return fmi2OK;
+}
+
+fmi2Status fmi2GetBoolean(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2Boolean value[]) {
+    int i;
+    ModelInstance *comp = (ModelInstance *)c;
+    if (invalidState(comp, "fmi2GetBoolean", MASK_fmi2GetBoolean))
+        return fmi2Error;
+    if (nvr > 0 && nullPointer(comp, "fmi2GetBoolean", "vr[]", vr))
+            return fmi2Error;
+    if (nvr > 0 && nullPointer(comp, "fmi2GetBoolean", "value[]", value))
+            return fmi2Error;
+    if (nvr > 0 && comp->isDirtyValues) {
+        calculateValues(comp);
+        comp->isDirtyValues = fmi2False;
+    }
+    for (i = 0; i < nvr; i++) {
+        if (vrOutOfRange(comp, "fmi2GetBoolean", vr[i], NUMBER_OF_BOOLEANS))
+            return fmi2Error;
+        value[i] = comp->b[vr[i]];
+        FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "fmi2GetBoolean: #b%u# = %s", vr[i], value[i]? "true" : "false")
+    }
+    return fmi2OK;
+}
+
+fmi2Status fmi2GetString (fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2String value[]) {
+    int i;
+    ModelInstance *comp = (ModelInstance *)c;
+    if (invalidState(comp, "fmi2GetString", MASK_fmi2GetString))
+        return fmi2Error;
+    if (nvr>0 && nullPointer(comp, "fmi2GetString", "vr[]", vr))
+            return fmi2Error;
+    if (nvr>0 && nullPointer(comp, "fmi2GetString", "value[]", value))
+            return fmi2Error;
+    if (nvr > 0 && comp->isDirtyValues) {
+        calculateValues(comp);
+        comp->isDirtyValues = fmi2False;
+    }
+    for (i=0; i<nvr; i++) {
+        if (vrOutOfRange(comp, "fmi2GetString", vr[i], NUMBER_OF_STRINGS))
+            return fmi2Error;
+        value[i] = comp->s[vr[i]];
+        FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "fmi2GetString: #s%u# = '%s'", vr[i], value[i])
+    }
+    return fmi2OK;
+}
+
+fmi2Status fmi2SetReal (fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2Real value[]) {
+    int i;
+    ModelInstance *comp = (ModelInstance *)c;
+    if (invalidState(comp, "fmi2SetReal", MASK_fmi2SetReal))
+        return fmi2Error;
+    if (nvr > 0 && nullPointer(comp, "fmi2SetReal", "vr[]", vr))
+        return fmi2Error;
+    if (nvr > 0 && nullPointer(comp, "fmi2SetReal", "value[]", value))
+        return fmi2Error;
+    FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "fmi2SetReal: nvr = %d", nvr)
+    // no check whether setting the value is allowed in the current state
+    for (i = 0; i < nvr; i++) {
+        if (vrOutOfRange(comp, "fmi2SetReal", vr[i], NUMBER_OF_REALS))
+            return fmi2Error;
+        FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "fmi2SetReal: #r%d# = %.16g", vr[i], value[i])
+        comp->r[vr[i]] = value[i];
+    }
+    if (nvr > 0) comp->isDirtyValues = fmi2True;
+    return fmi2OK;
+}
+
+fmi2Status fmi2SetInteger(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2Integer value[]) {
+    int i;
+    ModelInstance *comp = (ModelInstance *)c;
+    if (invalidState(comp, "fmi2SetInteger", MASK_fmi2SetInteger))
+        return fmi2Error;
+    if (nvr > 0 && nullPointer(comp, "fmi2SetInteger", "vr[]", vr))
+        return fmi2Error;
+    if (nvr > 0 && nullPointer(comp, "fmi2SetInteger", "value[]", value))
+        return fmi2Error;
+    FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "fmi2SetInteger: nvr = %d", nvr)
+
+    for (i = 0; i < nvr; i++) {
+        if (vrOutOfRange(comp, "fmi2SetInteger", vr[i], NUMBER_OF_INTEGERS))
+            return fmi2Error;
+        FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "fmi2SetInteger: #i%d# = %d", vr[i], value[i])
+        comp->i[vr[i]] = value[i];
+    }
+    if (nvr > 0) comp->isDirtyValues = fmi2True;
+    return fmi2OK;
+}
+
+fmi2Status fmi2SetBoolean(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2Boolean value[]) {
+    int i;
+    ModelInstance *comp = (ModelInstance *)c;
+    if (invalidState(comp, "fmi2SetBoolean", MASK_fmi2SetBoolean))
+        return fmi2Error;
+    if (nvr>0 && nullPointer(comp, "fmi2SetBoolean", "vr[]", vr))
+        return fmi2Error;
+    if (nvr>0 && nullPointer(comp, "fmi2SetBoolean", "value[]", value))
+        return fmi2Error;
+    FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "fmi2SetBoolean: nvr = %d", nvr)
+
+    for (i = 0; i < nvr; i++) {
+        if (vrOutOfRange(comp, "fmi2SetBoolean", vr[i], NUMBER_OF_BOOLEANS))
+            return fmi2Error;
+        FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "fmi2SetBoolean: #b%d# = %s", vr[i], value[i] ? "true" : "false")
+        comp->b[vr[i]] = value[i];
+    }
+    if (nvr > 0) comp->isDirtyValues = fmi2True;
+    return fmi2OK;
+}
+
+fmi2Status fmi2SetString (fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2String value[]) {
+    int i, n;
+    ModelInstance *comp = (ModelInstance *)c;
+    if (invalidState(comp, "fmi2SetString", MASK_fmi2SetString))
+        return fmi2Error;
+    if (nvr>0 && nullPointer(comp, "fmi2SetString", "vr[]", vr))
+        return fmi2Error;
+    if (nvr>0 && nullPointer(comp, "fmi2SetString", "value[]", value))
+        return fmi2Error;
+    FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "fmi2SetString: nvr = %d", nvr)
+
+    for (i = 0; i < nvr; i++) {
+        char *string = (char *)comp->s[vr[i]];
+        if (vrOutOfRange(comp, "fmi2SetString", vr[i], NUMBER_OF_STRINGS))
+            return fmi2Error;
+        FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "fmi2SetString: #s%d# = '%s'", vr[i], value[i])
+
+        if (value[i] == NULL) {
+            if (string) comp->functions->freeMemory(string);
+            comp->s[vr[i]] = NULL;
+            FILTERED_LOG(comp, fmi2Warning, LOG_ERROR, "fmi2SetString: string argument value[%d] = NULL.", i);
+        } else {
+            if (string == NULL || strlen(string) < strlen(value[i])) {
+                if (string) comp->functions->freeMemory(string);
+                comp->s[vr[i]] = (char *)comp->functions->allocateMemory(1 + strlen(value[i]), sizeof(char));
+                if (!comp->s[vr[i]]) {
+                    comp->state = modelError;
+                    FILTERED_LOG(comp, fmi2Error, LOG_ERROR, "fmi2SetString: Out of memory.")
+                    return fmi2Error;
+                }
+            }
+            strcpy((char *)comp->s[vr[i]], (char *)value[i]);
+        }
+    }
+    if (nvr > 0) comp->isDirtyValues = fmi2True;
+    return fmi2OK;
+}
+
+fmi2Status fmi2GetFMUstate(fmi2Component c, fmi2FMUstate* FMUstate) {
+    return unsupportedFunction(c, "fmi2GetFMUstate", MASK_fmi2GetFMUstate);
+}
+fmi2Status fmi2SetFMUstate (fmi2Component c, fmi2FMUstate FMUstate) {
+    return unsupportedFunction(c, "fmi2SetFMUstate", MASK_fmi2SetFMUstate);
+}
+fmi2Status fmi2FreeFMUstate(fmi2Component c, fmi2FMUstate* FMUstate) {
+    return unsupportedFunction(c, "fmi2FreeFMUstate", MASK_fmi2FreeFMUstate);
+}
+fmi2Status fmi2SerializedFMUstateSize(fmi2Component c, fmi2FMUstate FMUstate, size_t *size) {
+    return unsupportedFunction(c, "fmi2SerializedFMUstateSize", MASK_fmi2SerializedFMUstateSize);
+}
+fmi2Status fmi2SerializeFMUstate (fmi2Component c, fmi2FMUstate FMUstate, fmi2Byte serializedState[], size_t size) {
+    return unsupportedFunction(c, "fmi2SerializeFMUstate", MASK_fmi2SerializeFMUstate);
+}
+fmi2Status fmi2DeSerializeFMUstate (fmi2Component c, const fmi2Byte serializedState[], size_t size,
+                                    fmi2FMUstate* FMUstate) {
+    return unsupportedFunction(c, "fmi2DeSerializeFMUstate", MASK_fmi2DeSerializeFMUstate);
+}
+
+fmi2Status fmi2GetDirectionalDerivative(fmi2Component c, const fmi2ValueReference vUnknown_ref[], size_t nUnknown,
+                                        const fmi2ValueReference vKnown_ref[] , size_t nKnown,
+                                        const fmi2Real dvKnown[], fmi2Real dvUnknown[]) {
+    return unsupportedFunction(c, "fmi2GetDirectionalDerivative", MASK_fmi2GetDirectionalDerivative);
+}
+
+// ---------------------------------------------------------------------------
+// Functions for FMI for Co-Simulation
+// ---------------------------------------------------------------------------
+#ifdef FMI_COSIMULATION
+/* Simulating the slave */
+fmi2Status fmi2SetRealInputDerivatives(fmi2Component c, const fmi2ValueReference vr[], size_t nvr,
+                                     const fmi2Integer order[], const fmi2Real value[]) {
+    ModelInstance *comp = (ModelInstance *)c;
+    if (invalidState(comp, "fmi2SetRealInputDerivatives", MASK_fmi2SetRealInputDerivatives)) {
+        return fmi2Error;
+    }
+    FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "fmi2SetRealInputDerivatives: nvr= %d", nvr)
+    FILTERED_LOG(comp, fmi2Error, LOG_ERROR, "fmi2SetRealInputDerivatives: ignoring function call."
+        " This model cannot interpolate inputs: canInterpolateInputs=\"fmi2False\"")
+    return fmi2Error;
+}
+
+fmi2Status fmi2GetRealOutputDerivatives(fmi2Component c, const fmi2ValueReference vr[], size_t nvr,
+                                      const fmi2Integer order[], fmi2Real value[]) {
+    int i;
+    ModelInstance *comp = (ModelInstance *)c;
+    if (invalidState(comp, "fmi2GetRealOutputDerivatives", MASK_fmi2GetRealOutputDerivatives))
+        return fmi2Error;
+    FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "fmi2GetRealOutputDerivatives: nvr= %d", nvr)
+    FILTERED_LOG(comp, fmi2Error, LOG_ERROR,"fmi2GetRealOutputDerivatives: ignoring function call."
+        " This model cannot compute derivatives of outputs: MaxOutputDerivativeOrder=\"0\"")
+    for (i = 0; i < nvr; i++) value[i] = 0;
+    return fmi2Error;
+}
+
+fmi2Status fmi2CancelStep(fmi2Component c) {
+    ModelInstance *comp = (ModelInstance *)c;
+    if (invalidState(comp, "fmi2CancelStep", MASK_fmi2CancelStep)) {
+        // always fmi2CancelStep is invalid, because model is never in modelStepInProgress state.
+        return fmi2Error;
+    }
+    FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "fmi2CancelStep")
+    FILTERED_LOG(comp, fmi2Error, LOG_ERROR,"fmi2CancelStep: Can be called when fmi2DoStep returned fmi2Pending."
+        " This is not the case.");
+    // comp->state = modelStepCanceled;
+    return fmi2Error;
+}
+
+fmi2Status fmi2DoStep(fmi2Component c, fmi2Real currentCommunicationPoint,
+                    fmi2Real communicationStepSize, fmi2Boolean noSetFMUStatePriorToCurrentPoint) {
+    ModelInstance *comp = (ModelInstance *)c;
+    
+    if (invalidState(comp, "fmi2DoStep", MASK_fmi2DoStep))
+        return fmi2Error;
+
+    if (communicationStepSize <= 0) {
+        FILTERED_LOG(comp, fmi2Error, LOG_ERROR,
+            "fmi2DoStep: communication step size must be > 0. Fount %g.", communicationStepSize)
+        comp->state = modelError;
+        return fmi2Error;
+    }
+	
+	fmi2Status status = doStep(comp, currentCommunicationPoint, communicationStepSize, noSetFMUStatePriorToCurrentPoint);
+	
+	FILTERED_LOG(comp, status, LOG_FMI_CALL, "fmi2DoStep: "
+        "currentCommunicationPoint = %g, "
+        "communicationStepSize = %g, "
+        "noSetFMUStatePriorToCurrentPoint = fmi2%s",
+        currentCommunicationPoint, communicationStepSize, noSetFMUStatePriorToCurrentPoint ? "True" : "False")
+	
+    return fmi2OK;
+}
+
+/* Inquire slave status */
+static fmi2Status getStatus(char* fname, fmi2Component c, const fmi2StatusKind s) {
+    const char *statusKind[3] = {"fmi2DoStepStatus","fmi2PendingStatus","fmi2LastSuccessfulTime"};
+    ModelInstance *comp = (ModelInstance *)c;
+    if (invalidState(comp, fname, MASK_fmi2GetStatus)) // all get status have the same MASK_fmi2GetStatus
+            return fmi2Error;
+    FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "$s: fmi2StatusKind = %s", fname, statusKind[s])
+
+    switch(s) {
+        case fmi2DoStepStatus: FILTERED_LOG(comp, fmi2Error, LOG_ERROR,
+            "%s: Can be called with fmi2DoStepStatus when fmi2DoStep returned fmi2Pending."
+            " This is not the case.", fname)
+            break;
+        case fmi2PendingStatus: FILTERED_LOG(comp, fmi2Error, LOG_ERROR,
+            "%s: Can be called with fmi2PendingStatus when fmi2DoStep returned fmi2Pending."
+            " This is not the case.", fname)
+            break;
+        case fmi2LastSuccessfulTime: FILTERED_LOG(comp, fmi2Error, LOG_ERROR,
+            "%s: Can be called with fmi2LastSuccessfulTime when fmi2DoStep returned fmi2Discard."
+            " This is not the case.", fname)
+            break;
+        case fmi2Terminated: FILTERED_LOG(comp, fmi2Error, LOG_ERROR,
+            "%s: Can be called with fmi2Terminated when fmi2DoStep returned fmi2Discard."
+            " This is not the case.", fname)
+            break;
+    }
+    return fmi2Discard;
+}
+
+fmi2Status fmi2GetStatus(fmi2Component c, const fmi2StatusKind s, fmi2Status *value) {
+    return getStatus("fmi2GetStatus", c, s);
+}
+
+fmi2Status fmi2GetRealStatus(fmi2Component c, const fmi2StatusKind s, fmi2Real *value) {
+    if (s == fmi2LastSuccessfulTime) {
+        ModelInstance *comp = (ModelInstance *)c;
+        if (invalidState(comp, "fmi2GetRealStatus", MASK_fmi2GetRealStatus))
+            return fmi2Error;
+        *value = comp->time;
+        return fmi2OK;
+    }
+    return getStatus("fmi2GetRealStatus", c, s);
+}
+
+fmi2Status fmi2GetIntegerStatus(fmi2Component c, const fmi2StatusKind s, fmi2Integer *value) {
+    return getStatus("fmi2GetIntegerStatus", c, s);
+}
+
+fmi2Status fmi2GetBooleanStatus(fmi2Component c, const fmi2StatusKind s, fmi2Boolean *value) {
+    if (s == fmi2Terminated) {
+        ModelInstance *comp = (ModelInstance *)c;
+        if (invalidState(comp, "fmi2GetBooleanStatus", MASK_fmi2GetBooleanStatus))
+            return fmi2Error;
+        *value = comp->eventInfo.terminateSimulation;
+        return fmi2OK;
+    }
+    return getStatus("fmi2GetBooleanStatus", c, s);
+}
+
+fmi2Status fmi2GetStringStatus(fmi2Component c, const fmi2StatusKind s, fmi2String *value) {
+    return getStatus("fmi2GetStringStatus", c, s);
+}
+#endif // Functions for Co-Simulation
+
+#ifdef __cplusplus
+} // closing brace for extern "C"
+#endif

+ 182 - 0
SemanticAdaptationForFMI/Experiments/hierarchical_fmu/fmu20/fmu/cs/mass_spring_damper_hierarchical/sources/fmuTemplate.h

@@ -0,0 +1,182 @@
+/* ---------------------------------------------------------------------------*
+ * fmuTemplate.h
+ * Definitions by the includer of this file
+ * Copyright QTronic GmbH. All rights reserved.
+ * ---------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <minmax.h>
+
+#include "fmi2Functions.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// macros used to define variables
+#define  r(vr) comp->r[vr]
+#define  i(vr) comp->i[vr]
+#define  b(vr) comp->b[vr]
+#define  s(vr) comp->s[vr]
+#define pos(z) comp->isPositive[z]
+#define copy(vr, value) setString(comp, vr, value)
+
+fmi2Status setString(fmi2Component comp, fmi2ValueReference vr, fmi2String value);
+
+// categories of logging supported by model.
+// Value is the index in logCategories of a ModelInstance.
+#define LOG_ALL       0
+#define LOG_ERROR     1
+#define LOG_FMI_CALL  2
+#define LOG_EVENT     3
+
+#define NUMBER_OF_CATEGORIES 4
+
+typedef enum {
+    modelStartAndEnd        = 1<<0,
+    modelInstantiated       = 1<<1,
+    modelInitializationMode = 1<<2,
+
+    // ME states
+    modelEventMode          = 1<<3,
+    modelContinuousTimeMode = 1<<4,
+    // CS states
+    modelStepComplete       = 1<<5,
+    modelStepInProgress     = 1<<6,
+    modelStepFailed         = 1<<7,
+    modelStepCanceled       = 1<<8,
+
+    modelTerminated         = 1<<9,
+    modelError              = 1<<10,
+    modelFatal              = 1<<11,
+} ModelState;
+
+// ---------------------------------------------------------------------------
+// Function calls allowed state masks for both Model-exchange and Co-simulation
+// ---------------------------------------------------------------------------
+#define MASK_fmi2GetTypesPlatform        (modelStartAndEnd | modelInstantiated | modelInitializationMode \
+                                        | modelEventMode | modelContinuousTimeMode \
+                                        | modelStepComplete | modelStepInProgress | modelStepFailed | modelStepCanceled \
+                                        | modelTerminated | modelError)
+#define MASK_fmi2GetVersion              MASK_fmi2GetTypesPlatform
+#define MASK_fmi2SetDebugLogging         (modelInstantiated | modelInitializationMode \
+                                        | modelEventMode | modelContinuousTimeMode \
+                                        | modelStepComplete | modelStepInProgress | modelStepFailed | modelStepCanceled \
+                                        | modelTerminated | modelError)
+#define MASK_fmi2Instantiate             (modelStartAndEnd)
+#define MASK_fmi2FreeInstance            (modelInstantiated | modelInitializationMode \
+                                        | modelEventMode | modelContinuousTimeMode \
+                                        | modelStepComplete | modelStepFailed | modelStepCanceled \
+                                        | modelTerminated | modelError)
+#define MASK_fmi2SetupExperiment         modelInstantiated
+#define MASK_fmi2EnterInitializationMode modelInstantiated
+#define MASK_fmi2ExitInitializationMode  modelInitializationMode
+#define MASK_fmi2Terminate               (modelEventMode | modelContinuousTimeMode \
+                                        | modelStepComplete | modelStepFailed)
+#define MASK_fmi2Reset                   MASK_fmi2FreeInstance
+#define MASK_fmi2GetReal                 (modelInitializationMode \
+                                        | modelEventMode | modelContinuousTimeMode \
+                                        | modelStepComplete | modelStepFailed | modelStepCanceled \
+                                        | modelTerminated | modelError)
+#define MASK_fmi2GetInteger              MASK_fmi2GetReal
+#define MASK_fmi2GetBoolean              MASK_fmi2GetReal
+#define MASK_fmi2GetString               MASK_fmi2GetReal
+#define MASK_fmi2SetReal                 (modelInstantiated | modelInitializationMode \
+                                        | modelEventMode | modelContinuousTimeMode \
+                                        | modelStepComplete)
+#define MASK_fmi2SetInteger              (modelInstantiated | modelInitializationMode \
+                                        | modelEventMode \
+                                        | modelStepComplete)
+#define MASK_fmi2SetBoolean              MASK_fmi2SetInteger
+#define MASK_fmi2SetString               MASK_fmi2SetInteger
+#define MASK_fmi2GetFMUstate             MASK_fmi2FreeInstance
+#define MASK_fmi2SetFMUstate             MASK_fmi2FreeInstance
+#define MASK_fmi2FreeFMUstate            MASK_fmi2FreeInstance
+#define MASK_fmi2SerializedFMUstateSize  MASK_fmi2FreeInstance
+#define MASK_fmi2SerializeFMUstate       MASK_fmi2FreeInstance
+#define MASK_fmi2DeSerializeFMUstate     MASK_fmi2FreeInstance
+#define MASK_fmi2GetDirectionalDerivative (modelInitializationMode \
+                                        | modelEventMode | modelContinuousTimeMode \
+                                        | modelStepComplete | modelStepFailed | modelStepCanceled \
+                                        | modelTerminated | modelError)
+
+// ---------------------------------------------------------------------------
+// Function calls allowed state masks for Model-exchange
+// ---------------------------------------------------------------------------
+#define MASK_fmi2EnterEventMode          (modelEventMode | modelContinuousTimeMode)
+#define MASK_fmi2NewDiscreteStates       modelEventMode
+#define MASK_fmi2EnterContinuousTimeMode modelEventMode
+#define MASK_fmi2CompletedIntegratorStep modelContinuousTimeMode
+#define MASK_fmi2SetTime                 (modelEventMode | modelContinuousTimeMode)
+#define MASK_fmi2SetContinuousStates     modelContinuousTimeMode
+#define MASK_fmi2GetEventIndicators      (modelInitializationMode \
+                                        | modelEventMode | modelContinuousTimeMode \
+                                        | modelTerminated | modelError)
+#define MASK_fmi2GetContinuousStates     MASK_fmi2GetEventIndicators
+#define MASK_fmi2GetDerivatives          (modelEventMode | modelContinuousTimeMode \
+                                        | modelTerminated | modelError)
+#define MASK_fmi2GetNominalsOfContinuousStates ( modelInstantiated \
+                                        | modelEventMode | modelContinuousTimeMode \
+                                        | modelTerminated | modelError)
+
+// ---------------------------------------------------------------------------
+// Function calls allowed state masks for Co-simulation
+// ---------------------------------------------------------------------------
+#define MASK_fmi2SetRealInputDerivatives (modelInstantiated | modelInitializationMode \
+                                        | modelStepComplete)
+#define MASK_fmi2GetRealOutputDerivatives (modelStepComplete | modelStepFailed | modelStepCanceled \
+                                        | modelTerminated | modelError)
+#define MASK_fmi2DoStep                  modelStepComplete
+#define MASK_fmi2CancelStep              modelStepInProgress
+#define MASK_fmi2GetStatus               (modelStepComplete | modelStepInProgress | modelStepFailed \
+                                        | modelTerminated)
+#define MASK_fmi2GetRealStatus           MASK_fmi2GetStatus
+#define MASK_fmi2GetIntegerStatus        MASK_fmi2GetStatus
+#define MASK_fmi2GetBooleanStatus        MASK_fmi2GetStatus
+#define MASK_fmi2GetStringStatus         MASK_fmi2GetStatus
+
+typedef struct {
+    fmi2Real    *r;
+    fmi2Integer *i;
+    fmi2Boolean *b;
+    fmi2String  *s;
+    fmi2Boolean *isPositive;
+
+    fmi2Real time;
+    fmi2String instanceName;
+    fmi2Type type;
+    fmi2String GUID;
+    const fmi2CallbackFunctions *functions;
+    fmi2Boolean loggingOn;
+    fmi2Boolean logCategories[NUMBER_OF_CATEGORIES];
+
+    fmi2ComponentEnvironment componentEnvironment;
+    ModelState state;
+    fmi2EventInfo eventInfo;
+    fmi2Boolean isDirtyValues;
+    fmi2Boolean isNewEventIteration;
+	
+	// Stores generic state to be used by includers
+	void * genericState;
+} ModelInstance;
+
+// ---------------------------------------------------------------------------
+// Logger utilities
+// ---------------------------------------------------------------------------
+
+static fmi2String logCategoriesNames[] = {"logAll", "logError", "logFmiCall", "logEvent"};
+
+fmi2Boolean isCategoryLogged(ModelInstance *comp, int categoryIndex);
+
+// macro to be used to log messages. The macro check if current 
+// log category is valid and, if true, call the logger provided by simulator.
+#define FILTERED_LOG(instance, status, categoryIndex, message, ...) if (isCategoryLogged(instance, categoryIndex)) \
+        instance->functions->logger(instance->functions->componentEnvironment, instance->instanceName, status, \
+        logCategoriesNames[categoryIndex], message, ##__VA_ARGS__);
+
+
+#ifdef __cplusplus
+} // closing brace for extern "C"
+#endif

+ 211 - 0
SemanticAdaptationForFMI/Experiments/hierarchical_fmu/fmu20/fmu/cs/mass_spring_damper_hierarchical/sources/mass_spring_damper_hierarchical.c

@@ -0,0 +1,211 @@
+/* ---------------------------------------------------------------------------*
+ * Mass spring damper test FMU.
+ * ---------------------------------------------------------------------------*/
+
+// define class name and unique id
+#define MODEL_IDENTIFIER mass_spring_damper_hierarchical
+#define MODEL_GUID "{ae8ba062-ad27-4bfb-8ce5-54c82e9d7e35}"
+
+// define model size
+// This FMU, since it is a wrapper, does not have any real state even though its model description says so.
+#define NUMBER_OF_REALS 7
+#define NUMBER_OF_INTEGERS 0
+#define NUMBER_OF_BOOLEANS 0
+#define NUMBER_OF_STRINGS 0
+#define NUMBER_OF_STATES 0
+#define NUMBER_OF_EVENT_INDICATORS 0
+
+// These libraries are needed to load FMUs
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "fmi2.h"
+#include "sim_support.h"
+
+// include fmu header files, typedefs and macros
+#include "fmuTemplate.h"
+
+// define all model variables and their value references
+// conventions used here:
+// - if x is a variable, then macro x_ is its variable reference
+// - the vr of a variable is its index in array  r, i, b or s
+// - if k is the vr of a real state, then k+1 is the vr of its derivative
+#define x_     		0
+#define der_x_ 		1
+#define der_der_x_ 	2
+#define F_in_ 		3
+#define k_     		4
+#define c_     		5
+#define m_     		6
+
+// define state vector as vector of value references
+#define STATES { }
+
+// This is used by the loadFMU function, in the sim_support library, to load the FMU dll.
+FMU fmu; // the fmu to simulate
+FMU* childFMU; // pointer to the above FMU
+fmi2Component childFMUInstance;                        // instance of the above fmu
+
+// called by fmi2Instantiate
+// Set values for all variables that define a start value
+void setStartValues(ModelInstance *comp) {
+    // does nothing for now.
+}
+
+// called by fmi2Instantiate
+// In the case of hierarchical co-simulation, this will instantiate the (compiled) mass-spring-damper FMU.
+void instantiate(ModelInstance *comp) {
+	FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, ">instantiate")
+	
+	const char* fmuFileName = "fmu20\\fmu\\cs\\mass_spring_damper.fmu";
+	ModelDescription* md; 					// handle to the parsed XML file
+	const char *guid;                       // global unique id of the fmu
+	const char *instanceName;               // instance name
+    childFMU = &fmu;
+	fmi2Status fmi2Flag;                    // return code of the fmu functions
+    char *fmuResourceLocation = getTempResourcesLocation(); // path to the fmu resources as URL, "file://C:\QTronic\sales"
+    fmi2Boolean visible = fmi2False;        // no simulator user interface
+	fmi2Boolean loggingOn = fmi2True;  // TODO : this should be a parameter
+	
+	// TODO: Reuse categories given by instantiation
+	char **categories = NULL;
+	int nCategories = 0;
+	
+	loadFMU(fmuFileName);
+	FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "Mass Spring Damper FMU Loaded")
+	
+	md = childFMU->modelDescription;
+    guid = getAttributeValue((Element *)md, att_guid);
+    instanceName = getAttributeValue((Element *)getCoSimulation(md), att_modelIdentifier);
+    childFMUInstance = childFMU->instantiate(instanceName, fmi2CoSimulation, guid, fmuResourceLocation,
+                    comp->functions, visible, comp->loggingOn);
+    free(fmuResourceLocation);
+	
+    if (!childFMUInstance){
+		FILTERED_LOG(comp, fmi2Error, LOG_ERROR, "Could not instantiate mass spring damper model")
+		return;
+	}
+	
+	FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "Mass Spring Damper FMU Instantiated: fmu %u ; instance %u", childFMU, childFMUInstance)
+	
+    if (nCategories > 0) {
+        fmi2Flag = childFMU->setDebugLogging(childFMUInstance, fmi2True, nCategories, categories);
+        if (fmi2Flag > fmi2Warning) {
+			FILTERED_LOG(comp, fmi2Error, LOG_ERROR, "Could not initialize mass spring damper model - failed FMI set debug logging")
+			return;
+        }
+    }
+	
+	FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "<instantiate")
+}
+
+fmi2Status setupExperiment(ModelInstance *comp, fmi2Boolean toleranceDefined, fmi2Real tolerance,
+                            fmi2Real startTime, fmi2Boolean stopTimeDefined, fmi2Real stopTime){
+	FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, ">setupExperiment: toleranceDefined=%d tolerance=%g",
+        toleranceDefined, tolerance)
+	
+	FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "Setting up experiment in child: fmu %u ; instance %u", childFMU, childFMUInstance)
+	
+	fmi2Status fmi2Flag = childFMU->setupExperiment(childFMUInstance, toleranceDefined, tolerance, startTime, stopTimeDefined, stopTime);
+    
+	FILTERED_LOG(comp, fmi2Flag, LOG_FMI_CALL, "<setupExperiment")
+	
+	return fmi2Flag;
+}
+
+fmi2Status enterInitializationMode(ModelInstance *comp){
+	FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, ">enterInitializationMode")
+	
+	fmi2Status fmi2Flag = childFMU->enterInitializationMode(childFMUInstance);
+    
+	FILTERED_LOG(comp, fmi2Flag, LOG_FMI_CALL, "<enterInitializationMode")
+	return fmi2Flag;
+}
+
+fmi2Status exitInitializationMode(ModelInstance *comp){
+	FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, ">exitInitializationMode")
+	
+	fmi2Status fmi2Flag = childFMU->exitInitializationMode(childFMUInstance);
+    
+	FILTERED_LOG(comp, fmi2Flag, LOG_FMI_CALL, "<exitInitializationMode")
+	return fmi2Flag;
+}
+
+fmi2Status terminate(ModelInstance *comp){
+	FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, ">terminate")
+	
+	fmi2Status fmi2Flag = childFMU->terminate(childFMUInstance);
+    
+	FILTERED_LOG(comp, fmi2Flag, LOG_FMI_CALL, "<terminate")
+	
+	return fmi2Flag;
+}
+
+fmi2Status reset(ModelInstance *comp){
+	FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "reset")
+	return fmi2OK;
+}
+
+fmi2Status freeInstance(ModelInstance *comp){
+	FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, ">freeInstance")
+	
+	childFMU->freeInstance(childFMUInstance);
+    
+	FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "<freeInstance")
+	
+	return fmi2OK;
+}
+
+fmi2Status doStep(ModelInstance *comp, fmi2Real currentCommunicationPoint,
+                    fmi2Real communicationStepSize, fmi2Boolean noSetFMUStatePriorToCurrentPoint){
+	
+	FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "doStep: "
+        "currentCommunicationPoint = %g, "
+        "communicationStepSize = %g, "
+        "noSetFMUStatePriorToCurrentPoint = fmi2%s",
+        currentCommunicationPoint, communicationStepSize, noSetFMUStatePriorToCurrentPoint ? "True" : "False")
+	
+	int n_steps = 10;
+	double h = communicationStepSize / n_steps;
+    int k;
+	fmi2Status fmi2Flag;
+    
+    comp->time = currentCommunicationPoint;
+	
+	for (k = 0; k < n_steps; k++){
+		fmi2Flag = childFMU->doStep(childFMUInstance, comp->time, h, fmi2True);
+		FILTERED_LOG(comp, fmi2Flag, LOG_FMI_CALL, "doStep of child completed to time %g", comp->time)
+		comp->time += h;
+	}
+	
+	return fmi2OK;
+}
+
+// called by fmi2GetReal, fmi2GetInteger, fmi2GetBoolean, fmi2GetString, fmi2ExitInitialization
+// if setStartValues or environment set new values through fmi2SetXXX.
+// Lazy set values for all variable that are computed from other variables.
+void calculateValues(ModelInstance *comp) {
+	// do nothing
+}
+
+// called by fmi2GetReal, fmi2GetContinuousStates and fmi2GetDerivatives
+fmi2Real getReal(ModelInstance* comp, fmi2ValueReference vr){
+	FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, ">getReal")
+	
+	// passing the address is a cheap way of conforming to the vector.
+	fmi2Real val;
+	fmi2Status fmi2flag = childFMU->getReal(childFMUInstance, &vr, 1, &val);
+    
+	FILTERED_LOG(comp, fmi2flag, LOG_FMI_CALL, "<getReal = %g", val)
+	return val;
+}
+
+// used to set the next time event, if any.
+void eventUpdate(ModelInstance *comp, fmi2EventInfo *eventInfo, int isTimeEvent, int isNewEventIteration) {
+	// do nothing
+}
+
+// include code that implements the FMI based on the above definitions
+#include "fmuTemplate.c"
+
+