static int simulationStep(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo) { SIMULATION_INFO *simInfo = data->simulationInfo; if(0 != strcmp("ia", data->simulationInfo->outputFormat)) { communicateStatus("Running", (solverInfo->currentTime - simInfo->startTime)/(simInfo->stopTime - simInfo->startTime), solverInfo->currentTime, solverInfo->currentStepSize); } return solver_main_step(data, threadData, solverInfo); }
static int simulationStep(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo) { SIMULATION_INFO *simInfo = &(data->simulationInfo); infoStreamPrint(LOG_SOLVER, 1, "call solver from %g to %g (stepSize: %.15g)", solverInfo->currentTime, solverInfo->currentTime + solverInfo->currentStepSize, solverInfo->currentStepSize); if(0 != strcmp("ia", data->simulationInfo.outputFormat)) { communicateStatus("Running", (solverInfo->currentTime - simInfo->startTime)/(simInfo->stopTime - simInfo->startTime)); } return solver_main_step(data, threadData, solverInfo); }
/*! performQSSSimulation(DATA* data, SOLVER_INFO* solverInfo) * * \param [ref] [data] * \param [ref] [solverInfo] * * This function performs the simulation controlled by solverInfo. */ modelica_integer prefixedName_performQSSSimulation(DATA* data, SOLVER_INFO* solverInfo) { TRACE_PUSH SIMULATION_INFO *simInfo = &(data->simulationInfo); MODEL_DATA *mData = &(data->modelData); uinteger currStepNo = 0; modelica_integer retValIntegrator = 0; modelica_integer retValue = 0; uinteger ind = 0; solverInfo->currentTime = simInfo->startTime; warningStreamPrint(LOG_STDOUT, 0, "This QSS method is under development and should not be used yet."); if (data->callback->initialAnalyticJacobianA(data)) { infoStreamPrint(LOG_STDOUT, 0, "Jacobian or sparse pattern is not generated or failed to initialize."); return UNKNOWN; } printSparseStructure(data, LOG_SOLVER); /* *********************************************************************************** */ /* Initialization */ uinteger i = 0; /* loop var */ SIMULATION_DATA *sData = (SIMULATION_DATA*)data->localData[0]; modelica_real* state = sData->realVars; modelica_real* stateDer = sData->realVars + data->modelData.nStates; const SPARSE_PATTERN* pattern = &(data->simulationInfo.analyticJacobians[data->callback->INDEX_JAC_A].sparsePattern); const uinteger ROWS = data->simulationInfo.analyticJacobians[data->callback->INDEX_JAC_A].sizeRows; const uinteger STATES = data->modelData.nStates; uinteger numDer = 0; /* number of derivatives influenced by state k */ modelica_boolean fail = 0; modelica_real* qik = NULL; /* Approximation of states */ modelica_real* xik = NULL; /* states */ modelica_real* derXik = NULL; /* Derivative of states */ modelica_real* tq = NULL; /* Time of approximation, because not all approximations are calculated at a specific time, each approx. has its own timestamp */ modelica_real* tx = NULL; /* Time of the states, because not all states are calculated at a specific time, each state has its own timestamp */ modelica_real* tqp = NULL; /* Time of the next change in state */ modelica_real* nQh = NULL; /* next value of the state */ modelica_real* dQ = NULL; /* change in quantity of every state, default = nominal*10^-4 */ /* allocate memory*/ qik = (modelica_real*)calloc(STATES, sizeof(modelica_real)); fail = (qik == NULL) ? 1 : ( 0 | fail); xik = (modelica_real*)calloc(STATES, sizeof(modelica_real)); fail = (xik == NULL) ? 1 : ( 0 | fail); derXik = (modelica_real*)calloc(STATES, sizeof(modelica_real)); fail = (derXik == NULL) ? 1 : ( 0 | fail); tq = (modelica_real*)calloc(STATES, sizeof(modelica_real)); fail = (tq == NULL) ? 1 : ( 0 | fail); tx = (modelica_real*)calloc(STATES, sizeof(modelica_real)); fail = (tx == NULL) ? 1 : ( 0 | fail); tqp = (modelica_real*)calloc(STATES, sizeof(modelica_real)); fail = (tqp == NULL) ? 1 : ( 0 | fail); nQh = (modelica_real*)calloc(STATES, sizeof(modelica_real)); fail = (nQh == NULL) ? 1 : ( 0 | fail); dQ = (modelica_real*)calloc(STATES, sizeof(modelica_real)); fail = (dQ == NULL) ? 1 : ( 0 | fail); if (fail) return OO_MEMORY; /* end - allocate memory */ /* further initialization of local variables */ modelica_real diffQ = 0.0, dTnextQ = 0.0, nextQ = 0.0; for (i = 0; i < STATES; i++) { dQ[i] = 0.0001 * data->modelData.realVarsData[i].attribute.nominal; tx[i] = tq[i] = simInfo->startTime; qik[i] = state[i]; xik[i] = state[i]; derXik[i] = stateDer[i]; retValue = deltaQ(data, dQ[i], i, &dTnextQ, &nextQ, &diffQ); if (OK != retValue) return retValue; tqp[i] = tq[i] + dTnextQ; nQh[i] = nextQ; } /* Transform the sparsity pattern into a data structure for an index based access. */ modelica_integer* der = (modelica_integer*)calloc(ROWS, sizeof(modelica_integer)); if (NULL==der) return OO_MEMORY; for (i = 0; i < ROWS; i++) der[i] = -1; /* how many states are involved in each derivative */ /* **** This is needed if we have QSS2 or higher **** */ /* uinteger* numStatesInDer = calloc(ROWS,sizeof(uinteger)); if (NULL==numStatesInDer) return OO_MEMORY; */ /* * dx1/dt = x2 * dx2/dt = x1 + x2 * lead to * StatesInDer[0]-{ 2 } * StatesInDer[1]-{ 1, 2 } */ /* uinteger** StatesInDer = calloc(ROWS,sizeof(uinteger*)); if (NULL==StatesInDer) return OO_MEMORY; */ /* count number of states in each derivative*/ /* for (i = 0; i < pattern->leadindex[ROWS-1]; i++) numStatesInDer[ pattern->index[i] ]++; */ /* collect memory for all stateindices */ /* for (i = 0; i < ROWS; i++) { *(StatesInDer + i) = calloc(numStatesInDer[i], sizeof(uinteger)); if (NULL==*(StatesInDer + i)) return OO_MEMORY; } retValue = getStatesInDer(pattern->index, pattern->leadindex, ROWS, STATES, StatesInDer); if (OK != retValue) return retValue; */ /* retValue = getDerWithStateK(pattern->index, pattern->leadindex, der, &numDer, 0); if (OK != retValue) return retValue; */ /* End of transformation */ #ifdef D FILE* fid=NULL; fid = fopen("log_qss.txt","w"); #endif /* *********************************************************************************** */ /***** Start main simulation loop *****/ while(solverInfo->currentTime < simInfo->stopTime) { modelica_integer success = 0; threadData->currentErrorStage = ERROR_SIMULATION; omc_alloc_interface.collect_a_little(); #if !defined(OMC_EMCC) /* try */ MMC_TRY_INTERNAL(simulationJumpBuffer) { #endif #ifdef USE_DEBUG_TRACE if (useStream[LOG_TRACE]) printf("TRACE: push loop step=%u, time=%.12g\n", currStepNo, solverInfo->currentTime); #endif #ifdef D fprintf(fid,"t = %.8f\n",solverInfo->currentTime); fprintf(fid,"%16s\t%16s\t%16s\t%16s\t%16s\t%16s\n","tx","x","dx","tq","q","tqp"); for (i = 0; i < STATES; i++) { fprintf(fid,"%16.8f\t%16.8f\t%16.8f\t%16.8f\t%16.8f\t%16.8f\n",tx[i],xik[i],derXik[i],tq[i],qik[i],tqp[i]); } #endif currStepNo++; ind = minStep(tqp, STATES); if (isnan(tqp[ind])) { #ifdef D fprintf(fid,"Exit caused by #QNAN!\tind=%d",ind); #endif return ISNAN; } if (isinf(tqp[ind])) { /* If all derivatives are zero, the states stay constant and only the * time propagates till stop->time. */ warningStreamPrint(LOG_STDOUT, 0, "All derivatives are zero at time %f!.\n", sData->timeValue); solverInfo->currentTime = simInfo->stopTime; sData->timeValue = solverInfo->currentTime; continue; } qik[ind] = nQh[ind]; xik[ind] = qik[ind]; state[ind] = qik[ind]; tx[ind] = tqp[ind]; tq[ind] = tqp[ind]; solverInfo->currentTime = tqp[ind]; #ifdef D fprintf(fid,"Index: %d\n\n",ind); #endif /* the state[ind] will change again in dTnextQ*/ retValue = deltaQ(data, dQ[ind], ind, &dTnextQ, &nextQ, &diffQ); if (OK != retValue) return retValue; tqp[ind] = tq[ind] + dTnextQ; nQh[ind] = nextQ; if (0 != strcmp("ia", MMC_STRINGDATA(data->simulationInfo.outputFormat))) { communicateStatus("Running", (solverInfo->currentTime-simInfo->startTime)/(simInfo->stopTime-simInfo->startTime)); } /* get the derivatives depending on state[ind] */ for (i = 0; i < ROWS; i++) der[i] = -1; retValue = getDerWithStateK(pattern->index, pattern->leadindex, der, &numDer, ind); uinteger k = 0, j = 0; for (k = 0; k < numDer; k++) { j = der[k]; if (j != ind) { xik[j] = xik[j] + derXik[j] * (solverInfo->currentTime - tx[j]); state[j] = xik[j]; tx[j] = solverInfo->currentTime; } } /* * Recalculate all equations which are affected by state[ind]. * Unfortunately all equations will be calculated up to now. And we need to evaluate * the equations as f(t,q) and not f(t,x). So all states were saved onto a local stack * and overwritten by q. After evaluating the equations the states are written back. */ for (i = 0; i < STATES; i++) { xik[i] = state[i]; /* save current state */ state[i] = qik[i]; /* overwrite current state for dx/dt = f(t,q) */ } /* update continous system */ sData->timeValue = solverInfo->currentTime; externalInputUpdate(data); data->callback->input_function(data); data->callback->functionODE(data); data->callback->functionAlgebraics(data); data->callback->output_function(data); data->callback->function_storeDelayed(data); for (i = 0; i < STATES; i++) { state[i] = xik[i]; /* restore current state */ } /* * Get derivatives affected by state[ind] and write back ALL derivatives. After that we have * states and derivatives for different times tx. */ for (k = 0; k < numDer; k++) { j = der[k]; derXik[j] = stateDer[j]; } derXik[ind] = stateDer[ind]; /* not in every case part of the above derivatives */ for (i = 0; i < STATES; i++) { stateDer[i] = derXik[i]; /* write back all derivatives */ } /* recalculate the time of next change only for the affected states */ for (k = 0; k < numDer; k++) { j = der[k]; retValue = deltaQ(data, dQ[j], j, &dTnextQ, &nextQ, &diffQ); if (OK != retValue) return retValue; tqp[j] = solverInfo->currentTime + dTnextQ; nQh[j] = nextQ; } /*sData->timeValue = solverInfo->currentTime;*/ solverInfo->laststep = solverInfo->currentTime; sim_result.emit(&sim_result, data); /* check if terminate()=true */ if (terminationTerminate) { printInfo(stdout, TermInfo); fputc('\n', stdout); infoStreamPrint(LOG_STDOUT, 0, "Simulation call terminate() at time %f\nMessage : %s", data->localData[0]->timeValue, TermMsg); simInfo->stopTime = solverInfo->currentTime; } /* terminate for some cases: * - integrator fails * - non-linear system failed to solve * - assert was called */ if (retValIntegrator) { retValue = -1 + retValIntegrator; infoStreamPrint(LOG_STDOUT, 0, "model terminate | Integrator failed. | Simulation terminated at time %g", solverInfo->currentTime); break; } else if (check_nonlinear_solutions(data, 0)) { retValue = -2; infoStreamPrint(LOG_STDOUT, 0, "model terminate | non-linear system solver failed. | Simulation terminated at time %g", solverInfo->currentTime); break; } else if (check_linear_solutions(data, 0)) { retValue = -3; infoStreamPrint(LOG_STDOUT, 0, "model terminate | linear system solver failed. | Simulation terminated at time %g", solverInfo->currentTime); break; } else if (check_mixed_solutions(data, 0)) { retValue = -4; infoStreamPrint(LOG_STDOUT, 0, "model terminate | mixed system solver failed. | Simulation terminated at time %g", solverInfo->currentTime); break; } success = 1; #if !defined(OMC_EMCC) } /* catch */ MMC_CATCH_INTERNAL(simulationJumpBuffer) #endif if (!success) { retValue = -1; infoStreamPrint(LOG_STDOUT, 0, "model terminate | Simulation terminated by an assert at time: %g", data->localData[0]->timeValue); break; } TRACE_POP /* pop loop */ } /* End of main loop */ #ifdef D fprintf(fid,"t = %.8f\n",solverInfo->currentTime); fprintf(fid,"%16s\t%16s\t%16s\t%16s\t%16s\t%16s\n","tx","x","dx","tq","q","tqp"); for (i = 0; i < STATES; i++) { fprintf(fid,"%16.8f\t%16.8f\t%16.8f\t%16.8f\t%16.8f\t%16.8f\n",tx[i],xik[i],derXik[i],tq[i],qik[i],tqp[i]); } fclose(fid); #endif /* free memory*/ free(der); /* for (i = 0; i < ROWS; i++) free(*(StatesInDer + i)); free(StatesInDer); free(numStatesInDer); */ free(qik); free(xik); free(derXik); free(tq); free(tx); free(tqp); free(nQh); free(dQ); /* end - free memory */ TRACE_POP return retValue; }