static int getNsi(char*filename, const int nsi, modelica_boolean * exTimeGrid){ int n = 0, c; FILE * pFile = NULL; *exTimeGrid = 0; pFile = fopen(filename,"r"); if(pFile == NULL){ warningStreamPrint(LOG_STDOUT, 0, "OMC can't find the file %s.", filename); fclose(pFile); return nsi; } while(1){ c = fgetc(pFile); if (c==EOF) break; if (c=='\n') ++n; } // check if csv file is empty! if (n == 0){ warningStreamPrint(LOG_STDOUT, 0, "time grid file: %s is empty", filename); fclose(pFile); return nsi; } *exTimeGrid = 1; return n-1; }
static void fmtInit(DATA* data, MEASURE_TIME* mt) { mt->fmtReal = NULL; mt->fmtInt = NULL; if(measure_time_flag) { const char* fullFileName; if (omc_flag[FLAG_OUTPUT_PATH]) { /* read the output path from the command line (if any) */ if (0 > GC_asprintf(&fullFileName, "%s/%s", omc_flagValue[FLAG_OUTPUT_PATH], data->modelData->modelFilePrefix)) { throwStreamPrint(NULL, "perform_simulation.c: Error: can not allocate memory."); } } else { fullFileName = data->modelData->modelFilePrefix; } size_t len = strlen(fullFileName); char* filename = (char*) malloc((len+15) * sizeof(char)); strncpy(filename,fullFileName,len); strncpy(&filename[len],"_prof.realdata",15); mt->fmtReal = fopen(filename, "wb"); if(!mt->fmtReal) { warningStreamPrint(LOG_STDOUT, 0, "Time measurements output file %s could not be opened: %s", filename, strerror(errno)); } strncpy(&filename[len],"_prof.intdata",14); mt->fmtInt = fopen(filename, "wb"); if(!mt->fmtInt) { warningStreamPrint(LOG_STDOUT, 0, "Time measurements output file %s could not be opened: %s", filename, strerror(errno)); fclose(mt->fmtReal); mt->fmtReal = NULL; } free(filename); } }
static void fmtInit(DATA* data, MEASURE_TIME* mt) { mt->fmtReal = NULL; mt->fmtInt = NULL; if(measure_time_flag) { size_t len = strlen(data->modelData.modelFilePrefix); char* filename = (char*) malloc((len+15) * sizeof(char)); strncpy(filename,data->modelData.modelFilePrefix,len); strncpy(&filename[len],"_prof.realdata",15); mt->fmtReal = fopen(filename, "wb"); if(!mt->fmtReal) { warningStreamPrint(LOG_STDOUT, 0, "Time measurements output file %s could not be opened: %s", filename, strerror(errno)); } strncpy(&filename[len],"_prof.intdata",14); mt->fmtInt = fopen(filename, "wb"); if(!mt->fmtInt) { warningStreamPrint(LOG_STDOUT, 0, "Time measurements output file %s could not be opened: %s", filename, strerror(errno)); fclose(mt->fmtReal); mt->fmtReal = NULL; } free(filename); } }
/*! * pick up start values from csv for states * author: Vitalij Ruge **/ static inline void pickUpStates(OptData* optData){ char* cflags; cflags = (char*)omc_flagValue[FLAG_INPUT_FILE_STATES]; if(cflags){ FILE * pFile = NULL; pFile = fopen(cflags,"r"); if(pFile == NULL){ warningStreamPrint(LOG_STDOUT, 0, "OMC can't find the file %s.",cflags); }else{ int c, n = 0; modelica_boolean b; while(1){ c = fgetc(pFile); if (c==EOF) break; if (c=='\n') ++n; } // check if csv file is empty! if(n == 0){ fprintf(stderr, "External input file: externalInput.csv is empty!\n"); fflush(NULL); EXIT(1); }else{ int i, j; double start_value; char buffer[200]; const int nReal = optData->data->modelData.nVariablesReal; rewind(pFile); for(i =0; i< n; ++i){ fscanf(pFile, "%s", buffer); if (fscanf(pFile, "%lf", &start_value) <= 0) continue; for(j = 0, b = 0; j < nReal; ++j){ if(!strcmp(optData->data->modelData.realVarsData[j].info.name, buffer)){ optData->data->localData[0]->realVars[j] = start_value; optData->data->localData[1]->realVars[j] = start_value; optData->data->localData[2]->realVars[j] = start_value; optData->v0[i] = start_value; b = 1; continue; } } if(!b) warningStreamPrint(LOG_STDOUT, 0, "it was impossible to set %s.start %g", buffer,start_value); else printf("\n[%i]set %s.start %g", i, buffer,start_value); } fclose(pFile); printf("\n"); /*update system*/ optData->data->callback->input_function(optData->data); /*optData->data->callback->functionDAE(optData->data);*/ updateDiscreteSystem(optData->data); } } } }
static void nlsKinsolInfoPrint(const char *module, const char *function, char *msg, void *user_data) { if (ACTIVE_STREAM(LOG_NLS_V)) { warningStreamPrint(LOG_NLS_V, 1, "%s %s:", module, function); warningStreamPrint(LOG_NLS_V, 0, "%s", msg); messageClose(LOG_NLS_V); } }
/*! * helper for initial_guess_optimizer (pick up clfag option) * author: Vitalij Ruge **/ static int initial_guess_ipopt_cflag(OptData *optData, char* cflags) { if(!strcmp(cflags,"const") || !strcmp(cflags,"CONST")) { int i, j; const int nsi = optData->dim.nsi; const int np = optData->dim.np; const int nu = optData->dim.nu; const int nReal = optData->dim.nReal; for(i = 0; i< nu; ++i ) optData->data->simulationInfo->inputVars[i] = optData->bounds.u0[i]; for(i = 0; i < nsi; ++i){ for(j = 0; j < np; ++j){ memcpy(optData->v[i][j], optData->v0, nReal*sizeof(modelica_real)); } } infoStreamPrint(LOG_IPOPT, 0, "Using const trajectory as initial guess."); return 0; }else if(!strcmp(cflags,"sim") || !strcmp(cflags,"SIM")){ infoStreamPrint(LOG_IPOPT, 0, "Using simulation as initial guess."); return 1; }else if(!strcmp(cflags,"file") || !strcmp(cflags,"FILE")){ infoStreamPrint(LOG_STDOUT, 0, "Using values from file as initial guess."); return 2; } warningStreamPrint(LOG_STDOUT, 0, "not support ipopt_init=%s", cflags); return 1; }
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 check_nonlinear_solution * * This function checks if a non-linear system * is solved. Returns a warning and 1 in case it's not * solved otherwise 0. * * \param [in] [data] * \param [in] [printFailingSystems] * \param [in] [sysNumber] index of corresponding non-linear System * \param [out] [returnValue] Returns 1 if fail otherwise 0. * * \author wbraun */ int check_nonlinear_solution(DATA *data, int printFailingSystems, int sysNumber) { NONLINEAR_SYSTEM_DATA* nonlinsys = data->simulationInfo->nonlinearSystemData; long j; int i = sysNumber; if(nonlinsys[i].solved == 0) { int index = nonlinsys[i].equationIndex, indexes[2] = {1,index}; if (!printFailingSystems) return 1; warningStreamPrintWithEquationIndexes(LOG_NLS, 1, indexes, "nonlinear system %d fails: at t=%g", index, data->localData[0]->timeValue); if(data->simulationInfo->initial) { warningStreamPrint(LOG_NLS, 0, "proper start-values for some of the following iteration variables might help"); } for(j=0; j<modelInfoGetEquation(&data->modelData->modelDataXml, (nonlinsys[i]).equationIndex).numVar; ++j) { int done=0; long k; const MODEL_DATA *mData = data->modelData; for(k=0; k<mData->nVariablesReal && !done; ++k) { if (!strcmp(mData->realVarsData[k].info.name, modelInfoGetEquation(&data->modelData->modelDataXml, (nonlinsys[i]).equationIndex).vars[j])) { done = 1; warningStreamPrint(LOG_NLS, 0, "[%ld] Real %s(start=%g, nominal=%g)", j+1, mData->realVarsData[k].info.name, mData->realVarsData[k].attribute.start, mData->realVarsData[k].attribute.nominal); } } if (!done) { warningStreamPrint(LOG_NLS, 0, "[%ld] Real %s(start=?, nominal=?)", j+1, modelInfoGetEquation(&data->modelData->modelDataXml, (nonlinsys[i]).equationIndex).vars[j]); } } messageCloseWarning(LOG_NLS); return 1; } if(nonlinsys[i].solved == 2) { nonlinsys[i].solved = 1; return 2; } return 0; }
static inline void overwriteTimeGridFile(OptDataTime * time, char* filename, long double c[], const int np, const int nsi){ int i,k; long double dc[np]; const int np1 = np - 1; double t; FILE * pFile = NULL; pFile = fopen(filename,"r"); fscanf(pFile, "%lf", &t); time->t0 = t; fscanf(pFile, "%lf", &t); time->t[0][np1] = t; time->dt[0] = time->t[0][np1] - time->t0; if(time->dt[0] <= 0){ warningStreamPrint(LOG_STDOUT, 0, "read time grid from file fail!"); warningStreamPrint(LOG_STDOUT, 0, "line %i: %g <= %g",0, (double)time->t[0][np1], (double)time->t0); EXIT(0); } for(k = 0; k < np; ++k){ dc[k] = c[k]*time->dt[0]; time->t[0][k] = time->t0 + dc[k]; } for(i=1;i<nsi;++i){ fscanf(pFile, "%lf", &t); time->t[i][np1] = t; time->dt[i] = time->t[i][np1] - time->t[i-1][np1]; for(k = 0; k < np; ++k){ dc[k] = c[k]*time->dt[i]; time->t[i][k] = time->t[i-1][np1] + dc[k]; } if(time->dt[i] <= 0){ warningStreamPrint(LOG_STDOUT, 0, "read time grid"); warningStreamPrint(LOG_STDOUT, 0, "line %i/%i: %g <= %g",i, nsi, (double)time->t[i][np1], (double)time->t[i-1][np1]); warningStreamPrint(LOG_STDOUT, 0, "failed!"); EXIT(0); } } time->tf = time->t[nsi-1][np1]; fclose(pFile); }
static void nlsKinsolErrorPrint(int errorCode, const char *module, const char *function, char *msg, void *userData) { NLS_KINSOL_DATA *kinsolData = (NLS_KINSOL_DATA*) userData; DATA* data = kinsolData->userData.data; int sysNumber = kinsolData->userData.sysNumber; long eqSystemNumber = data->simulationInfo->nonlinearSystemData[sysNumber].equationIndex; if (ACTIVE_STREAM(LOG_NLS)) { warningStreamPrint(LOG_NLS, 1, "kinsol failed for %d", modelInfoGetEquation(&data->modelData->modelDataXml,eqSystemNumber).id); warningStreamPrint(LOG_NLS, 0, "[module] %s | [function] %s | [error_code] %d", module, function, errorCode); warningStreamPrint(LOG_NLS, 0, "%s", msg); messageClose(LOG_NLS); } }
static void fmtEmitStep(DATA* data, threadData_t *threadData, MEASURE_TIME* mt, int didEventStep) { if(mt->fmtReal) { int i, flag=1; double tmpdbl; unsigned int tmpint; int total = data->modelData->modelDataXml.nFunctions + data->modelData->modelDataXml.nProfileBlocks; rt_tick(SIM_TIMER_OVERHEAD); rt_accumulate(SIM_TIMER_STEP); /* Disable time measurements if we have trouble writing to the file... */ flag = flag && 1 == fwrite(&mt->stepNo, sizeof(unsigned int), 1, mt->fmtInt); mt->stepNo++; flag = flag && 1 == fwrite(&(data->localData[0]->timeValue), sizeof(double), 1, mt->fmtReal); tmpdbl = rt_accumulated(SIM_TIMER_STEP); flag = flag && 1 == fwrite(&tmpdbl, sizeof(double), 1, mt->fmtReal); flag = flag && total == fwrite(rt_ncall_arr(SIM_TIMER_FIRST_FUNCTION), sizeof(uint32_t), total, mt->fmtInt); for(i=0; i<data->modelData->modelDataXml.nFunctions + data->modelData->modelDataXml.nProfileBlocks; i++) { tmpdbl = rt_accumulated(i + SIM_TIMER_FIRST_FUNCTION); flag = flag && 1 == fwrite(&tmpdbl, sizeof(double), 1, mt->fmtReal); } rt_accumulate(SIM_TIMER_OVERHEAD); if(!flag) { warningStreamPrint(LOG_SOLVER, 0, "Disabled time measurements because the output file could not be generated: %s", strerror(errno)); fclose(mt->fmtInt); fclose(mt->fmtReal); mt->fmtInt = NULL; mt->fmtReal = NULL; } } /* prevent emit if noEventEmit flag is used, if it's an event */ if ((omc_flag[FLAG_NOEVENTEMIT] && didEventStep == 0) || !omc_flag[FLAG_NOEVENTEMIT]) { sim_result.emit(&sim_result, data, threadData); } #if !defined(OMC_MINIMAL_RUNTIME) embedded_server_update(data->embeddedServerState, data->localData[0]->timeValue); if (data->real_time_sync.enabled) { double time = data->localData[0]->timeValue; int64_t res = rt_ext_tp_sync_nanosec(&data->real_time_sync.clock, (uint64_t) (data->real_time_sync.scaling*(time-data->real_time_sync.time)*1e9)); int64_t maxLateNano = data->simulationInfo->stepSize*1e9*0.1*data->real_time_sync.scaling /* Maximum late time: 10% of step size */; if (res > maxLateNano) { int t=0,tMaxLate=0; const char *unit = prettyPrintNanoSec(res, &t); const char *unit2 = prettyPrintNanoSec(maxLateNano, &tMaxLate); errorStreamPrint(LOG_RT, 0, "Missed deadline at time %g; delta was %d %s (maxLate=%d %s)", time, t, unit, tMaxLate, unit2); } if (res > data->real_time_sync.maxLate) { data->real_time_sync.maxLate = res; } } printAllVarsDebug(data, 0, LOG_DEBUG); /* ??? */ #endif }
/*! \fn damping_heuristic * * first damping heuristic: * x_increment will be halved until the Euclidean norm of the residual function * is smaller than the Euclidean norm of the current point * * treshold for damping = 0.01 * compiler flag: -newton = damped */ void damping_heuristic(double* x, int(*f)(int*, double*, double*, void*, int), double current_fvec_enorm, int* n, double* fvec, double* lambda, int* k, DATA_NEWTON* solverData, void* userdata) { int i,j=0; double enorm_new, treshold = 1e-2; /* calculate new function values */ (*f)(n, solverData->x_new, fvec, userdata, 1); solverData->nfev++; enorm_new=enorm_(n,fvec); if (enorm_new >= current_fvec_enorm) infoStreamPrint(LOG_NLS_V, 1, "Start Damping: enorm_new : %e; current_fvec_enorm: %e ", enorm_new, current_fvec_enorm); while (enorm_new >= current_fvec_enorm) { j++; *lambda*=0.5; for (i=0; i<*n; i++) solverData->x_new[i]=x[i]-*lambda*solverData->x_increment[i]; /* calculate new function values */ (*f)(n, solverData->x_new, fvec, userdata, 1); solverData->nfev++; enorm_new=enorm_(n,fvec); if (*lambda <= treshold) { warningStreamPrint(LOG_NLS_V, 0, "Warning: lambda reached a threshold."); /* if damping is without success, trying full newton step; after 5 full newton steps try a very little step */ if (*k >= 5) for (i=0; i<*n; i++) solverData->x_new[i]=x[i]-*lambda*solverData->x_increment[i]; else for (i=0; i<*n; i++) solverData->x_new[i]=x[i]-solverData->x_increment[i]; /* calculate new function values */ (*f)(n, solverData->x_new, fvec, userdata, 1); solverData->nfev++; (*k)++; break; } } *lambda = 1; messageClose(LOG_NLS_V); }
/* finish sparse matrix, by fixing colprts */ static void finishSparseColPtr(SlsMat mat) { int i; /* finish matrix colptrs */ mat->colptrs[mat->N] = mat->NNZ; for(i=1; i<mat->N+1; ++i){ if (mat->colptrs[i] == 0){ warningStreamPrint(LOG_STDOUT, 0, "##KINSOL## Jac row %d singular. See LOG_NLS for more infomation.", i); mat->colptrs[i] = mat->colptrs[i-1]; } } }
static void retrySimulationStep(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo) { /* reduce step size by a half and try again */ solverInfo->laststep = solverInfo->currentTime - solverInfo->laststep; /* restore old values and try another step with smaller step-size by dassl*/ restoreOldValues(data); solverInfo->currentTime = data->localData[0]->timeValue; overwriteOldSimulationData(data); updateDiscreteSystem(data, threadData); warningStreamPrint(LOG_STDOUT, 0, "Integrator attempt to handle a problem with a called assert."); solverInfo->didEventStep = 1; }
/*! \fn solveLinearSystem * * function solves linear system J*(x_{n+1} - x_n) = f using lapack */ int solveLinearSystem(int* n, int* iwork, double* fvec, double *fjac, DATA_NEWTON* solverData) { int i, nrsh=1, lapackinfo; char trans = 'N'; /* if no factorization is given, calculate it */ if (solverData->factorization == 0) { /* solve J*(x_{n+1} - x_n)=f */ dgetrf_(n, n, fjac, n, iwork, &lapackinfo); solverData->factorization = 1; dgetrs_(&trans, n, &nrsh, fjac, n, iwork, fvec, n, &lapackinfo); } else { dgetrs_(&trans, n, &nrsh, fjac, n, iwork, fvec, n, &lapackinfo); } if(lapackinfo > 0) { warningStreamPrint(LOG_NLS, 0, "Jacobian Matrix singular!"); return -1; } else if(lapackinfo < 0) { warningStreamPrint(LOG_NLS, 0, "illegal input in argument %d", (int)lapackinfo); return -1; } else { /* save solution of J*(x_{n+1} - x_n)=f */ memcpy(solverData->x_increment, fvec, *n*sizeof(double)); } return 0; }
/*! \fn calculatingErrors * * function scales the residual vector using the jacobian (heuristic) */ void scaling_residual_vector(DATA_NEWTON* solverData) { int i,j,k; for(i=0, k=0; i<solverData->n; i++) { solverData->resScaling[i] = 0.0; for(j=0; j<solverData->n; j++, ++k) { solverData->resScaling[i] = fmax(fabs(solverData->fjac[k]), solverData->resScaling[i]); } if(solverData->resScaling[i] <= 0.0){ warningStreamPrint(LOG_NLS_V, 1, "Jacobian matrix is singular."); solverData->resScaling[i] = 1e-16; } solverData->fvecScaled[i] = solverData->fvec[i] / solverData->resScaling[i]; } }
/*! \fn check_mixed_solutions * This function checks whether some of the mixed systems * are failed to solve. If one is failed it returns 1 otherwise 0. * * \param [in] [data] * \param [in] [printFailingSystems] * * \author wbraun */ int check_mixed_solutions(DATA *data, int printFailingSystems) { MIXED_SYSTEM_DATA* system = data->simulationInfo->mixedSystemData; int i, j, retVal=0; for(i=0; i<data->modelData->nMixedSystems; ++i) if(system[i].solved == 0) { retVal = 1; if(printFailingSystems && ACTIVE_WARNING_STREAM(LOG_NLS)) { warningStreamPrint(LOG_NLS, 1, "mixed system fails: %d at t=%g", modelInfoGetEquation(&data->modelData->modelDataXml, system->equationIndex).id, data->localData[0]->timeValue); messageClose(LOG_NLS); } } return retVal; }
/*! \fn updateInnerEquation * * This function updates inner equation with the current x. * * \param [ref] [data] * [in] [sysNumber] index of corresponding non-linear system */ int updateInnerEquation(void **dataIn, int sysNumber, int discrete) { DATA *data = (DATA*) ((void**)dataIn[0]); threadData_t *threadData = (threadData_t*) ((void**)dataIn[1]); NONLINEAR_SYSTEM_DATA* nonlinsys = &(data->simulationInfo->nonlinearSystemData[sysNumber]); int success = 0; /* solve non continuous at discrete points*/ if(discrete) { data->simulationInfo->solveContinuous = 0; } /* try */ #ifndef OMC_EMCC MMC_TRY_INTERNAL(simulationJumpBuffer) #endif /* call residual function */ nonlinsys->residualFunc((void*) dataIn, nonlinsys->nlsx, nonlinsys->resValues, (int*)&nonlinsys->size); /* replace extrapolated values by current x for discrete step */ memcpy(nonlinsys->nlsxExtrapolation, nonlinsys->nlsx, nonlinsys->size*(sizeof(double))); success = 1; /*catch */ #ifndef OMC_EMCC MMC_CATCH_INTERNAL(simulationJumpBuffer) #endif if (!success) { warningStreamPrint(LOG_STDOUT, 0, "Non-Linear Solver try to handle a problem with a called assert."); } if(discrete) { data->simulationInfo->solveContinuous = 1; } return success; }
static void fmtEmitStep(DATA* data, threadData_t *threadData, MEASURE_TIME* mt, int didEventStep) { if(mt->fmtReal) { int i, flag=1; double tmpdbl; unsigned int tmpint; int total = data->modelData.modelDataXml.nFunctions + data->modelData.modelDataXml.nProfileBlocks; rt_tick(SIM_TIMER_OVERHEAD); rt_accumulate(SIM_TIMER_STEP); /* Disable time measurements if we have trouble writing to the file... */ flag = flag && 1 == fwrite(&mt->stepNo, sizeof(unsigned int), 1, mt->fmtInt); mt->stepNo++; flag = flag && 1 == fwrite(&(data->localData[0]->timeValue), sizeof(double), 1, mt->fmtReal); tmpdbl = rt_accumulated(SIM_TIMER_STEP); flag = flag && 1 == fwrite(&tmpdbl, sizeof(double), 1, mt->fmtReal); flag = flag && total == fwrite(rt_ncall_arr(SIM_TIMER_FIRST_FUNCTION), sizeof(uint32_t), total, mt->fmtInt); for(i=0; i<data->modelData.modelDataXml.nFunctions + data->modelData.modelDataXml.nProfileBlocks; i++) { tmpdbl = rt_accumulated(i + SIM_TIMER_FIRST_FUNCTION); flag = flag && 1 == fwrite(&tmpdbl, sizeof(double), 1, mt->fmtReal); } rt_accumulate(SIM_TIMER_OVERHEAD); if(!flag) { warningStreamPrint(LOG_SOLVER, 0, "Disabled time measurements because the output file could not be generated: %s", strerror(errno)); fclose(mt->fmtInt); fclose(mt->fmtReal); mt->fmtInt = NULL; mt->fmtReal = NULL; } } /* prevent emit if noEventEmit flag is used, if it's an event */ if ((omc_flag[FLAG_NOEVENTEMIT] && didEventStep == 0) || !omc_flag[FLAG_NOEVENTEMIT]) { sim_result.emit(&sim_result, data, threadData); } printAllVarsDebug(data, 0, LOG_DEBUG); /* ??? */ }
/*! \fn solve non-linear systems * * \param [in] [data] * \param [in] [sysNumber] index of corresponding non-linear system * * \author wbraun */ int solve_nonlinear_system(DATA *data, threadData_t *threadData, int sysNumber) { void *dataAndThreadData[2] = {data, threadData}; int success = 0, saveJumpState; NONLINEAR_SYSTEM_DATA* nonlinsys = &(data->simulationInfo.nonlinearSystemData[sysNumber]); struct dataNewtonAndHybrid *mixedSolverData; data->simulationInfo.currentNonlinearSystemIndex = sysNumber; /* enable to avoid division by zero */ data->simulationInfo.noThrowDivZero = 1; ((DATA*)data)->simulationInfo.solveContinuous = 1; rt_ext_tp_tick(&nonlinsys->totalTimeClock); if(data->simulationInfo.discreteCall) { double *fvec = malloc(sizeof(double)*nonlinsys->size); int success = 0; #ifndef OMC_EMCC /* try */ MMC_TRY_INTERNAL(simulationJumpBuffer) #endif ((DATA*)data)->simulationInfo.solveContinuous = 0; nonlinsys->residualFunc((void*) dataAndThreadData, nonlinsys->nlsx, fvec, (int*)&nonlinsys->size); ((DATA*)data)->simulationInfo.solveContinuous = 1; success = 1; #ifndef OMC_EMCC /*catch */ MMC_CATCH_INTERNAL(simulationJumpBuffer) #endif if (!success) { warningStreamPrint(LOG_STDOUT, 0, "Non-Linear Solver try to handle a problem with a called assert."); } free(fvec); }
int setLogFormat(int argc, char** argv) { const char* value = getOption(FLAG_NAME[FLAG_LOG_FORMAT], argc, argv); if (NULL == value) { value = getFlagValue(FLAG_NAME[FLAG_LOG_FORMAT], argc, argv); } if (NULL != value) { if (0 == strcmp(value, "xml")) { setStreamPrintXML(1); } else if (0 == strcmp(value, "xmltcp")) { setStreamPrintXML(2); } else if (0 == strcmp(value, "text")) { setStreamPrintXML(0); } else { warningStreamPrint(LOG_STDOUT, 0, "invalid command line option: -logFormat=%s, expected text, xml, or xmltcp", value); return 1; } } return 0; }
/* pick up information(nStates...) from model data to optimizer struct * author: Vitalij Ruge */ static inline void pickUpDim(OptDataDim * dim, DATA* data, OptDataTime * time){ char * cflags = NULL; cflags = (char*)omc_flagValue[FLAG_OPTIMIZER_NP]; if(cflags){ dim->np = atoi(cflags); if(dim->np != 1 && dim->np!=3){ warningStreamPrint(LOG_STDOUT, 0, "FLAG_OPTIZER_NP is %i. Currently optimizer support only 1 and 3.\nFLAG_OPTIZER_NP set of 3", dim->np); dim->np = 3; } }else dim->np = 3; /*ToDo*/ dim->nx = data->modelData.nStates; dim->nu = data->modelData.nInputVars; dim->nv = dim->nx + dim->nu; dim->nc = data->modelData.nOptimizeConstraints; dim->ncf = data->modelData.nOptimizeFinalConstraints; dim->nJ = dim->nx + dim->nc; dim->nJ2 = dim->nJ + 2; dim->nReal = data->modelData.nVariablesReal; cflags = (char*)omc_flagValue[FLAG_OPTIMIZER_TGRID]; data->callback->getTimeGrid(data, &dim->nsi, &time->tt); time->model_grid = (modelica_boolean)(dim->nsi > 0); if(!time->model_grid) dim->nsi = data->simulationInfo.numSteps; if(cflags) dim->nsi = getNsi(cflags, dim->nsi, &dim->exTimeGrid); dim->nt = dim->nsi*dim->np; dim->NV = dim->nt*dim->nv; dim->NRes = dim->nt*dim->nJ + dim->ncf; dim->index_con = dim->nReal - (dim->nc + dim->ncf); dim->index_conf = dim->index_con + dim->nc; assert(dim->nt > 0); }
int nlsKinsolSolve(DATA *data, threadData_t *threadData, int sysNumber) { NONLINEAR_SYSTEM_DATA *nlsData = &(data->simulationInfo->nonlinearSystemData[sysNumber]); NLS_KINSOL_DATA *kinsolData = (NLS_KINSOL_DATA*)nlsData->solverData; long eqSystemNumber = nlsData->equationIndex; int indexes[2] = {1,eqSystemNumber}; int flag, i; long nFEval; int success = 0; int retry = 0; double *xStart = NV_DATA_S(kinsolData->initialGuess); double *xScaling = NV_DATA_S(kinsolData->xScale); double *fScaling = NV_DATA_S(kinsolData->fScale); double fNormValue; /* set user data */ kinsolData->userData.data = data; kinsolData->userData.threadData = threadData; kinsolData->userData.sysNumber = sysNumber; /* reset configuration settings */ nlsKinsolConfigSetup(kinsolData); infoStreamPrint(LOG_NLS, 0, "------------------------------------------------------"); infoStreamPrintWithEquationIndexes(LOG_NLS, 1, indexes, "Start solving non-linear system >>%ld<< using Kinsol solver at time %g", eqSystemNumber, data->localData[0]->timeValue); nlsKinsolResetInitial(data, kinsolData, nlsData, INITIAL_EXTRAPOLATION); /* set x scaling */ nlsKinsolXScaling(data, kinsolData, nlsData, SCALING_NOMINALSTART); /* set f scaling */ _omc_fillVector(_omc_createVector(nlsData->size, fScaling), 1.); /* */ do{ /* dump configuration */ nlsKinsolConfigPrint(kinsolData, nlsData); flag = KINSol(kinsolData->kinsolMemory, /* KINSol memory block */ kinsolData->initialGuess, /* initial guess on input; solution vector */ kinsolData->kinsolStrategy, /* global strategy choice */ kinsolData->xScale, /* scaling vector, for the variable cc */ kinsolData->fScale); /* scaling vector for function values fval */ infoStreamPrint(LOG_NLS_V, 0, "KINSol finished with errorCode %d.", flag); /* check for errors */ if(flag < 0) { retry = nlsKinsolErrorHandler(flag, data, nlsData, kinsolData); } /* solution found */ if ((flag == KIN_SUCCESS) || (flag == KIN_INITIAL_GUESS_OK) || (flag == KIN_STEP_LT_STPTOL)) { success = 1; } kinsolData->retries++; /* write statistics */ KINGetNumNonlinSolvIters(kinsolData->kinsolMemory, &nFEval); nlsData->numberOfIterations += nFEval; nlsData->numberOfFEval += kinsolData->countResCalls; infoStreamPrint(LOG_NLS_V, 0, "Next try? success = %d, retry = %d, retries = %d = %s\n", success, retry, kinsolData->retries,!success && !(retry<1) && kinsolData->retries<RETRY_MAX ? "true" : "false" ); }while(!success && !(retry<0) && kinsolData->retries < RETRY_MAX); /* solution found */ if (success) { /* check if solution really solves the residuals */ nlsKinsolResiduals(kinsolData->initialGuess, kinsolData->fRes, &kinsolData->userData); fNormValue = N_VWL2Norm(kinsolData->fRes, kinsolData->fRes); infoStreamPrint(LOG_NLS, 0, "scaled Euclidean norm of F(u) = %e", fNormValue); if (FTOL_WITH_LESS_ACCURANCY<fNormValue) { warningStreamPrint(LOG_NLS, 0, "False positive solution. FNorm is too small."); success = 0; } else /* solved system for reuse linear solver information */ { kinsolData->solved = 1; } /* copy solution */ memcpy(nlsData->nlsx, xStart, nlsData->size*(sizeof(double))); /* dump solution */ if(ACTIVE_STREAM(LOG_NLS)) { infoStreamPrintWithEquationIndexes(LOG_NLS, 1, indexes, "solution for NLS %ld at t=%g", eqSystemNumber, kinsolData->userData.data->localData[0]->timeValue); for(i=0; i<nlsData->size; ++i) { infoStreamPrintWithEquationIndexes(LOG_NLS, 0, indexes, "[%d] %s = %g", i+1, modelInfoGetEquation(&kinsolData->userData.data->modelData->modelDataXml,eqSystemNumber).vars[i], nlsData->nlsx[i]); } messageClose(LOG_NLS); } } messageClose(LOG_NLS); return success; }
static int nlsKinsolErrorHandler(int errorCode, DATA *data, NONLINEAR_SYSTEM_DATA *nlsData, NLS_KINSOL_DATA *kinsolData) { int retValue, i, retValue2=0; double fNorm; double *xStart = NV_DATA_S(kinsolData->initialGuess); double *xScaling = NV_DATA_S(kinsolData->xScale); /* check what kind of error * retValue < 0 -> a non recoverable issue * retValue == 1 -> try with other settings */ KINSetNoInitSetup(kinsolData->kinsolMemory, FALSE); switch(errorCode) { case KIN_MEM_NULL: case KIN_ILL_INPUT: case KIN_NO_MALLOC: errorStreamPrint(LOG_NLS, 0, "kinsol has a serious memory issue ERROR %d\n", errorCode); return errorCode; break; /* just retry with new initial guess */ case KIN_MXNEWT_5X_EXCEEDED: warningStreamPrint(LOG_NLS, 0, "initial guess was too far away from the solution. Try again.\n"); return 1; break; /* just retry without line search */ case KIN_LINESEARCH_NONCONV: warningStreamPrint(LOG_NLS, 0, "kinsols line search did not convergence. Try without.\n"); kinsolData->kinsolStrategy = KIN_NONE; return 1; /* maybe happened because of an out-dated factorization, so just retry */ case KIN_LSETUP_FAIL: case KIN_LSOLVE_FAIL: warningStreamPrint(LOG_NLS, 0, "kinsols matrix need new factorization. Try again.\n"); KINKLUReInit(kinsolData->kinsolMemory, kinsolData->size, kinsolData->nnz, 2); return 1; case KIN_MAXITER_REACHED: case KIN_REPTD_SYSFUNC_ERR: warningStreamPrint(LOG_NLS, 0, "kinsols runs into issues retry with differnt configuration.\n"); retValue = 1; break; default: errorStreamPrint(LOG_STDOUT, 0, "kinsol has a serious solving issue ERROR %d\n", errorCode); return errorCode; break; } /* check if the current solution is sufficient anyway */ KINGetFuncNorm(kinsolData->kinsolMemory, &fNorm); if (fNorm<FTOL_WITH_LESS_ACCURANCY) { warningStreamPrint(LOG_NLS, 0, "Move forward with a less accurate solution."); KINSetFuncNormTol(kinsolData->kinsolMemory, FTOL_WITH_LESS_ACCURANCY); KINSetScaledStepTol(kinsolData->kinsolMemory, FTOL_WITH_LESS_ACCURANCY); retValue2 = 1; } else { warningStreamPrint(LOG_NLS, 0, "Current status of fx = %f", fNorm); } /* reconfigure kinsol for an other try */ if (retValue == 1 && !retValue2) { switch(kinsolData->retries) { case 0: /* try without x scaling */ nlsKinsolXScaling(data, kinsolData, nlsData, SCALING_ONES); break; case 1: /* try without line-search and oldValues */ nlsKinsolResetInitial(data, kinsolData, nlsData, INITIAL_OLDVALUES); kinsolData->kinsolStrategy = KIN_LINESEARCH; break; case 2: /* try without line-search and oldValues */ nlsKinsolResetInitial(data, kinsolData, nlsData, INITIAL_EXTRAPOLATION); kinsolData->kinsolStrategy = KIN_NONE; break; case 3: /* try with exact newton */ nlsKinsolXScaling(data, kinsolData, nlsData, SCALING_NOMINALSTART); nlsKinsolResetInitial(data, kinsolData, nlsData, INITIAL_EXTRAPOLATION); KINSetMaxSetupCalls(kinsolData->kinsolMemory, 1); kinsolData->kinsolStrategy = KIN_LINESEARCH; break; case 4: /* try with exact newton to with out x scaling values */ nlsKinsolXScaling(data, kinsolData, nlsData, SCALING_ONES); nlsKinsolResetInitial(data, kinsolData, nlsData, INITIAL_OLDVALUES); KINSetMaxSetupCalls(kinsolData->kinsolMemory, 1); kinsolData->kinsolStrategy = KIN_LINESEARCH; break; default: retValue = 0; break; } } return retValue+retValue2; }
/*! \fn solve non-linear system with hybrd method * * \param [in] [data] * [sysNumber] index of the corresponing non-linear system * * \author wbraun */ int solveHybrd(DATA *data, threadData_t *threadData, int sysNumber) { NONLINEAR_SYSTEM_DATA* systemData = &(data->simulationInfo->nonlinearSystemData[sysNumber]); DATA_HYBRD* solverData = (DATA_HYBRD*)systemData->solverData; /* * We are given the number of the non-linear system. * We want to look it up among all equations. */ int eqSystemNumber = systemData->equationIndex; int i, j; integer iflag = 1; double xerror, xerror_scaled; int success = 0; double local_tol = 1e-12; double initial_factor = solverData->factor; int nfunc_evals = 0; int continuous = 1; int nonContinuousCase = 0; int giveUp = 0; int retries = 0; int retries2 = 0; int retries3 = 0; int assertCalled = 0; int assertRetries = 0; int assertMessage = 0; modelica_boolean* relationsPreBackup; struct dataAndSys dataAndSysNumber = {data, threadData, sysNumber}; relationsPreBackup = (modelica_boolean*) malloc(data->modelData->nRelations*sizeof(modelica_boolean)); solverData->numberOfFunctionEvaluations = 0; /* debug output */ if(ACTIVE_STREAM(LOG_NLS_V)) { int indexes[2] = {1,eqSystemNumber}; infoStreamPrintWithEquationIndexes(LOG_NLS_V, 1, indexes, "start solving non-linear system >>%d<< at time %g", eqSystemNumber, data->localData[0]->timeValue); for(i=0; i<solverData->n; i++) { infoStreamPrint(LOG_NLS_V, 1, "%d. %s = %f", i+1, modelInfoGetEquation(&data->modelData->modelDataXml,eqSystemNumber).vars[i], systemData->nlsx[i]); infoStreamPrint(LOG_NLS_V, 0, " nominal = %f\nold = %f\nextrapolated = %f", systemData->nominal[i], systemData->nlsxOld[i], systemData->nlsxExtrapolation[i]); messageClose(LOG_NLS_V); } messageClose(LOG_NLS_V); } /* set x vector */ if(data->simulationInfo->discreteCall) memcpy(solverData->x, systemData->nlsx, solverData->n*(sizeof(double))); else memcpy(solverData->x, systemData->nlsxExtrapolation, solverData->n*(sizeof(double))); for(i=0; i<solverData->n; i++){ solverData->xScalefactors[i] = fmax(fabs(solverData->x[i]), systemData->nominal[i]); } /* start solving loop */ while(!giveUp && !success) { for(i=0; i<solverData->n; i++) solverData->xScalefactors[i] = fmax(fabs(solverData->x[i]), systemData->nominal[i]); /* debug output */ if(ACTIVE_STREAM(LOG_NLS_V)) { printVector(solverData->xScalefactors, &(solverData->n), LOG_NLS_V, "scaling factors x vector"); printVector(solverData->x, &(solverData->n), LOG_NLS_V, "Iteration variable values"); } /* Scaling x vector */ if(solverData->useXScaling) { for(i=0; i<solverData->n; i++) { solverData->x[i] = (1.0/solverData->xScalefactors[i]) * solverData->x[i]; } } /* debug output */ if(ACTIVE_STREAM(LOG_NLS_V)) { printVector(solverData->x, &solverData->n, LOG_NLS_V, "Iteration variable values (scaled)"); } /* set residual function continuous */ if(continuous) { ((DATA*)data)->simulationInfo->solveContinuous = 1; } else { ((DATA*)data)->simulationInfo->solveContinuous = 0; } giveUp = 1; /* try */ { int success = 0; #ifndef OMC_EMCC MMC_TRY_INTERNAL(simulationJumpBuffer) #endif hybrj_(wrapper_fvec_hybrj, &solverData->n, solverData->x, solverData->fvec, solverData->fjac, &solverData->ldfjac, &solverData->xtol, &solverData->maxfev, solverData->diag, &solverData->mode, &solverData->factor, &solverData->nprint, &solverData->info, &solverData->nfev, &solverData->njev, solverData->r__, &solverData->lr, solverData->qtf, solverData->wa1, solverData->wa2, solverData->wa3, solverData->wa4, (void*) &dataAndSysNumber); success = 1; if(assertCalled) { infoStreamPrint(LOG_NLS, 0, "After assertions failed, found a solution for which assertions did not fail."); /* re-scaling x vector */ for(i=0; i<solverData->n; i++){ if(solverData->useXScaling) systemData->nlsxOld[i] = solverData->x[i]*solverData->xScalefactors[i]; else systemData->nlsxOld[i] = solverData->x[i]; } } assertRetries = 0; assertCalled = 0; success = 1; #ifndef OMC_EMCC MMC_CATCH_INTERNAL(simulationJumpBuffer) #endif /* catch */ if (!success) { if (!assertMessage) { if (ACTIVE_WARNING_STREAM(LOG_STDOUT)) { if(data->simulationInfo->initial) warningStreamPrint(LOG_STDOUT, 1, "While solving non-linear system an assertion failed during initialization."); else warningStreamPrint(LOG_STDOUT, 1, "While solving non-linear system an assertion failed at time %g.", data->localData[0]->timeValue); warningStreamPrint(LOG_STDOUT, 0, "The non-linear solver tries to solve the problem that could take some time."); warningStreamPrint(LOG_STDOUT, 0, "It could help to provide better start-values for the iteration variables."); if (!ACTIVE_STREAM(LOG_NLS)) warningStreamPrint(LOG_STDOUT, 0, "For more information simulate with -lv LOG_NLS"); messageClose(LOG_STDOUT); } assertMessage = 1; } solverData->info = -1; xerror_scaled = 1; xerror = 1; assertCalled = 1; } } /* set residual function continuous */ if(continuous) { ((DATA*)data)->simulationInfo->solveContinuous = 0; } else { ((DATA*)data)->simulationInfo->solveContinuous = 1; } /* re-scaling x vector */ if(solverData->useXScaling) for(i=0; i<solverData->n; i++) solverData->x[i] = solverData->x[i]*solverData->xScalefactors[i]; /* check for proper inputs */ if(solverData->info == 0) { printErrorEqSyst(IMPROPER_INPUT, modelInfoGetEquation(&data->modelData->modelDataXml, eqSystemNumber), data->localData[0]->timeValue); } if(solverData->info != -1) { /* evaluate with discontinuities */ if(data->simulationInfo->discreteCall){ int scaling = solverData->useXScaling; int success = 0; if(scaling) solverData->useXScaling = 0; ((DATA*)data)->simulationInfo->solveContinuous = 0; /* try */ #ifndef OMC_EMCC MMC_TRY_INTERNAL(simulationJumpBuffer) #endif wrapper_fvec_hybrj(&solverData->n, solverData->x, solverData->fvec, solverData->fjac, &solverData->ldfjac, &iflag, (void*) &dataAndSysNumber); success = 1; #ifndef OMC_EMCC MMC_CATCH_INTERNAL(simulationJumpBuffer) #endif /* catch */ if (!success) { warningStreamPrint(LOG_STDOUT, 0, "Non-Linear Solver try to handle a problem with a called assert."); solverData->info = -1; xerror_scaled = 1; xerror = 1; assertCalled = 1; } if(scaling) solverData->useXScaling = 1; updateRelationsPre(data); } } if(solverData->info != -1) { /* scaling residual vector */ { int l=0; for(i=0; i<solverData->n; i++){ solverData->resScaling[i] = 1e-16; for(j=0; j<solverData->n; j++){ solverData->resScaling[i] = (fabs(solverData->fjacobian[l]) > solverData->resScaling[i]) ? fabs(solverData->fjacobian[l]) : solverData->resScaling[i]; l++; } solverData->fvecScaled[i] = solverData->fvec[i] * (1 / solverData->resScaling[i]); } /* debug output */ if(ACTIVE_STREAM(LOG_NLS_V)) { infoStreamPrint(LOG_NLS_V, 1, "scaling factors for residual vector"); for(i=0; i<solverData->n; i++) { infoStreamPrint(LOG_NLS_V, 1, "scaled residual [%d] : %.20e", i, solverData->fvecScaled[i]); infoStreamPrint(LOG_NLS_V, 0, "scaling factor [%d] : %.20e", i, solverData->resScaling[i]); messageClose(LOG_NLS_V); } messageClose(LOG_NLS_V); } /* debug output */ if(ACTIVE_STREAM(LOG_NLS_JAC)) { char buffer[4096]; infoStreamPrint(LOG_NLS_JAC, 1, "jacobian matrix [%dx%d]", (int)solverData->n, (int)solverData->n); for(i=0; i<solverData->n; i++) { buffer[0] = 0; for(j=0; j<solverData->n; j++) sprintf(buffer, "%s%10g ", buffer, solverData->fjacobian[i*solverData->n+j]); infoStreamPrint(LOG_NLS_JAC, 0, "%s", buffer); } messageClose(LOG_NLS_JAC); } /* check for error */ xerror_scaled = enorm_(&solverData->n, solverData->fvecScaled); xerror = enorm_(&solverData->n, solverData->fvec); } } /* reset non-contunuousCase */ if(nonContinuousCase && xerror > local_tol && xerror_scaled > local_tol) { memcpy(data->simulationInfo->relationsPre, relationsPreBackup, sizeof(modelica_boolean)*data->modelData->nRelations); nonContinuousCase = 0; } if(solverData->info < 4 && xerror > local_tol && xerror_scaled > local_tol) solverData->info = 4; /* solution found */ if(solverData->info == 1 || xerror <= local_tol || xerror_scaled <= local_tol) { int scaling; success = 1; nfunc_evals += solverData->nfev; if(ACTIVE_STREAM(LOG_NLS)) { int indexes[2] = {1,eqSystemNumber}; /* output solution */ infoStreamPrintWithEquationIndexes(LOG_NLS, 1, indexes, "solution for NLS %d at t=%g", eqSystemNumber, data->localData[0]->timeValue); for(i=0; i<solverData->n; ++i) { infoStreamPrint(LOG_NLS, 0, "[%d] %s = %g", i+1, modelInfoGetEquation(&data->modelData->modelDataXml,eqSystemNumber).vars[i], solverData->x[i]); } messageClose(LOG_NLS); }else if (ACTIVE_STREAM(LOG_NLS_V)){ infoStreamPrint(LOG_NLS_V, 1, "system solved"); infoStreamPrint(LOG_NLS_V, 0, "%d retries\n%d restarts", retries, retries2+retries3); messageClose(LOG_NLS_V); printStatus(data, solverData, eqSystemNumber, &nfunc_evals, &xerror, &xerror_scaled, LOG_NLS_V); } scaling = solverData->useXScaling; if(scaling) solverData->useXScaling = 0; /* take the solution */ memcpy(systemData->nlsx, solverData->x, solverData->n*(sizeof(double))); /* try */ { int success = 0; #ifndef OMC_EMCC MMC_TRY_INTERNAL(simulationJumpBuffer) #endif wrapper_fvec_hybrj(&solverData->n, solverData->x, solverData->fvec, solverData->fjac, &solverData->ldfjac, &iflag, (void*) &dataAndSysNumber); success = 1; #ifndef OMC_EMCC MMC_CATCH_INTERNAL(simulationJumpBuffer) #endif /* catch */ if (!success) { warningStreamPrint(LOG_STDOUT, 0, "Non-Linear Solver try to handle a problem with a called assert."); solverData->info = 4; xerror_scaled = 1; xerror = 1; assertCalled = 1; success = 0; giveUp = 0; } } if(scaling) solverData->useXScaling = 1; }
/*! \fn solve linear system with lapack method * * \param [in] [data] * [sysNumber] index of the corresponding linear system * * \author wbraun */ int solveLapack(DATA *data, int sysNumber) { int i, j, iflag = 1; LINEAR_SYSTEM_DATA* systemData = &(data->simulationInfo.linearSystemData[sysNumber]); DATA_LAPACK* solverData = (DATA_LAPACK*)systemData->solverData; int success = 1; /* We are given the number of the linear system. * We want to look it up among all equations. */ int eqSystemNumber = systemData->equationIndex; int indexes[2] = {1,eqSystemNumber}; _omc_scalar residualNorm = 0; infoStreamPrintWithEquationIndexes(LOG_LS, 0, indexes, "Start solving Linear System %d (size %d) at time %g with Lapack Solver", eqSystemNumber, (int) systemData->size, data->localData[0]->timeValue); /* set data */ _omc_setVectorData(solverData->x, systemData->x); _omc_setVectorData(solverData->b, systemData->b); _omc_setMatrixData(solverData->A, systemData->A); rt_ext_tp_tick(&(solverData->timeClock)); if (0 == systemData->method) { /* reset matrix A */ memset(systemData->A, 0, (systemData->size)*(systemData->size)*sizeof(double)); /* update matrix A */ systemData->setA(data, systemData); /* update vector b (rhs) */ systemData->setb(data, systemData); } else { /* calculate jacobian -> matrix A*/ if(systemData->jacobianIndex != -1){ getAnalyticalJacobianLapack(data, solverData->A->data, sysNumber); } else { assertStreamPrint(data->threadData, 1, "jacobian function pointer is invalid" ); } /* calculate vector b (rhs) */ _omc_copyVector(solverData->work, solverData->x); wrapper_fvec_lapack(solverData->work, solverData->b, &iflag, data, sysNumber); } infoStreamPrint(LOG_LS, 0, "### %f time to set Matrix A and vector b.", rt_ext_tp_tock(&(solverData->timeClock))); /* Log A*x=b */ if(ACTIVE_STREAM(LOG_LS_V)){ _omc_printVector(solverData->x, "Vector old x", LOG_LS_V); _omc_printMatrix(solverData->A, "Matrix A", LOG_LS_V); _omc_printVector(solverData->b, "Vector b", LOG_LS_V); } rt_ext_tp_tick(&(solverData->timeClock)); /* Solve system */ dgesv_((int*) &systemData->size, (int*) &solverData->nrhs, solverData->A->data, (int*) &systemData->size, solverData->ipiv, solverData->b->data, (int*) &systemData->size, &solverData->info); infoStreamPrint(LOG_LS, 0, "Solve System: %f", rt_ext_tp_tock(&(solverData->timeClock))); if(solverData->info < 0) { warningStreamPrint(LOG_LS, 0, "Error solving linear system of equations (no. %d) at time %f. Argument %d illegal.", (int)systemData->equationIndex, data->localData[0]->timeValue, (int)solverData->info); success = 0; } else if(solverData->info > 0) { warningStreamPrint(LOG_LS, 0, "Failed to solve linear system of equations (no. %d) at time %f, system is singular for U[%d, %d].", (int)systemData->equationIndex, data->localData[0]->timeValue, (int)solverData->info+1, (int)solverData->info+1); success = 0; /* debug output */ if (ACTIVE_STREAM(LOG_LS)){ _omc_printMatrix(solverData->A, "Matrix U", LOG_LS); _omc_printVector(solverData->b, "Output vector x", LOG_LS); } } if (1 == success){ if (1 == systemData->method){ /* take the solution */ solverData->x = _omc_addVectorVector(solverData->x, solverData->work, solverData->b); /* update inner equations */ wrapper_fvec_lapack(solverData->x, solverData->work, &iflag, data, sysNumber); residualNorm = _omc_euclideanVectorNorm(solverData->work); } else { /* take the solution */ _omc_copyVector(solverData->x, solverData->b); } if (ACTIVE_STREAM(LOG_LS_V)){ infoStreamPrint(LOG_LS_V, 1, "Residual Norm %f of solution x:", residualNorm); infoStreamPrint(LOG_LS_V, 0, "System %d numVars %d.", eqSystemNumber, modelInfoGetEquation(&data->modelData.modelDataXml,eqSystemNumber).numVar); for(i = 0; i < systemData->size; ++i) { infoStreamPrint(LOG_LS_V, 0, "[%d] %s = %g", i+1, modelInfoGetEquation(&data->modelData.modelDataXml,eqSystemNumber).vars[i], systemData->x[i]); } messageClose(LOG_LS_V); } } return success; }
/*! \fn solve linear system with UmfPack method * * \param [in] [data] * [sysNumber] index of the corresponding linear system * * * author: kbalzereit, wbraun */ int solveUmfPack(DATA *data, int sysNumber) { LINEAR_SYSTEM_DATA* systemData = &(data->simulationInfo.linearSystemData[sysNumber]); DATA_UMFPACK* solverData = (DATA_UMFPACK*)systemData->solverData; int i, j, status = UMFPACK_OK, success = 0, ni=0, n = systemData->size, eqSystemNumber = systemData->equationIndex, indexes[2] = {1,eqSystemNumber}; infoStreamPrintWithEquationIndexes(LOG_LS, 0, indexes, "Start solving Linear System %d (size %d) at time %g with UMFPACK Solver", eqSystemNumber, (int) systemData->size, data->localData[0]->timeValue); rt_ext_tp_tick(&(solverData->timeClock)); if (0 == systemData->method) { /* set A matrix */ solverData->Ap[0] = 0; systemData->setA(data, systemData); solverData->Ap[solverData->n_row] = solverData->nnz; if (ACTIVE_STREAM(LOG_LS_V)) { infoStreamPrint(LOG_LS_V, 1, "Matrix A"); printMatrixCSR(solverData->Ap, solverData->Ai, solverData->Ax, n); messageClose(LOG_LS_V); } /* set b vector */ systemData->setb(data, systemData); } else { solverData->Ap[0] = 0; /* calculate jacobian -> matrix A*/ if(systemData->jacobianIndex != -1) { getAnalyticalJacobianUmfPack(data, sysNumber); } else { assertStreamPrint(data->threadData, 1, "jacobian function pointer is invalid" ); } solverData->Ap[solverData->n_row] = solverData->nnz; /* calculate vector b (rhs) */ memcpy(solverData->work, systemData->x, sizeof(double)*solverData->n_row); wrapper_fvec_umfpack(solverData->work, systemData->b, data, sysNumber); } infoStreamPrint(LOG_LS, 0, "### %f time to set Matrix A and vector b.", rt_ext_tp_tock(&(solverData->timeClock))); if (ACTIVE_STREAM(LOG_LS_V)) { if (ACTIVE_STREAM(LOG_LS_V)) { infoStreamPrint(LOG_LS_V, 1, "Old solution x:"); for(i = 0; i < solverData->n_row; ++i) infoStreamPrint(LOG_LS_V, 0, "[%d] %s = %g", i+1, modelInfoGetEquation(&data->modelData.modelDataXml,eqSystemNumber).vars[i], systemData->x[i]); messageClose(LOG_LS_V); } infoStreamPrint(LOG_LS_V, 1, "Matrix A n_rows = %d", solverData->n_row); for (i=0; i<solverData->n_row; i++) { infoStreamPrint(LOG_LS_V, 0, "%d. Ap => %d -> %d", i, solverData->Ap[i], solverData->Ap[i+1]); for (j=solverData->Ap[i]; j<solverData->Ap[i+1]; j++) { infoStreamPrint(LOG_LS_V, 0, "A[%d,%d] = %f", i, solverData->Ai[j], solverData->Ax[j]); } } messageClose(LOG_LS_V); for (i=0; i<solverData->n_row; i++) infoStreamPrint(LOG_LS_V, 0, "b[%d] = %e", i, systemData->b[i]); } rt_ext_tp_tick(&(solverData->timeClock)); /* symbolic pre-ordering of A to reduce fill-in of L and U */ if (0 == solverData->numberSolving) { status = umfpack_di_symbolic(solverData->n_col, solverData->n_row, solverData->Ap, solverData->Ai, solverData->Ax, &(solverData->symbolic), solverData->control, solverData->info); } /* compute the LU factorization of A */ if (0 == status) { status = umfpack_di_numeric(solverData->Ap, solverData->Ai, solverData->Ax, solverData->symbolic, &(solverData->numeric), solverData->control, solverData->info); } if (0 == status) { if (1 == systemData->method) { status = umfpack_di_solve(UMFPACK_A, solverData->Ap, solverData->Ai, solverData->Ax, systemData->x, systemData->b, solverData->numeric, solverData->control, solverData->info); } else { status = umfpack_di_solve(UMFPACK_Aat, solverData->Ap, solverData->Ai, solverData->Ax, systemData->x, systemData->b, solverData->numeric, solverData->control, solverData->info); } } if (status == UMFPACK_OK) { success = 1; } else if (status == UMFPACK_WARNING_singular_matrix) { if (!solveSingularSystem(systemData)) { success = 1; } } infoStreamPrint(LOG_LS, 0, "Solve System: %f", rt_ext_tp_tock(&(solverData->timeClock))); /* print solution */ if (1 == success) { if (1 == systemData->method) { /* take the solution */ for(i = 0; i < solverData->n_row; ++i) systemData->x[i] += solverData->work[i]; /* update inner equations */ wrapper_fvec_umfpack(systemData->x, solverData->work, data, sysNumber); } else { /* the solution is automatically in x */ } if (ACTIVE_STREAM(LOG_LS_V)) { infoStreamPrint(LOG_LS_V, 1, "Solution x:"); infoStreamPrint(LOG_LS_V, 0, "System %d numVars %d.", eqSystemNumber, modelInfoGetEquation(&data->modelData.modelDataXml,eqSystemNumber).numVar); for(i = 0; i < systemData->size; ++i) infoStreamPrint(LOG_LS_V, 0, "[%d] %s = %g", i+1, modelInfoGetEquation(&data->modelData.modelDataXml,eqSystemNumber).vars[i], systemData->x[i]); messageClose(LOG_LS_V); } } else { warningStreamPrint(LOG_STDOUT, 0, "Failed to solve linear system of equations (no. %d) at time %f, system status %d.", (int)systemData->equationIndex, data->localData[0]->timeValue, status); } solverData->numberSolving += 1; return success; }
/*! \fn stateSelection * * function to select the actual states * * \param [ref] [data] * \param [in] [reportError] * \param [in] [switchStates] flag for switch states, function does switch only if this switchStates = 1 * \return ??? * * \author Frenkel TUD */ int stateSelection(DATA *data, threadData_t *threadData, char reportError, int switchStates) { TRACE_PUSH long i=0; long j=0; int globalres=0; long k=0; long l=0; /* go through all the state sets */ for(i=0; i<data->modelData->nStateSets; i++) { int res=0; STATE_SET_DATA *set = &(data->simulationInfo->stateSetData[i]); modelica_integer* oldColPivot = (modelica_integer*) malloc(set->nCandidates * sizeof(modelica_integer)); modelica_integer* oldRowPivot = (modelica_integer*) malloc(set->nDummyStates * sizeof(modelica_integer)); /* debug */ if(ACTIVE_STREAM(LOG_DSS)) { infoStreamPrint(LOG_DSS, 1, "StateSelection Set %ld. Select %ld states from %ld candidates.", i, set->nStates, set->nCandidates); for(k=0; k < set->nCandidates; k++) { infoStreamPrint(LOG_DSS, 0, "[%ld] cadidate %s", k+1, set->statescandidates[k]->name); } messageClose(LOG_DSS); infoStreamPrint(LOG_DSS, 0, "StateSelection Matrix A"); { unsigned int aid = set->A->id - data->modelData->integerVarsData[0].info.id; modelica_integer *Adump = &(data->localData[0]->integerVars[aid]); for(k=0; k < set->nCandidates; k++) { for(l=0; l < set->nStates; l++) { infoStreamPrint(LOG_DSS, 0, "A[%ld,%ld] = %ld", k+1, l+1, Adump[k*set->nCandidates+l]); } } } } /* generate jacobian, stored in set->J */ getAnalyticalJacobianSet(data, threadData, i); /* call pivoting function to select the states */ memcpy(oldColPivot, set->colPivot, set->nCandidates*sizeof(modelica_integer)); memcpy(oldRowPivot, set->rowPivot, set->nDummyStates*sizeof(modelica_integer)); if((pivot(set->J, set->nDummyStates, set->nCandidates, set->rowPivot, set->colPivot) != 0) && reportError) { /* error, report the matrix and the time */ char *buffer = (char*)malloc(sizeof(char)*data->simulationInfo->analyticJacobians[set->jacobianIndex].sizeCols*10); warningStreamPrint(LOG_DSS, 1, "jacobian %dx%d [id: %ld]", data->simulationInfo->analyticJacobians[set->jacobianIndex].sizeRows, data->simulationInfo->analyticJacobians[set->jacobianIndex].sizeCols, set->jacobianIndex); for(i=0; i < data->simulationInfo->analyticJacobians[set->jacobianIndex].sizeRows; i++) { buffer[0] = 0; for(j=0; j < data->simulationInfo->analyticJacobians[set->jacobianIndex].sizeCols; j++) sprintf(buffer, "%s%.5e ", buffer, set->J[i*data->simulationInfo->analyticJacobians[set->jacobianIndex].sizeCols+j]); warningStreamPrint(LOG_DSS, 0, "%s", buffer); } free(buffer); for(i=0; i<set->nCandidates; i++) warningStreamPrint(LOG_DSS, 0, "%s", set->statescandidates[i]->name); messageClose(LOG_DSS); throwStreamPrint(threadData, "Error, singular Jacobian for dynamic state selection at time %f\nUse -lv LOG_DSS_JAC to get the Jacobian", data->localData[0]->timeValue); } /* if we have a new set throw event for reinitialization and set the A matrix for set.x=A*(states) */ res = comparePivot(oldColPivot, set->colPivot, set->nCandidates, set->nDummyStates, set->nStates, set->A, set->states, set->statescandidates, data, switchStates); if(!switchStates) { memcpy(set->colPivot, oldColPivot, set->nCandidates*sizeof(modelica_integer)); memcpy(set->rowPivot, oldRowPivot, set->nDummyStates*sizeof(modelica_integer)); } if(res) globalres = 1; free(oldColPivot); free(oldRowPivot); } TRACE_POP return globalres; }
/*! * run optimization with ipopt * author: Vitalij Ruge **/ static inline void optimizationWithIpopt(OptData*optData) { IpoptProblem nlp = NULL; const int NV = optData->dim.NV; const int NRes = optData->dim.NRes; const int nsi = optData->dim.nsi; const int np = optData->dim.np; const int nx = optData->dim.nx; const int NJ = optData->dim.nJderx; const int NJf = optData->dim.nJfderx; const int nH0 = optData->dim.nH0_; const int nH1 = optData->dim.nH1_; const int njac = np*(NJ*nsi + nx*(np*nsi - 1)) + NJf; const int nhess = (nsi*np-1)*nH0+nH1; Number * Vmin = optData->bounds.Vmin; Number * Vmax = optData->bounds.Vmax; Number * gmin = optData->ipop.gmin; Number * gmax = optData->ipop.gmax; Number * vopt = optData->ipop.vopt; Number * mult_g = optData->ipop.mult_g; Number * mult_x_L = optData->ipop.mult_x_L; Number * mult_x_U = optData->ipop.mult_x_U; Number obj; char *cflags; int max_iter = 5000; int res = 0; nlp = CreateIpoptProblem(NV, Vmin, Vmax, NRes, gmin, gmax, njac, nhess, 0, &evalfF, &evalfG, &evalfDiffF, &evalfDiffG, &ipopt_h); /********************************************************************/ /******************* ipopt flags ************************/ /********************************************************************/ /*tol */ AddIpoptNumOption(nlp, "tol", optData->data->simulationInfo.tolerance); AddIpoptStrOption(nlp, "evaluate_orig_obj_at_resto_trial", "yes"); /* print level */ if(ACTIVE_STREAM(LOG_IPOPT_FULL)) { AddIpoptIntOption(nlp, "print_level", 7); } else if(ACTIVE_STREAM(LOG_IPOPT)) { AddIpoptIntOption(nlp, "print_level", 5); } else if(ACTIVE_STREAM(LOG_STATS)) { AddIpoptIntOption(nlp, "print_level", 3); } else { AddIpoptIntOption(nlp, "print_level", 2); } AddIpoptIntOption(nlp, "file_print_level", 0); /* derivative_test */ if(ACTIVE_STREAM(LOG_IPOPT_JAC) && ACTIVE_STREAM(LOG_IPOPT_HESSE)) { AddIpoptIntOption(nlp, "print_level", 4); AddIpoptStrOption(nlp, "derivative_test", "second-order"); } else if(ACTIVE_STREAM(LOG_IPOPT_JAC)) { AddIpoptIntOption(nlp, "print_level", 4); AddIpoptStrOption(nlp, "derivative_test", "first-order"); } else if(ACTIVE_STREAM(LOG_IPOPT_HESSE)) { AddIpoptIntOption(nlp, "print_level", 4); AddIpoptStrOption(nlp, "derivative_test", "only-second-order"); } else { AddIpoptStrOption(nlp, "derivative_test", "none"); } cflags = (char*)omc_flagValue[FLAG_IPOPT_HESSE]; if(cflags) { if(!strcmp(cflags,"BFGS")) AddIpoptStrOption(nlp, "hessian_approximation", "limited-memory"); else if(!strcmp(cflags,"const") || !strcmp(cflags,"CONST")) AddIpoptStrOption(nlp, "hessian_constant", "yes"); else if(!(!strcmp(cflags,"num") || !strcmp(cflags,"NUM"))) warningStreamPrint(LOG_STDOUT, 0, "not support ipopt_hesse=%s",cflags); } /*linear_solver e.g. mumps, MA27, MA57,... * be sure HSL solver are installed if your try HSL solver*/ cflags = (char*)omc_flagValue[FLAG_LS_IPOPT]; if(cflags) AddIpoptStrOption(nlp, "linear_solver", cflags); AddIpoptNumOption(nlp,"mumps_pivtolmax",1e-5); /* max iter */ cflags = (char*)omc_flagValue[FLAG_IPOPT_MAX_ITER]; if(cflags) { char buffer[100]; char c; int index_e = -1, i = 0; strcpy(buffer,cflags); while(buffer[i] != '\0') { if(buffer[i] == 'e') { index_e = i; break; } ++i; } if(index_e < 0) { max_iter = atoi(cflags); if(max_iter >= 0) AddIpoptIntOption(nlp, "max_iter", max_iter); printf("\nmax_iter = %i",atoi(cflags)); } else { max_iter = (atoi(cflags)*pow(10.0, (double)atoi(cflags+index_e+1))); if(max_iter >= 0) AddIpoptIntOption(nlp, "max_iter", (int)max_iter); printf("\nmax_iter = (int) %i | (double) %g",(int)max_iter, atoi(cflags)*pow(10.0, (double)atoi(cflags+index_e+1))); } } else AddIpoptIntOption(nlp, "max_iter", 5000); /*heuristic optition */ { int ws = 0; cflags = (char*)omc_flagValue[FLAG_IPOPT_WARM_START]; if(cflags) { ws = atoi(cflags); } if(ws > 0) { double shift = pow(10,-1.0*ws); AddIpoptNumOption(nlp,"mu_init",shift); AddIpoptNumOption(nlp,"bound_mult_init_val",shift); AddIpoptStrOption(nlp,"mu_strategy", "monotone"); AddIpoptNumOption(nlp,"bound_push", 1e-5); AddIpoptNumOption(nlp,"bound_frac", 1e-5); AddIpoptNumOption(nlp,"slack_bound_push", 1e-5); AddIpoptNumOption(nlp,"constr_mult_init_max", 1e-5); AddIpoptStrOption(nlp,"bound_mult_init_method","mu-based"); } else { AddIpoptStrOption(nlp,"mu_strategy","adaptive"); AddIpoptStrOption(nlp,"bound_mult_init_method","constant"); } AddIpoptStrOption(nlp,"fixed_variable_treatment","make_parameter"); AddIpoptStrOption(nlp,"dependency_detection_with_rhs","yes"); AddIpoptNumOption(nlp,"nu_init",1e-9); AddIpoptNumOption(nlp,"eta_phi",1e-10); } /********************************************************************/ if(max_iter >=0) { optData->iter_ = 0.0; optData->index = 1; res = IpoptSolve(nlp, vopt, NULL, &obj, mult_g, mult_x_L, mult_x_U, (void*)optData); } if(res != 0 && !ACTIVE_STREAM(LOG_IPOPT)) warningStreamPrint(LOG_STDOUT, 0, "No optimal solution found!\nUse -lv=LOG_IPOPT for more information."); FreeIpoptProblem(nlp); }
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)); data->simulationInfo->currentContext = CONTEXT_ALGEBRAIC; /* ### start configuration of dassl ### */ infoStreamPrint(LOG_SOLVER, 1, "Configuration of the dassl code:"); printf("---------------###---------------\n\n"); printf("Some stats:\n\n"); printf("(A) Firstly, we consider some info of the object DATA *data:\n"); printf("(1) SIMULATION_INFO (*simulationInfo):\n"); printf("\tstartTime: %f\n", data->simulationInfo->startTime); printf("\tstopTime: %f\n", data->simulationInfo->stopTime); printf("\tnumSteps: %d\n", data->simulationInfo->numSteps); printf("\ttolerance: %f\n", data->simulationInfo->tolerance); printf("\ttolerance: %f\n", (*(*data).simulationInfo).tolerance); printf("\t*solverMethod: %c\n", *(data->simulationInfo->solverMethod)); printf("\t*outputFormat: %c\n", *(data->simulationInfo->outputFormat)); printf("\t*variableFilter: %c\n", *(data->simulationInfo->variableFilter)); printf("\tlsMethod: %d\n", data->simulationInfo->lsMethod); printf("\tmixedMethod: %d\n", data->simulationInfo->mixedMethod); printf("\tnlsMethod: %d\n", data->simulationInfo->nlsMethod); printf("\tnewtonStrategy: %d\n", data->simulationInfo->newtonStrategy); printf("\tnlsCsvInfomation: %d\n", data->simulationInfo->nlsCsvInfomation); printf("\tcurrentContext: %d\n", data->simulationInfo->currentContext); printf("\tcurrentContextOld: %d\n", data->simulationInfo->currentContextOld); printf("\tjacobianEvals: %d\n", data->simulationInfo->jacobianEvals); printf("\tlambda: %d\n", data->simulationInfo->lambda); printf("\tnextSampleEvent: %f\n", data->simulationInfo->nextSampleEvent); printf("\tnextSampleTimes[0]: %f\n", data->simulationInfo->nextSampleTimes[0]); printf("\tnextSampleTimes[1]: %f\n", data->simulationInfo->nextSampleTimes[1]); printf("\tnextSampleTimes[2]: %f\n", data->simulationInfo->nextSampleTimes[2]); printf("\n\tThere are even more although I believe they will not be useful for now.\n\n"); printf("(2) SIMULATION_DATA (**localData):\n"); printf("\ttimeValue: %f\n", data->localData[0]->timeValue); printf("The following are the initial values.\n"); printf("\trealVars[0]: %f\n", data->localData[0]->realVars[0]); printf("\trealVars[1]: %f\n", data->localData[0]->realVars[1]); printf("\tintegerVars: %d\n", data->localData[0]->integerVars[1]); printf("\t*booleanVars: %s\n", *(data->localData[0]->booleanVars)); printf("\t*stringVars: %s\n", *(data->localData[0]->stringVars)); //printf("\t*inlineVars: %f\n", *(data->localData[0]->inlineVars)); //Errors when attempting to print this one. Not sure why though. printf("\n\tI am not sure this garbage struct is necessary. One \'timeValue\' is used. I am sure we can use a local variable or a similar route.\n\n"); printf("(3) MODEL_DATA (*modelData):\n"); printf("\trealVarsData[0].attribute.nominal: %f\n", data->modelData->realVarsData[0].attribute.nominal); printf("\trealVarsData[1].attribute.nominal: %f\n", data->modelData->realVarsData[1].attribute.nominal); printf("\trealVarsData[0].attribute.useStart: %s\n", data->modelData->realVarsData[0].attribute.useStart ? "true" : "false"); printf("\trealVarsData[1].attribute.useStart: %s\n", data->modelData->realVarsData[1].attribute.useStart ? "true" : "false"); printf("\tnStates: %d\n", data->modelData->nStates); printf("\tnVariablesReal: %d\n", data->modelData->nVariablesReal); printf("\tnDiscreteReal: %d\n", data->modelData->nDiscreteReal); printf("\tnVariablesInteger: %d\n", data->modelData->nVariablesInteger); printf("\tnVariablesBoolean: %d\n", data->modelData->nVariablesBoolean); printf("\tnVariablesString: %d\n", data->modelData->nVariablesString); printf("\tnParametersReal: %d\n", data->modelData->nParametersReal); printf("\tnVariablesReal: %d\n", data->modelData->nVariablesReal); printf("\tnParametersInteger: %d\n", data->modelData->nParametersInteger); printf("\tnParametersBoolean: %d\n", data->modelData->nParametersBoolean); printf("\tnParametersString: %d\n", data->modelData->nParametersString); printf("\tnInputVars: %d\n", data->modelData->nInputVars); printf("\tnOutputVars: %d\n", data->modelData->nOutputVars); printf("\tnZeroCrossings: %d\n", data->modelData->nZeroCrossings); printf("\tnMathEvents: %d\n", data->modelData->nMathEvents); printf("\tnDelayExpressions: %d\n", data->modelData->nDelayExpressions); printf("\tnExtObjs: %d\n", data->modelData->nExtObjs); printf("\tnMixedSystems: %d\n", data->modelData->nMixedSystems); printf("\tnLinearSystems: %d\n", data->modelData->nLinearSystems); printf("\tnNonLinearSystems: %d\n", data->modelData->nNonLinearSystems); printf("\tnStateSets: %d\n", data->modelData->nStateSets); printf("\tnInlineVars: %d\n", data->modelData->nInlineVars); printf("\tnOptimizeConstraints: %d\n", data->modelData->nOptimizeConstraints); printf("\tnOptimizeFinalConstraints: %d\n\n", data->modelData->nOptimizeFinalConstraints); printf("(4) RINGBUFFER* (simulationData) -- The first comment in the .c file is that this does not work. This struct is never used in the qss solver.\n\n"); //printf("\titemSize: %d\n", data->simulationData->itemSize); printf("(5) OpenModelicaGeneratedFunctionCallbacks (*callback). Just a number of functions updating the results. Not even sure where all these functions are defined. We may want to investigate where these functions are defined if we want to have a full understanding of the how OpenModelica enables it's solvers.\n\n"); printf("(B) threadData_t threadData. Next we have to consider the object threadData_t. However, I cannot find the definition of this object. Must investigate and get all attributes.\n\n"); printf("(C) SOLVER_INFO solverInfo:\n"); printf("\tcurrentTime: %f\n", solverInfo->currentTime); printf("\tcurrentStepSize: %f\n", solverInfo->currentStepSize); printf("\tlaststep: %f\n", solverInfo->laststep); printf("\tsolverMethod: %d\n", solverInfo->solverMethod); printf("\tsolverStepSize: %f\n", solverInfo->solverStepSize); printf("\tsolverRootFinding: %s\n", solverInfo->solverRootFinding ? "true" : "false"); printf("\tsolverNoEquidistantGrid: %s\n", solverInfo->solverNoEquidistantGrid ? "true" : "false"); printf("\tlastdesiredStep: %f\n", solverInfo->lastdesiredStep); printf("\tstateEvents: %d\n", solverInfo->stateEvents); printf("\tdidEventStep: %d\n", solverInfo->didEventStep); // printf("\teventLst.itemSize %d\n", solverInfo->eventLst->itemSize); // printf("\teventLst.length %d\n", solverInfo->eventLst.length); printf("\tsampleEvents: %d\n", solverInfo->sampleEvents); printf("\tintegratorSteps: %d\n", solverInfo->integratorSteps); printf("---------------###---------------\n\n"); /* 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_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; } } /* default use a user sub-routine for JAC */ dasslData->info[4] = 1; /* set up the appropriate function pointer */ switch (dasslData->dasslJacobian){ case DASSL_COLOREDNUMJAC: data->simulationInfo->jacobianEvals = data->simulationInfo->analyticJacobians[data->callback->INDEX_JAC_A].sparsePattern.maxColors; dasslData->jacobianFunction = JacobianOwnNumColored; break; case DASSL_COLOREDSYMJAC: data->simulationInfo->jacobianEvals = data->simulationInfo->analyticJacobians[data->callback->INDEX_JAC_A].sparsePattern.maxColors; 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; /* no user sub-routine for JAC */ dasslData->info[4] = 0; 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; }