void exec() { fmi2Flag = fmu.doStep(c, time.to_seconds(), h.to_seconds(), fmi2True); if (fmi2Flag == fmi2Discard) { fmi2Boolean b; // check if model requests to end simulation if (fmi2OK != fmu.getBooleanStatus(c, fmi2Terminated, &b)) { return SC_REPORT_ERROR(name(),"could not complete simulation of the model. getBooleanStatus return other than fmi2OK"); } if (b == fmi2True) { return SC_REPORT_ERROR(name(),"the model requested to end the simulation"); } return SC_REPORT_ERROR(name(),"could not complete simulation of the model"); } if (fmi2Flag != fmi2OK) return SC_REPORT_ERROR(name(),"could not complete simulation of the model"); // FIXME: res = outputRow(fmu, c, time, file, separator, fmi2False); // output values for this step auto res = getRealOutput(&fmu, c, output_index); oval = sub_signal(time, time+h, [this,res](const sc_time& t) { return res; } ); }
/////////////////////////////////////////////////////////////////////////////// /// Simulate the given FMU using the forward euler method. /// Time events are processed by reducing step size to exactly hit tNext. /// State events are checked and fired only at the end of an Euler step. /// The simulator may therefore miss state events and fires state events typically too late. /// ///\param fmu FMU. ///\param tEnd Ending time of simulation. ///\param h Tiem step size. ///\param loggingOn Controller for logging. ///\param separator Separator character. ///\return 0 if there is no error occurred. /////////////////////////////////////////////////////////////////////////////// static int simulate(FMU* fmu, double tEnd, double h, fmiBoolean loggingOn, char separator) { int i, n; fmiBoolean timeEvent, stateEvent, stepEvent; double time; ModelDescription* md; // handle to the parsed XML file const char* guid; // global unique id of the fmu fmiCallbackFunctions callbacks; // called by the model during simulation fmiComponent c; // instance of the fmu fmiStatus fmiFlag; // return code of the fmu functions fmiReal t0 = 0; // start time fmiBoolean toleranceControlled = fmiFalse; int nSteps = 0; FILE* file; fmiValueReference vr; // add it to get value reference for variables //Note: User defined references //Begin------------------------------------------------------------------ fmiValueReference vru[1], vry[1]; // value references for two input and two output variables //End-------------------------------------------------------------------- ScalarVariable** vars = fmu->modelDescription->modelVariables; // add it to get variables int k; // add a counter for variables fmiReal ru1, ru2, ry, ry1, ry2; // add real variables for input and output fmiInteger ix, iy; // add integer variables for input and output fmiBoolean bx, by; // add boolean variables for input and output fmiString sx, sy; // Zuo: add string variables for input and output fmiStatus status; // Zuo: add stauus for fmi printDebug("Instantiate the fmu.\n"); // instantiate the fmu md = fmu->modelDescription; guid = getString(md, att_guid); printfDebug("Got GUID = %s!\n", guid); callbacks.logger = fmuLogger; callbacks.allocateMemory = calloc; callbacks.freeMemory = free; printDebug("Got callbacks!\n"); printfDebug("Model Identifer is %s\n", getModelIdentifier(md)); c = fmu->instantiateSlave(getModelIdentifier(md), guid, "Model1", "", 10, fmiFalse, fmiFalse, callbacks, loggingOn); if (!c) { printError("could not instantiate slaves.\n"); return 1; } printDebug("Instantiated slaves!\n"); // Open result file if (!(file=fopen(RESULT_FILE, "w"))) { printfError("could not write %s because:\n", RESULT_FILE); printfError(" %s\n", strerror(errno)); return 1; } printDebug("Open results file!\n"); // Set the start time and initialize time = t0; printDebug("start to initialize fmu!\n"); fmiFlag = fmu->initializeSlave(c, t0, fmiTrue, tEnd); printDebug("Initialized fmu!\n"); if (fmiFlag > fmiWarning) { printError("could not initialize model"); return 1; } // Output solution for time t0 printDebug("start to outputRow"); //outputRow(fmu, c, t0, file, separator, TRUE); // output column names //outputRow(fmu, c, t0, file, separator, FALSE); // output initla value of fmu outputdata(t0, file, separator, 0, 0, TRUE); printDebug("start to getValueReference"); ///////////////////////////////////////////////////////////////////////////// // Get value references for input and output varibles // Note: User needs to specify the name of variables for their own fmus //Begin------------------------------------------------------------------ vru[0] = getValueReference(getVariableByName(md, "Toa")); //vru[1] = getValueReference(getVariableByName(md, "u2")); vry[0] = getValueReference(getVariableByName(md, "TrmSou")); //vry[1] = getValueReference(getVariableByName(md, "y2")); //End-------------------------------------------------------------------- printDebug("Enter in simulation loop.\n"); // enter the simulation loop while (time < tEnd) { if (loggingOn) printf("Step %d to t=%.4f\n", nSteps, time); /////////////////////////////////////////////////////////////////////////// // Step 1: get values of output variables from slaves for (k=0; vars[k]; k++) { ScalarVariable* sv = vars[k]; if (getAlias(sv)!=enu_noAlias) continue; if (getCausality(sv) != enu_output) continue; // only get output variable vr = getValueReference(sv); switch (sv->typeSpec->type){ case elm_Real: fmu->getReal(c, &vr, 1, &ry); break; case elm_Integer: fmu->getInteger(c, &vr, 1, &iy); break; case elm_Boolean: fmu->getBoolean(c, &vr, 1, &by); break; case elm_String: fmu->getString(c, &vr, 1, &sy); break; } // Allocate values to cooresponding varibles on master program // Note: User needs to specify the output variables for their own fmu //Begin------------------------------------------------------------------ if (vr == vry[0]) ry1 = ry; //else if(vr == vry[1]) ry2 = ry; //End-------------------------------------------------------------------- } /////////////////////////////////////////////////////////////////////////// // Step 2: compute on master side // Note: User can adjust the computing schemes of mater program //Begin------------------------------------------------------------------ printf("Dymola output = %f\n", ry1); //= ry2 + 3.0; ru1 = 293; //End-------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // Step 3: set input variables back to slaves for (k=0; vars[k]; k++) { ScalarVariable* sv = vars[k]; if (getAlias(sv)!=enu_noAlias) continue; if (getCausality(sv) != enu_input) continue; // only set input variable vr = getValueReference(sv); // Note: User can adjust the settings for input variables //Begin------------------------------------------------------------------ switch (sv->typeSpec->type){ case elm_Real: if(vr == vru[0]) { fmu->setReal(c, &vr, 1, &ru1); printDebug("Set u1.\n"); } //else if (vr == vru[1]) { // fmu->setReal(c, &vr, 1, &ru2); // printDebug("Set u2.\n"); //} else printf("Warning: no data given for input variable.\n"); break; case elm_Integer: fmu->setInteger(c, &vr, 1, &ix); break; case elm_Boolean: fmu->setBoolean(c, &vr, 1, &bx); break; case elm_String: printDebug("Get string in simulatio()"); fmu->setString(c, &vr, 1, &sx); break; } //End-------------------------------------------------------------------- } // Advance to next time step status = fmu->doStep(c, time, h, fmiTrue); // Terminate this row // fprintf(file, "\n"); (comment out this line to get rid of the blank line between the results in the csv file.) time = min(time+h, tEnd); //outputRow(fmu, c, time, file, separator, FALSE); // output values for this step outputdata(time, file, separator, ru1, ry1, FALSE); nSteps++; } // end of while // Cleanup fclose(file); // Print simulation summary if (loggingOn) printf("Step %d to t=%.4f\n", nSteps, time); printf("Simulation from %g to %g terminated successful\n", t0, tEnd); printf(" steps ............ %d\n", nSteps); printf(" fixed step size .. %g\n", h); return 0; // success }
// simulate the given FMU from tStart = 0 to tEnd. static int simulate(FMU* fmu, double tEnd, double h, fmi2Boolean loggingOn, char separator, int nCategories, const fmi2String categories[]) { double time; double tStart = 0; // start time const char *guid; // global unique id of the fmu const char *instanceName; // instance name fmi2Component c; // instance of the 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 fmi2CallbackFunctions callbacks = {fmuLogger, calloc, free, NULL, fmu}; // called by the model during simulation ModelDescription* md; // handle to the parsed XML file fmi2Boolean toleranceDefined = fmi2False; // true if model description define tolerance fmi2Real tolerance = 0; // used in setting up the experiment ValueStatus vs = 0; int nSteps = 0; Element *defaultExp; FILE* file; // instantiate the fmu md = fmu->modelDescription; guid = getAttributeValue((Element *)md, att_guid); instanceName = getAttributeValue((Element *)getCoSimulation(md), att_modelIdentifier); c = fmu->instantiate(instanceName, fmi2CoSimulation, guid, fmuResourceLocation, &callbacks, visible, loggingOn); free(fmuResourceLocation); if (!c) return error("could not instantiate model"); if (nCategories > 0) { fmi2Flag = fmu->setDebugLogging(c, fmi2True, nCategories, categories); if (fmi2Flag > fmi2Warning) { return error("could not initialize model; failed FMI set debug logging"); } } defaultExp = getDefaultExperiment(md); if (defaultExp) tolerance = getAttributeDouble(defaultExp, att_tolerance, &vs); if (vs == valueDefined) { toleranceDefined = fmi2True; } fmi2Flag = fmu->setupExperiment(c, toleranceDefined, tolerance, tStart, fmi2True, tEnd); if (fmi2Flag > fmi2Warning) { return error("could not initialize model; failed FMI setup experiment"); } fmi2Flag = fmu->enterInitializationMode(c); if (fmi2Flag > fmi2Warning) { return error("could not initialize model; failed FMI enter initialization mode"); } fmi2Flag = fmu->exitInitializationMode(c); if (fmi2Flag > fmi2Warning) { return error("could not initialize model; failed FMI exit initialization mode"); } // open result file if (!(file = fopen(RESULT_FILE, "w"))) { printf("could not write %s because:\n", RESULT_FILE); printf(" %s\n", strerror(errno)); return 0; // failure } // output solution for time t0 outputRow(fmu, c, tStart, file, separator, fmi2True); // output column names outputRow(fmu, c, tStart, file, separator, fmi2False); // output values // enter the simulation loop time = tStart; while (time < tEnd) { fmi2Flag = fmu->doStep(c, time, h, fmi2True); if (fmi2Flag == fmi2Discard) { fmi2Boolean b; // check if model requests to end simulation if (fmi2OK != fmu->getBooleanStatus(c, fmi2Terminated, &b)) { return error("could not complete simulation of the model. getBooleanStatus return other than fmi2OK"); } if (b == fmi2True) { return error("the model requested to end the simulation"); } return error("could not complete simulation of the model"); } if (fmi2Flag != fmi2OK) return error("could not complete simulation of the model"); time += h; outputRow(fmu, c, time, file, separator, fmi2False); // output values for this step nSteps++; } // end simulation fmu->terminate(c); fmu->freeInstance(c); fclose(file); // print simulation summary printf("Simulation from %g to %g terminated successful\n", tStart, tEnd); printf(" steps ............ %d\n", nSteps); printf(" fixed step size .. %g\n", h); return 1; // success }
// simulate the given FMU from tStart = 0 to tEnd. static int simulate(FMU* fmu, double tEnd, double h, fmiBoolean loggingOn, char separator) { double time; double tStart = 0; // start time const char* guid; // global unique id of the fmu fmiComponent c; // instance of the fmu fmiStatus fmiFlag; // return code of the fmu functions char* fmuLocation = getTempFmuLocation(); // path to the fmu as URL, "file://C:\QTronic\sales" const char* mimeType = "application/x-fmu-sharedlibrary"; // denotes tool in case of tool coupling fmiReal timeout = 1000; // wait period in milli seconds, 0 for unlimited wait period" fmiBoolean visible = fmiFalse; // no simulator user interface fmiBoolean interactive = fmiFalse; // simulation run without user interaction fmiCallbackFunctions callbacks; // called by the model during simulation ModelDescription* md; // handle to the parsed XML file int nSteps = 0; FILE* file; // instantiate the fmu md = fmu->modelDescription; guid = getString(md, att_guid); callbacks.logger = fmuLogger; callbacks.allocateMemory = calloc; callbacks.freeMemory = free; callbacks.stepFinished = NULL; // fmiDoStep has to be carried out synchronously c = fmu->instantiateSlave(getModelIdentifier(md), guid, fmuLocation, mimeType, timeout, visible, interactive, callbacks, loggingOn); free(fmuLocation); if (!c) return error("could not instantiate model"); // open result file if (!(file=fopen(RESULT_FILE, "w"))) { printf("could not write %s because:\n", RESULT_FILE); printf(" %s\n", strerror(errno)); return 0; // failure } // StopTimeDefined=fmiFalse means: ignore value of tEnd fmiFlag = fmu->initializeSlave(c, tStart, fmiTrue, tEnd); if (fmiFlag > fmiWarning) return error("could not initialize model"); // output solution for time t0 outputRow(fmu, c, tStart, file, separator, fmiTrue); // output column names outputRow(fmu, c, tStart, file, separator, fmiFalse); // output values // enter the simulation loop time = tStart; while (time < tEnd) { fmiFlag = fmu->doStep(c, time, h, fmiTrue); if (fmiFlag != fmiOK) return error("could not complete simulation of the model"); time += h; outputRow(fmu, c, time, file, separator, fmiFalse); // output values for this step nSteps++; } // end simulation fmiFlag = fmu->terminateSlave(c); fmu->freeSlaveInstance(c); fclose(file); // print simulation summary printf("Simulation from %g to %g terminated successful\n", tStart, tEnd); printf(" steps ............ %d\n", nSteps); printf(" fixed step size .. %g\n", h); return 1; // success }