/*! \fn updateDiscreteSystem * * Function to update the whole system with event iteration. * Evaluates functionDAE() * * \param [ref] [data] */ void updateDiscreteSystem(DATA *data, threadData_t *threadData) { TRACE_PUSH int IterationNum = 0; int discreteChanged = 0; modelica_boolean relationChanged = 0; data->simulationInfo.needToIterate = 0; data->simulationInfo.callStatistics.updateDiscreteSystem++; data->callback->function_updateRelations(data, threadData, 1); updateRelationsPre(data); storeRelations(data); data->callback->functionDAE(data, threadData); debugStreamPrint(LOG_EVENTS_V, 0, "updated discrete System"); relationChanged = checkRelations(data); discreteChanged = data->callback->checkForDiscreteChanges(data, threadData); while(discreteChanged || data->simulationInfo.needToIterate || relationChanged) { if(data->simulationInfo.needToIterate) { debugStreamPrint(LOG_EVENTS_V, 0, "reinit() call. Iteration needed!"); } if(relationChanged) { debugStreamPrint(LOG_EVENTS_V, 0, "relations changed. Iteration needed."); } if(discreteChanged) { debugStreamPrint(LOG_EVENTS_V, 0, "discrete Variable changed. Iteration needed."); } storePreValues(data); updateRelationsPre(data); printRelations(data, LOG_EVENTS_V); printZeroCrossings(data, LOG_EVENTS_V); data->callback->functionDAE(data, threadData); IterationNum++; if(IterationNum > IterationMax) { throwStreamPrint(threadData, "ERROR: Too many event iterations. System is inconsistent. Simulation terminate."); } relationChanged = checkRelations(data); discreteChanged = data->callback->checkForDiscreteChanges(data, threadData); } storeRelations(data); TRACE_POP }
/*! \fn solve mixed system with extended search * * \param [in] [data] * [sysNumber] index of the corresponing mixed system * * \author wbraun */ int solveMixedSearch(DATA *data, int sysNumber) { MIXED_SYSTEM_DATA* systemData = &(data->simulationInfo->mixedSystemData[sysNumber]); DATA_SEARCHMIXED_SOLVER* solverData = (DATA_SEARCHMIXED_SOLVER*)systemData->solverData; int eqSystemNumber = systemData->equationIndex; int found_solution = 0; /* * We are given the number of the non-linear system. * We want to look it up among all equations. */ int i, ix; int stepCount = 0; int mixedIterations = 0; int success = 0; debugStreamPrint(LOG_NLS, 1, "\n#### Start solver mixed equation system at time %f.", data->localData[0]->timeValue); memset(solverData->stateofSearch, 0, systemData->size); /* update pre iteration vars */ /* update iteration vars */ for(i=0;i<systemData->size;++i) solverData->iterationVarsPre[i] = *(systemData->iterationVarsPtr[i]); do { /* update pre iteration vars */ for(i=0;i<systemData->size;++i) solverData->iterationVars[i] = *(systemData->iterationVarsPtr[i]); /* solve continuous equation part * and update iteration variables in model */ systemData->solveContinuousPart(data); systemData->updateIterationExps(data); /* set new values of boolean variable */ for(i=0;i<systemData->size;++i) solverData->iterationVars2[i] = *(systemData->iterationVarsPtr[i]); found_solution = systemData->continuous_solution; debugStreamPrint(LOG_NLS, 0, "#### continuous system solution status = %d", found_solution); /* restart if any relation has changed */ if(checkRelations(data)) { updateRelationsPre(data); systemData->updateIterationExps(data); debugStreamPrint(LOG_NLS, 0, "#### System relation changed restart iteration"); if(mixedIterations++ > 200) found_solution = -4; /* mixedIterations++ > 200 */ } if(found_solution == -1) { /* system of equations failed */ found_solution = -2; debugStreamPrint(LOG_NLS, 0, "#### NO SOLUTION "); } else { found_solution = 1; for(i = 0; i < systemData->size; i++) { debugStreamPrint(LOG_NLS, 0, " check iterationVar[%d] = %d <-> %d", i, solverData->iterationVars[i], solverData->iterationVars2[i]); if(solverData->iterationVars[i] != solverData->iterationVars2[i]) { found_solution = 0; break; } } debugStreamPrint(LOG_NLS, 0, "#### SOLUTION = %c", found_solution ? 'T' : 'F'); } if(!found_solution ) { /* try next set of values*/ if(nextVar(solverData->stateofSearch, systemData->size)) { debugStreamPrint(LOG_NLS, 0, "#### set next STATE "); for(i = 0; i < systemData->size; i++) *(systemData->iterationVarsPtr[i]) = *(systemData->iterationPreVarsPtr[i]) != solverData->stateofSearch[i]; /* debug output */ if(ACTIVE_STREAM(LOG_NLS)) { const char * __name; for(i = 0; i < systemData->size; i++) { ix = (systemData->iterationVarsPtr[i]-data->localData[0]->booleanVars); __name = data->modelData->booleanVarsData[ix].info.name; debugStreamPrint(LOG_NLS, 0, "%s changed : %d -> %d", __name, solverData->iterationVars[i], *(systemData->iterationVarsPtr[i])); } } } else { /* while the initialization it's okay not a solution */ if(!data->simulationInfo->initial) { warningStreamPrint(LOG_STDOUT, 0, "Error solving mixed equation system with index %d at time %e", eqSystemNumber, data->localData[0]->timeValue); } data->simulationInfo->needToIterate = 1; found_solution = -1; /*TODO: "break simulation?"*/ } } /* we found a solution*/ if(found_solution == 1) { success = 1; if(ACTIVE_STREAM(LOG_NLS)) { const char * __name; debugStreamPrint(LOG_NLS, 0, "#### SOLUTION FOUND! (system %d)", eqSystemNumber); for(i = 0; i < systemData->size; i++) { ix = (systemData->iterationVarsPtr[i]-data->localData[0]->booleanVars); __name = data->modelData->booleanVarsData[ix].info.name; debugStreamPrint(LOG_NLS, 0, "%s = %d pre(%s)= %d", __name, *systemData->iterationVarsPtr[i], __name, *systemData->iterationPreVarsPtr[i]); } } } stepCount++; mixedIterations++; }while(!found_solution); messageClose(LOG_NLS); debugStreamPrint(LOG_NLS, 0, "#### Finished mixed equation system in steps %d.\n", stepCount); return success; }
fmiStatus fmiEventUpdate(fmiComponent c, fmiBoolean intermediateResults, fmiEventInfo* eventInfo) { int i; ModelInstance* comp = (ModelInstance *)c; threadData_t *threadData = comp->threadData; if (invalidState(comp, "fmiEventUpdate", modelInitialized)) return fmiError; if (nullPointer(comp, "fmiEventUpdate", "eventInfo", eventInfo)) return fmiError; eventInfo->stateValuesChanged = fmiFalse; if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", "fmiEventUpdate: Start Event Update! Next Sample Event %g", eventInfo->nextEventTime); /* try */ MMC_TRY_INTERNAL(simulationJumpBuffer) if (stateSelection(comp->fmuData, threadData, 1, 1)) { if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", "fmiEventUpdate: Need to iterate state values changed!"); /* if new set is calculated reinit the solver */ eventInfo->stateValuesChanged = fmiTrue; } storePreValues(comp->fmuData); /* activate sample event */ for(i=0; i<comp->fmuData->modelData->nSamples; ++i) { if(comp->fmuData->simulationInfo->nextSampleTimes[i] <= comp->fmuData->localData[0]->timeValue) { comp->fmuData->simulationInfo->samples[i] = 1; infoStreamPrint(LOG_EVENTS, 0, "[%ld] sample(%g, %g)", comp->fmuData->modelData->samplesInfo[i].index, comp->fmuData->modelData->samplesInfo[i].start, comp->fmuData->modelData->samplesInfo[i].interval); } } comp->fmuData->callback->functionDAE(comp->fmuData, threadData); /* deactivate sample events */ for(i=0; i<comp->fmuData->modelData->nSamples; ++i) { if(comp->fmuData->simulationInfo->samples[i]) { comp->fmuData->simulationInfo->samples[i] = 0; comp->fmuData->simulationInfo->nextSampleTimes[i] += comp->fmuData->modelData->samplesInfo[i].interval; } } for(i=0; i<comp->fmuData->modelData->nSamples; ++i) if((i == 0) || (comp->fmuData->simulationInfo->nextSampleTimes[i] < comp->fmuData->simulationInfo->nextSampleEvent)) comp->fmuData->simulationInfo->nextSampleEvent = comp->fmuData->simulationInfo->nextSampleTimes[i]; if(comp->fmuData->callback->checkForDiscreteChanges(comp->fmuData, threadData) || comp->fmuData->simulationInfo->needToIterate || checkRelations(comp->fmuData) || eventInfo->stateValuesChanged) { intermediateResults = fmiTrue; if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", "fmiEventUpdate: Need to iterate(discrete changes)!"); eventInfo->iterationConverged = fmiTrue; eventInfo->stateValueReferencesChanged = fmiFalse; eventInfo->stateValuesChanged = fmiTrue; eventInfo->terminateSimulation = fmiFalse; } else { intermediateResults = fmiFalse; eventInfo->iterationConverged = fmiTrue; eventInfo->stateValueReferencesChanged = fmiFalse; eventInfo->terminateSimulation = fmiFalse; } /* due to an event overwrite old values */ overwriteOldSimulationData(comp->fmuData); /* TODO: check the event iteration for relation * in fmi import and export. This is an workaround, * since the iteration seem not starting. */ storePreValues(comp->fmuData); updateRelationsPre(comp->fmuData); if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", "fmiEventUpdate: intermediateResults = %d", intermediateResults); //Get Next Event Time double nextSampleEvent=0; nextSampleEvent = getNextSampleTimeFMU(comp->fmuData); if (nextSampleEvent == -1) { eventInfo->upcomingTimeEvent = fmiFalse; } else { eventInfo->upcomingTimeEvent = fmiTrue; eventInfo->nextEventTime = nextSampleEvent; } if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", "fmiEventUpdate: Checked for Sample Events! Next Sample Event %g",eventInfo->nextEventTime); return fmiOK; /* catch */ MMC_CATCH_INTERNAL(simulationJumpBuffer) comp->functions.logger(c, comp->instanceName, fmiError, "error", "fmiEventUpdate: terminated by an assertion."); return fmiError; }