static inline void smallIntSolverStep(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo, const double tstop){ long double a; int iter; int err; solverInfo->currentTime = data->localData[0]->timeValue; while(solverInfo->currentTime < tstop){ a = 1.0; iter = 0; rotateRingBuffer(data->simulationData, 1, (void**) data->localData); do{ if(data->modelData->nStates < 1){ solverInfo->currentTime = tstop; data->localData[0]->timeValue = tstop; break; } solverInfo->currentStepSize = a*(tstop - solverInfo->currentTime); err = dassl_step(data, threadData, solverInfo); a *= 0.5; if(++iter > 10){ printf("\n"); warningStreamPrint(LOG_STDOUT, 0, "Initial guess failure at time %.12g", solverInfo->currentTime); assert(0); } }while(err < 0); data->callback->updateContinuousSystem(data, threadData); } }
/*! \fn performSimulation(DATA* data, SOLVER_INFO* solverInfo) * * \param [ref] [data] * \param [ref] [solverInfo] * * This function performs the simulation controlled by solverInfo. */ int prefixedName_performSimulation(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo) { TRACE_PUSH int retValIntegrator=0; int retValue=0; int i, retry=0; unsigned int __currStepNo = 0; SIMULATION_INFO *simInfo = &(data->simulationInfo); solverInfo->currentTime = simInfo->startTime; MEASURE_TIME fmt; fmtInit(data, &fmt); printAllVarsDebug(data, 0, LOG_DEBUG); /* ??? */ printSparseStructure(data, LOG_SOLVER); modelica_boolean syncStep = 0; /***** Start main simulation loop *****/ while(solverInfo->currentTime < simInfo->stopTime) { int success = 0; threadData->currentErrorStage = ERROR_SIMULATION; #ifdef USE_DEBUG_TRACE if(useStream[LOG_TRACE]) printf("TRACE: push loop step=%u, time=%.12g\n", __currStepNo, solverInfo->currentTime); #endif omc_alloc_interface.collect_a_little(); /* try */ #if !defined(OMC_EMCC) MMC_TRY_INTERNAL(simulationJumpBuffer) #endif { clear_rt_step(data); rotateRingBuffer(data->simulationData, 1, (void**) data->localData); modelica_boolean syncEventStep = solverInfo->didEventStep || syncStep; /***** Calculation next step size *****/ if(syncEventStep) { infoStreamPrint(LOG_SOLVER, 0, "offset value for the next step: %.16g", (solverInfo->currentTime - solverInfo->laststep)); } else { if (solverInfo->solverNoEquidistantGrid) { if (solverInfo->currentTime >= solverInfo->lastdesiredStep) { double tmpTime = solverInfo->currentTime; do { __currStepNo++; solverInfo->currentStepSize = (double)(__currStepNo*(simInfo->stopTime-simInfo->startTime))/(simInfo->numSteps) + simInfo->startTime - solverInfo->currentTime; }while(solverInfo->currentStepSize <= 0); } } else { __currStepNo++; } } solverInfo->currentStepSize = (double)(__currStepNo*(simInfo->stopTime-simInfo->startTime))/(simInfo->numSteps) + simInfo->startTime - solverInfo->currentTime; solverInfo->lastdesiredStep = solverInfo->currentTime + solverInfo->currentStepSize; /* if retry reduce stepsize */ if(0 != retry) { solverInfo->currentStepSize /= 2; } /***** End calculation next step size *****/ checkForSynchronous(data, solverInfo); /* check for next time event */ checkForSampleEvent(data, solverInfo); /* if regular output point and last time events are almost equals * skip that step and go further */ if (solverInfo->currentStepSize < 1e-15 && syncEventStep){ __currStepNo++; continue; } /* * integration step determine all states by a integration method * update continuous system */ retValIntegrator = simulationStep(data, threadData, solverInfo); if (S_OPTIMIZATION == solverInfo->solverMethod) break; syncStep = simulationUpdate(data, threadData, solverInfo); retry = 0; /* reset retry */ fmtEmitStep(data, threadData, &fmt, solverInfo->didEventStep); saveDasslStats(solverInfo); checkSimulationTerminated(data, solverInfo); /* 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) MMC_CATCH_INTERNAL(simulationJumpBuffer) #endif if (!success) /* catch */ { if(0 == retry) { retrySimulationStep(data, threadData, solverInfo); retry = 1; } else { 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 while solver */ fmtClose(&fmt); TRACE_POP return retValue; }
int dassl_initial(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo, DASSL_DATA *dasslData) { TRACE_PUSH /* work arrays for DASSL */ unsigned int i; SIMULATION_DATA tmpSimData = {0}; RHSFinalFlag = 0; dasslData->liw = 40 + data->modelData.nStates; dasslData->lrw = 60 + ((maxOrder + 4) * data->modelData.nStates) + (data->modelData.nStates * data->modelData.nStates) + (3*data->modelData.nZeroCrossings); dasslData->rwork = (double*) calloc(dasslData->lrw, sizeof(double)); assertStreamPrint(threadData, 0 != dasslData->rwork,"out of memory"); dasslData->iwork = (int*) calloc(dasslData->liw, sizeof(int)); assertStreamPrint(threadData, 0 != dasslData->iwork,"out of memory"); dasslData->ng = (int) data->modelData.nZeroCrossings; dasslData->jroot = (int*) calloc(data->modelData.nZeroCrossings, sizeof(int)); dasslData->rpar = (double**) malloc(3*sizeof(double*)); dasslData->ipar = (int*) malloc(sizeof(int)); dasslData->ipar[0] = ACTIVE_STREAM(LOG_JAC); assertStreamPrint(threadData, 0 != dasslData->ipar,"out of memory"); dasslData->atol = (double*) malloc(data->modelData.nStates*sizeof(double)); dasslData->rtol = (double*) malloc(data->modelData.nStates*sizeof(double)); dasslData->info = (int*) calloc(infoLength, sizeof(int)); assertStreamPrint(threadData, 0 != dasslData->info,"out of memory"); dasslData->dasslStatistics = (unsigned int*) calloc(numStatistics, sizeof(unsigned int)); assertStreamPrint(threadData, 0 != dasslData->dasslStatistics,"out of memory"); dasslData->dasslStatisticsTmp = (unsigned int*) calloc(numStatistics, sizeof(unsigned int)); assertStreamPrint(threadData, 0 != dasslData->dasslStatisticsTmp,"out of memory"); dasslData->idid = 0; dasslData->sqrteps = sqrt(DBL_EPSILON); dasslData->ysave = (double*) malloc(data->modelData.nStates*sizeof(double)); dasslData->delta_hh = (double*) malloc(data->modelData.nStates*sizeof(double)); dasslData->newdelta = (double*) malloc(data->modelData.nStates*sizeof(double)); dasslData->stateDer = (double*) malloc(data->modelData.nStates*sizeof(double)); dasslData->currentContext = CONTEXT_UNKNOWN; /* setup internal ring buffer for dassl */ /* RingBuffer */ dasslData->simulationData = 0; dasslData->simulationData = allocRingBuffer(SIZERINGBUFFER, sizeof(SIMULATION_DATA)); if(!data->simulationData) { throwStreamPrint(threadData, "Your memory is not strong enough for our Ringbuffer!"); } /* prepare RingBuffer */ for(i=0; i<SIZERINGBUFFER; i++) { /* set time value */ tmpSimData.timeValue = 0; /* buffer for all variable values */ tmpSimData.realVars = (modelica_real*)calloc(data->modelData.nVariablesReal, sizeof(modelica_real)); assertStreamPrint(threadData, 0 != tmpSimData.realVars, "out of memory"); tmpSimData.integerVars = (modelica_integer*)calloc(data->modelData.nVariablesInteger, sizeof(modelica_integer)); assertStreamPrint(threadData, 0 != tmpSimData.integerVars, "out of memory"); tmpSimData.booleanVars = (modelica_boolean*)calloc(data->modelData.nVariablesBoolean, sizeof(modelica_boolean)); assertStreamPrint(threadData, 0 != tmpSimData.booleanVars, "out of memory"); tmpSimData.stringVars = (modelica_string*) GC_malloc_uncollectable(data->modelData.nVariablesString * sizeof(modelica_string)); assertStreamPrint(threadData, 0 != tmpSimData.stringVars, "out of memory"); appendRingData(dasslData->simulationData, &tmpSimData); } dasslData->localData = (SIMULATION_DATA**) GC_malloc_uncollectable(SIZERINGBUFFER * sizeof(SIMULATION_DATA)); memset(dasslData->localData, 0, SIZERINGBUFFER * sizeof(SIMULATION_DATA)); rotateRingBuffer(dasslData->simulationData, 0, (void**) dasslData->localData); /* end setup internal ring buffer for dassl */ /* ### start configuration of dassl ### */ infoStreamPrint(LOG_SOLVER, 1, "Configuration of the dassl code:"); /* set nominal values of the states for absolute tolerances */ dasslData->info[1] = 1; infoStreamPrint(LOG_SOLVER, 1, "The relative tolerance is %g. Following absolute tolerances are used for the states: ", data->simulationInfo.tolerance); for(i=0; i<data->modelData.nStates; ++i) { dasslData->rtol[i] = data->simulationInfo.tolerance; dasslData->atol[i] = data->simulationInfo.tolerance * fmax(fabs(data->modelData.realVarsData[i].attribute.nominal), 1e-32); infoStreamPrint(LOG_SOLVER, 0, "%d. %s -> %g", i+1, data->modelData.realVarsData[i].info.name, dasslData->atol[i]); } messageClose(LOG_SOLVER); /* let dassl return at every internal step */ dasslData->info[2] = 1; /* define maximum step size, which is dassl is allowed to go */ if (omc_flag[FLAG_MAX_STEP_SIZE]) { double maxStepSize = atof(omc_flagValue[FLAG_MAX_STEP_SIZE]); assertStreamPrint(threadData, maxStepSize >= DASSL_STEP_EPS, "Selected maximum step size %e is too small.", maxStepSize); dasslData->rwork[1] = maxStepSize; dasslData->info[6] = 1; infoStreamPrint(LOG_SOLVER, 0, "maximum step size %g", dasslData->rwork[1]); } else { infoStreamPrint(LOG_SOLVER, 0, "maximum step size not set"); } /* define initial step size, which is dassl is used every time it restarts */ if (omc_flag[FLAG_INITIAL_STEP_SIZE]) { double initialStepSize = atof(omc_flagValue[FLAG_INITIAL_STEP_SIZE]); assertStreamPrint(threadData, initialStepSize >= DASSL_STEP_EPS, "Selected initial step size %e is too small.", initialStepSize); dasslData->rwork[2] = initialStepSize; dasslData->info[7] = 1; infoStreamPrint(LOG_SOLVER, 0, "initial step size %g", dasslData->rwork[2]); } else { infoStreamPrint(LOG_SOLVER, 0, "initial step size not set"); } /* define maximum integration order of dassl */ if (omc_flag[FLAG_MAX_ORDER]) { int maxOrder = atoi(omc_flagValue[FLAG_MAX_ORDER]); assertStreamPrint(threadData, maxOrder >= 1 && maxOrder <= 5, "Selected maximum order %d is out of range (1-5).", maxOrder); dasslData->iwork[2] = maxOrder; dasslData->info[8] = 1; } infoStreamPrint(LOG_SOLVER, 0, "maximum integration order %d", dasslData->info[8]?dasslData->iwork[2]:maxOrder); /* if FLAG_NOEQUIDISTANT_GRID is set, choose dassl step method */ if (omc_flag[FLAG_NOEQUIDISTANT_GRID]) { dasslData->dasslSteps = 1; /* TRUE */ solverInfo->solverNoEquidistantGrid = 1; } else { dasslData->dasslSteps = 0; /* FALSE */ } infoStreamPrint(LOG_SOLVER, 0, "use equidistant time grid %s", dasslData->dasslSteps?"NO":"YES"); /* check if Flags FLAG_NOEQUIDISTANT_OUT_FREQ or FLAG_NOEQUIDISTANT_OUT_TIME are set */ if (dasslData->dasslSteps){ if (omc_flag[FLAG_NOEQUIDISTANT_OUT_FREQ]) { dasslData->dasslStepsFreq = atoi(omc_flagValue[FLAG_NOEQUIDISTANT_OUT_FREQ]); } else if (omc_flag[FLAG_NOEQUIDISTANT_OUT_TIME]) { dasslData->dasslStepsTime = atof(omc_flagValue[FLAG_NOEQUIDISTANT_OUT_TIME]); dasslData->rwork[1] = dasslData->dasslStepsTime; dasslData->info[6] = 1; infoStreamPrint(LOG_SOLVER, 0, "maximum step size %g", dasslData->rwork[1]); } else { dasslData->dasslStepsFreq = 1; dasslData->dasslStepsTime = 0.0; } if (omc_flag[FLAG_NOEQUIDISTANT_OUT_FREQ] && omc_flag[FLAG_NOEQUIDISTANT_OUT_TIME]){ warningStreamPrint(LOG_STDOUT, 0, "The flags are \"noEquidistantOutputFrequency\" " "and \"noEquidistantOutputTime\" are in opposition " "to each other. The flag \"noEquidistantOutputFrequency\" superiors."); } infoStreamPrint(LOG_SOLVER, 0, "as the output frequency control is used: %d", dasslData->dasslStepsFreq); infoStreamPrint(LOG_SOLVER, 0, "as the output frequency time step control is used: %f", dasslData->dasslStepsTime); } /* if FLAG_DASSL_JACOBIAN is set, choose dassl jacobian calculation method */ if (omc_flag[FLAG_DASSL_JACOBIAN]) { for(i=1; i< DASSL_JAC_MAX;i++) { if(!strcmp((const char*)omc_flagValue[FLAG_DASSL_JACOBIAN], dasslJacobianMethodStr[i])){ dasslData->dasslJacobian = (int)i; break; } } if(dasslData->dasslJacobian == DASSL_JAC_UNKNOWN) { if (ACTIVE_WARNING_STREAM(LOG_SOLVER)) { warningStreamPrint(LOG_SOLVER, 1, "unrecognized jacobian calculation method %s, current options are:", (const char*)omc_flagValue[FLAG_DASSL_JACOBIAN]); for(i=1; i < DASSL_JAC_MAX; ++i) { warningStreamPrint(LOG_SOLVER, 0, "%-15s [%s]", dasslJacobianMethodStr[i], dasslJacobianMethodDescStr[i]); } messageClose(LOG_SOLVER); } throwStreamPrint(threadData,"unrecognized jacobian calculation method %s", (const char*)omc_flagValue[FLAG_DASSL_JACOBIAN]); } /* default case colored numerical jacobian */ } else { dasslData->dasslJacobian = DASSL_COLOREDNUMJAC; } /* selects the calculation method of the jacobian */ if(dasslData->dasslJacobian == DASSL_COLOREDNUMJAC || dasslData->dasslJacobian == DASSL_COLOREDSYMJAC || dasslData->dasslJacobian == DASSL_NUMJAC || dasslData->dasslJacobian == DASSL_SYMJAC) { if (data->callback->initialAnalyticJacobianA(data, threadData)) { infoStreamPrint(LOG_STDOUT, 0, "Jacobian or SparsePattern is not generated or failed to initialize! Switch back to normal."); dasslData->dasslJacobian = DASSL_INTERNALNUMJAC; } else { dasslData->info[4] = 1; /* use sub-routine JAC */ } } /* set up the appropriate function pointer */ switch (dasslData->dasslJacobian){ case DASSL_COLOREDNUMJAC: dasslData->jacobianFunction = JacobianOwnNumColored; break; case DASSL_COLOREDSYMJAC: dasslData->jacobianFunction = JacobianSymbolicColored; break; case DASSL_SYMJAC: dasslData->jacobianFunction = JacobianSymbolic; break; case DASSL_NUMJAC: dasslData->jacobianFunction = JacobianOwnNum; break; case DASSL_INTERNALNUMJAC: dasslData->jacobianFunction = dummy_Jacobian; break; default: throwStreamPrint(threadData,"unrecognized jacobian calculation method %s", (const char*)omc_flagValue[FLAG_DASSL_JACOBIAN]); break; } infoStreamPrint(LOG_SOLVER, 0, "jacobian is calculated by %s", dasslJacobianMethodDescStr[dasslData->dasslJacobian]); /* if FLAG_DASSL_NO_ROOTFINDING is set, choose dassl with out internal root finding */ if(omc_flag[FLAG_DASSL_NO_ROOTFINDING]) { dasslData->dasslRootFinding = 0; dasslData->zeroCrossingFunction = dummy_zeroCrossing; dasslData->ng = 0; } else { solverInfo->solverRootFinding = 1; dasslData->dasslRootFinding = 1; dasslData->zeroCrossingFunction = function_ZeroCrossingsDASSL; } infoStreamPrint(LOG_SOLVER, 0, "dassl uses internal root finding method %s", dasslData->dasslRootFinding?"YES":"NO"); /* if FLAG_DASSL_NO_RESTART is set, choose dassl step method */ if (omc_flag[FLAG_DASSL_NO_RESTART]) { dasslData->dasslAvoidEventRestart = 1; /* TRUE */ } else { dasslData->dasslAvoidEventRestart = 0; /* FALSE */ } infoStreamPrint(LOG_SOLVER, 0, "dassl performs an restart after an event occurs %s", dasslData->dasslAvoidEventRestart?"NO":"YES"); /* ### end configuration of dassl ### */ messageClose(LOG_SOLVER); TRACE_POP return 0; }
/*! * create initial guess dasslColorSymJac * author: Vitalij Ruge **/ static short initial_guess_ipopt_sim(OptData *optData, SOLVER_INFO* solverInfo, const short o) { double *u0; int i,j,k,l; modelica_real ***v; long double tol; short printGuess, op=1; const int nx = optData->dim.nx; const int nu = optData->dim.nu; const int np = optData->dim.np; const int nsi = optData->dim.nsi; const int nReal = optData->dim.nReal; char *cflags = (char*)omc_flagValue[FLAG_IIF]; DATA* data = optData->data; threadData_t *threadData = optData->threadData; SIMULATION_INFO *sInfo = data->simulationInfo; if(!data->simulationInfo->external_input.active){ externalInputallocate(data); } /* Initial DASSL solver */ DASSL_DATA* dasslData = (DASSL_DATA*) malloc(sizeof(DASSL_DATA)); tol = data->simulationInfo->tolerance; data->simulationInfo->tolerance = fmin(fmax(tol,1e-8),1e-3); infoStreamPrint(LOG_SOLVER, 0, "Initial Guess: Initializing DASSL"); sInfo->solverMethod = "dassl"; solverInfo->solverMethod = S_DASSL; dassl_initial(data, threadData, solverInfo, dasslData); solverInfo->solverMethod = S_OPTIMIZATION; solverInfo->solverData = dasslData; u0 = optData->bounds.u0; v = optData->v; if(!data->simulationInfo->external_input.active) for(i = 0; i< nu;++i) data->simulationInfo->inputVars[i] = u0[i]/*optData->bounds.scalF[i + nx]*/; printGuess = (short)(ACTIVE_STREAM(LOG_INIT) && !ACTIVE_STREAM(LOG_SOLVER)); if((double)data->simulationInfo->startTime < optData->time.t0){ double t = data->simulationInfo->startTime; const int nBoolean = data->modelData->nVariablesBoolean; const int nInteger = data->modelData->nVariablesInteger; const int nRelations = data->modelData->nRelations; FILE * pFile = optData->pFile; fprintf(pFile, "%lf ",(double)t); for(i = 0; i < nu; ++i){ fprintf(pFile, "%lf ", (float)data->simulationInfo->inputVars[i]); } fprintf(pFile, "%s", "\n"); if(1){ printf("\nPreSim"); printf("\n========================================================\n"); printf("\ndone: time[%i] = %g",0,(double)data->simulationInfo->startTime); } while(t < optData->time.t0){ externalInputUpdate(data); smallIntSolverStep(data, threadData, solverInfo, fmin(t += optData->time.dt[0], optData->time.t0)); printf("\ndone: time[%i] = %g",0,(double)data->localData[0]->timeValue); sim_result.emit(&sim_result,data,threadData); fprintf(pFile, "%lf ",(double)data->localData[0]->timeValue); for(i = 0; i < nu; ++i){ fprintf(pFile, "%lf ", (float)data->simulationInfo->inputVars[i]); } fprintf(pFile, "%s", "\n"); } memcpy(optData->v0, data->localData[0]->realVars, nReal*sizeof(modelica_real)); memcpy(optData->i0, data->localData[0]->integerVars, nInteger*sizeof(modelica_integer)); memcpy(optData->b0, data->localData[0]->booleanVars, nBoolean*sizeof(modelica_boolean)); memcpy(optData->i0Pre, data->simulationInfo->integerVarsPre, nInteger*sizeof(modelica_integer)); memcpy(optData->b0Pre, data->simulationInfo->booleanVarsPre, nBoolean*sizeof(modelica_boolean)); memcpy(optData->v0Pre, data->simulationInfo->realVarsPre, nReal*sizeof(modelica_real)); memcpy(optData->rePre, data->simulationInfo->relationsPre, nRelations*sizeof(modelica_boolean)); memcpy(optData->re, data->simulationInfo->relations, nRelations*sizeof(modelica_boolean)); memcpy(optData->storeR, data->simulationInfo->storedRelations, nRelations*sizeof(modelica_boolean)); if(1){ printf("\n--------------------------------------------------------"); printf("\nfinished: PreSim"); printf("\n========================================================\n"); } } if(o == 2 && cflags && strcmp(cflags, "")) op = 2; if(printGuess ){ printf("\nInitial Guess"); printf("\n========================================================\n"); printf("\ndone: time[%i] = %g",0,(double)optData->time.t0); } for(i = 0, k=1; i < nsi; ++i){ for(j = 0; j < np; ++j, ++k){ externalInputUpdate(data); if(op==1) smallIntSolverStep(data, threadData, solverInfo, (double)optData->time.t[i][j]); else{ rotateRingBuffer(data->simulationData, 1, (void**) data->localData); importStartValues(data, threadData, cflags, (double)optData->time.t[i][j]); for(l=0; l<nReal; ++l){ data->localData[0]->realVars[l] = data->modelData->realVarsData[l].attribute.start; } } if(printGuess) printf("\ndone: time[%i] = %g", k, (double)optData->time.t[i][j]); memcpy(v[i][j], data->localData[0]->realVars, nReal*sizeof(double)); for(l = 0; l < nx; ++l){ if(((double) v[i][j][l] < (double)optData->bounds.vmin[l]*optData->bounds.vnom[l]) || (double) (v[i][j][l] > (double) optData->bounds.vmax[l]*optData->bounds.vnom[l])){ printf("\n********************************************\n"); warningStreamPrint(LOG_STDOUT, 0, "Initial guess failure at time %g",(double)optData->time.t[i][j]); warningStreamPrint(LOG_STDOUT, 0, "%g<= (%s=%g) <=%g", (double)optData->bounds.vmin[l]*optData->bounds.vnom[l], data->modelData->realVarsData[l].info.name, (double)v[i][j][l], (double)optData->bounds.vmax[l]*optData->bounds.vnom[l]); printf("\n********************************************"); } } } } if(printGuess){ printf("\n--------------------------------------------------------"); printf("\nfinished: Initial Guess"); printf("\n========================================================\n"); } dassl_deinitial(solverInfo->solverData); solverInfo->solverData = (void*)optData; sInfo->solverMethod = "optimization"; data->simulationInfo->tolerance = tol; externalInputFree(data); return op; }
/*! \fn performSimulation(DATA* data, SOLVER_INFO* solverInfo) * * \param [ref] [data] * \param [ref] [solverInfo] * * This function performs the simulation controlled by solverInfo. */ int prefixedName_performSimulation(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo) { TRACE_PUSH int retValIntegrator=0; int retValue=0; int i, retry=0, steadStateReached=0; unsigned int __currStepNo = 0; SIMULATION_INFO *simInfo = data->simulationInfo; solverInfo->currentTime = simInfo->startTime; MEASURE_TIME fmt; fmtInit(data, &fmt); printAllVarsDebug(data, 0, LOG_DEBUG); /* ??? */ if (!compiledInDAEMode) { printSparseStructure(&(data->simulationInfo->analyticJacobians[data->callback->INDEX_JAC_A].sparsePattern), data->simulationInfo->analyticJacobians[data->callback->INDEX_JAC_A].sizeRows, data->simulationInfo->analyticJacobians[data->callback->INDEX_JAC_A].sizeCols, LOG_SOLVER, "ODE sparse pattern"); } else { printSparseStructure(data->simulationInfo->daeModeData->sparsePattern, data->simulationInfo->daeModeData->nResidualVars, data->simulationInfo->daeModeData->nResidualVars, LOG_SOLVER, "DAE sparse pattern"); } if(terminationTerminate) { printInfo(stdout, TermInfo); fputc('\n', stdout); infoStreamPrint(LOG_STDOUT, 0, "Simulation call terminate() at initialization (time %f)\nMessage : %s", data->localData[0]->timeValue, TermMsg); data->simulationInfo->stopTime = solverInfo->currentTime; } else { modelica_boolean syncStep = 0; /***** Start main simulation loop *****/ while(solverInfo->currentTime < simInfo->stopTime || !simInfo->useStopTime) { int success = 0; threadData->currentErrorStage = ERROR_SIMULATION; #ifdef USE_DEBUG_TRACE if(useStream[LOG_TRACE]) { printf("TRACE: push loop step=%u, time=%.12g\n", __currStepNo, solverInfo->currentTime); } #endif /* check for steady state */ if (omc_flag[FLAG_STEADY_STATE]) { if (0 < data->modelData->nStates) { int i; double maxDer = 0.0; double currDer; for(i=data->modelData->nStates; i<2*data->modelData->nStates; ++i) { currDer = fabs(data->localData[0]->realVars[i] / data->modelData->realVarsData[i].attribute.nominal); if(maxDer < currDer) maxDer = currDer; } if (maxDer < steadyStateTol) { steadStateReached=1; infoStreamPrint(LOG_STDOUT, 0, "steady state reached at time = %g\n * max(|d(x_i)/dt|/nominal(x_i)) = %g\n * relative tolerance = %g", solverInfo->currentTime, maxDer, steadyStateTol); break; } } else throwStreamPrint(threadData, "No states in model. Flag -steadyState can only be used if states are present."); } omc_alloc_interface.collect_a_little(); /* try */ #if !defined(OMC_EMCC) MMC_TRY_INTERNAL(simulationJumpBuffer) #endif { printAllVars(data, 0, LOG_SOLVER_V); clear_rt_step(data); if (!compiledInDAEMode) /* do not use ringbuffer for daeMode */ rotateRingBuffer(data->simulationData, 1, (void**) data->localData); modelica_boolean syncEventStep = solverInfo->didEventStep || syncStep; /***** Calculation next step size *****/ if(syncEventStep) { infoStreamPrint(LOG_SOLVER, 0, "offset value for the next step: %.16g", (solverInfo->currentTime - solverInfo->laststep)); } else { if (solverInfo->solverNoEquidistantGrid) { if (solverInfo->currentTime >= solverInfo->lastdesiredStep) { do { __currStepNo++; solverInfo->currentStepSize = (double)(__currStepNo*(simInfo->stopTime-simInfo->startTime))/(simInfo->numSteps) + simInfo->startTime - solverInfo->currentTime; } while(solverInfo->currentStepSize <= 0); } } else { __currStepNo++; } } solverInfo->currentStepSize = (double)(__currStepNo*(simInfo->stopTime-simInfo->startTime))/(simInfo->numSteps) + simInfo->startTime - solverInfo->currentTime; solverInfo->lastdesiredStep = solverInfo->currentTime + solverInfo->currentStepSize; /* if retry reduce stepsize */ if (0 != retry) { solverInfo->currentStepSize /= 2; } /***** End calculation next step size *****/ checkForSynchronous(data, solverInfo); /* check for next time event */ checkForSampleEvent(data, solverInfo); /* if regular output point and last time events are almost equals * skip that step and go further */ if (solverInfo->currentStepSize < 1e-15 && syncEventStep){ __currStepNo++; continue; } /* * integration step determine all states by a integration method * update continuous system */ infoStreamPrint(LOG_SOLVER, 1, "call solver from %g to %g (stepSize: %.15g)", solverInfo->currentTime, solverInfo->currentTime + solverInfo->currentStepSize, solverInfo->currentStepSize); retValIntegrator = simulationStep(data, threadData, solverInfo); infoStreamPrint(LOG_SOLVER, 0, "finished solver step %g", solverInfo->currentTime); messageClose(LOG_SOLVER); if (S_OPTIMIZATION == solverInfo->solverMethod) break; syncStep = simulationUpdate(data, threadData, solverInfo); retry = 0; /* reset retry */ fmtEmitStep(data, threadData, &fmt, solverInfo); saveIntegratorStats(solverInfo); checkSimulationTerminated(data, solverInfo); /* 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) MMC_CATCH_INTERNAL(simulationJumpBuffer) #endif if (!success) { /* catch */ if(0 == retry) { retrySimulationStep(data, threadData, solverInfo); retry = 1; } else { 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 while solver */ } /* end else */ fmtClose(&fmt); if (omc_flag[FLAG_STEADY_STATE] && !steadStateReached) { warningStreamPrint(LOG_STDOUT, 0, "Steady state has not been reached.\nThis may be due to too restrictive relative tolerance (%g) or short stopTime (%g).", steadyStateTol, simInfo->stopTime); } TRACE_POP return retValue; }
/*! * create initial guess * author: Vitalij Ruge **/ int initial_guess_ipopt(IPOPT_DATA_ *iData,SOLVER_INFO* solverInfo) { double *u0, *u, *x, uu,tmp ,lhs, rhs; int i,j,k,ii,jj,id; int err; double *v; DATA* data = iData->data; SIMULATION_DATA *sData = (SIMULATION_DATA*)data->localData[0]; SIMULATION_INFO *sInfo = &(data->simulationInfo); KINODE *kinOde; u0 = iData->data->localData[1]->realVars + iData->index_u; u = iData->data->localData[0]->realVars + iData->index_u; x = iData->data->localData[0]->realVars; v = iData->v; for(ii=iData->nx,j=0; j < iData->nu; ++j, ++ii) { u0[j] = data->modelData.realVarsData[iData->index_u+j].attribute.start; u0[j] = fmin(fmax(u0[j],iData->umin[j]),iData->umax[j]); u[j] = u0[j]; v[ii] = u0[j]*iData->scalVar[j + iData->nx]; } solverInfo->solverData = calloc(1, sizeof(KINODE)); kinOde = (KINODE*) solverInfo->solverData; refreshSimData(x, u, iData->tf, iData); allocateKinOde(data, solverInfo, 8, 1); if(ACTIVE_STREAM(LOG_IPOPT)) { printf("\n****initial guess****"); printf("\n #####done time[%i] = %f",0,iData->time[0]); } for(i=0, k=1, v=iData->v + iData->nv; i<iData->nsi; ++i) { for(jj=0; jj<iData->deg; ++jj, ++k) { solverInfo->currentStepSize = iData->time[k] - iData->time[k-1]; iData->data->localData[1]->timeValue = iData->time[k]; do { err = kinsolOde(solverInfo->solverData); if(err < 0) { solverInfo->currentStepSize *= 0.99; kinOde->kData->fnormtol *=10.0; kinOde->kData->scsteptol *=10.0; if(ACTIVE_STREAM(LOG_SOLVER)) { printf("\n #####try time[%i] = %f",k,iData->time[k]); } } else { if(ACTIVE_STREAM(LOG_IPOPT)) printf("\n #####done time[%i] = %f",k,iData->time[k]); } }while(err <0); kinOde->kData->fnormtol =iData->data->simulationInfo.tolerance; kinOde->kData->scsteptol =iData->data->simulationInfo.tolerance; for(j=0; j< iData->nx; ++j) { v[j] = sData->realVars[j] * iData->scalVar[j]; } for(ii=iData->index_u; j< iData->nv; ++j, ++ii) { v[j] = sData->realVars[ii] * iData->scalVar[j]; } v += iData->nv; /* updateContinuousSystem(iData->data); */ rotateRingBuffer(iData->data->simulationData, 1, (void**) iData->data->localData); } } for(i = 0, id=0; i<iData->NV;i++,++id) { if(id >=iData->nv) id = 0; if(id <iData->nx) { iData->v[i] =fmin(fmax(iData->vmin[id],iData->v[i]),iData->vmax[id]); } else if(id< iData->nv) { iData->v[i] = fmin(fmax(iData->vmin[id],iData->v[i]),iData->vmax[id]); } } if(ACTIVE_STREAM(LOG_IPOPT)) printf("\n*****initial guess done*****"); freeKinOde(data, solverInfo, 8, 1); solverInfo->solverData = (void*)iData; return 0; }