static int simulationUpdate(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo) { prefixedName_updateContinuousSystem(data, threadData); if (solverInfo->solverMethod == S_SYM_IMP_EULER) data->callback->symEulerUpdate(data, solverInfo->solverStepSize); saveZeroCrossings(data, threadData); messageClose(LOG_SOLVER); /***** Event handling *****/ if (measure_time_flag) rt_tick(SIM_TIMER_EVENT); int syncRet = handleTimers(data, threadData, solverInfo); int syncRet1; do { int eventType = checkEvents(data, threadData, solverInfo->eventLst, &(solverInfo->currentTime), solverInfo); if(eventType > 0 || syncRet == 2) /* event */ { threadData->currentErrorStage = ERROR_EVENTHANDLING; infoStreamPrint(LOG_EVENTS, 1, "%s event at time=%.12g", eventType == 1 ? "time" : "state", solverInfo->currentTime); /* prevent emit if noEventEmit flag is used */ if (!(omc_flag[FLAG_NOEVENTEMIT])) /* output left limit */ sim_result.emit(&sim_result, data, threadData); handleEvents(data, threadData, solverInfo->eventLst, &(solverInfo->currentTime), solverInfo); messageClose(LOG_EVENTS); threadData->currentErrorStage = ERROR_SIMULATION; solverInfo->didEventStep = 1; overwriteOldSimulationData(data); } else /* no event */ { solverInfo->laststep = solverInfo->currentTime; solverInfo->didEventStep = 0; } if (measure_time_flag) rt_accumulate(SIM_TIMER_EVENT); /***** End event handling *****/ /***** check state selection *****/ if (stateSelection(data, threadData, 1, 1)) { /* if new set is calculated reinit the solver */ solverInfo->didEventStep = 1; overwriteOldSimulationData(data); } /* Check for warning of variables out of range assert(min<x || x>xmax, ...)*/ data->callback->checkForAsserts(data, threadData); storePreValues(data); storeOldValues(data); syncRet1 = handleTimers(data, threadData, solverInfo); syncRet = syncRet1 == 0 ? syncRet : syncRet1; } while (syncRet1); return syncRet; }
/******************************* interpolation module ************************************************/ int interpolation_control(const int dideventstep, double interpolationStep, double fixStep, double stop) { int i,l; if(sim_verbose >= LOG_SOLVER) { fprintf(stdout, "| info | dense output: $$$$$\t interpolate data at %g\n", interpolationStep); fflush(NULL); } /* if(sim_verbose >= LOG_SOLVER) * { * cout << "oldTime,Time,interpolate data at " << globalData->oldTime << ", " * << globalData->timeValue << ", " << interpolationStep << endl; fflush(NULL); * } /* for debugging */ if(dideventstep == 1) { /* Emit data after an event */ sim_result.emit(&sim_result,data); } if(((interpolationStep > globalData->oldTime) && (interpolationStep < globalData->timeValue)) || ((dideventstep == 1) && (interpolationStep < globalData->timeValue))) { double** k = work_states; double backupTime = globalData->timeValue; double backupTime_old = globalData->oldTime; double* backupstats = (double*) malloc(globalData->nStates * sizeof(double)); double* backupderivatives = (double*) malloc(globalData->nStates * sizeof(double)); double* backupstats_old = (double*) malloc(globalData->nStates * sizeof(double)); double bstar[9]; double numerator = 0, sigma, sh, sum; /* save states and derivatives as they're altered by linear interpolation method */ for(i = 0; i < globalData->nStates; i++) { backupstats[i] = globalData->states[i]; backupderivatives[i] = globalData->statesDerivatives[i]; backupstats_old[i] = globalData->states_old[i]; } do { if(!(backupTime == backupTime_old)) /* don't interpolate during an event */ { /* calculate dense output interpolation parameter sigma */ sh = interpolationStep - globalData->timeValue; sigma = sh / globalData->current_stepsize; for(i = 0; i < dop5dense_s; i++) { /* compute bstar vector components using Horner's scheme */ numerator = dop_bst[i][4] + sigma * (dop_bst[i][3] + sigma * (dop_bst[i][2] + sigma * (dop_bst[i][1] + sigma * dop_bst[i][0]))); bstar[i] = numerator / dop_bst[i][5]; } for(i = 0; i < globalData->nStates; i++) { sum = 0; for(l = 0; l < dop5dense_s; l++) { sum = sum + bstar[l] * k[l][i]; } globalData->states[i] = globalData->states[i] + sh * sum; } /* set global time value to interpolated time */ globalData->timeValue = interpolationStep; /* update all dependent variables */ functionODE(NULL); functionAlgebraics(NULL); saveZeroCrossings(); /* Emit interpolated data at the current time step */ sim_result.emit(&sim_result,data); } interpolationStep = interpolationStep + fixStep; } while ((interpolationStep <= stop + fixStep) && (interpolationStep < backupTime)); /* update old data */ globalData->oldTime = backupTime; /* reset data for next solver step */ globalData->timeValue = backupTime; for(i = 0; i < globalData->nStates; i++) { globalData->states[i] = backupstats[i]; globalData->statesDerivatives[i] = backupderivatives[i]; } free(backupstats); free(backupderivatives); free(backupstats_old); } else { globalData->oldTime = globalData->timeValue; } return 0; }