int MultFive_updateBoundVariableAttributes(DATA *data) { /* min ******************************************************** */ infoStreamPrint(LOG_INIT, 1, "updating min-values"); if (ACTIVE_STREAM(LOG_INIT)) messageClose(LOG_INIT); /* max ******************************************************** */ infoStreamPrint(LOG_INIT, 1, "updating max-values"); if (ACTIVE_STREAM(LOG_INIT)) messageClose(LOG_INIT); /* nominal **************************************************** */ infoStreamPrint(LOG_INIT, 1, "updating nominal-values"); if (ACTIVE_STREAM(LOG_INIT)) messageClose(LOG_INIT); /* start ****************************************************** */ infoStreamPrint(LOG_INIT, 1, "updating start-values"); if (ACTIVE_STREAM(LOG_INIT)) messageClose(LOG_INIT); return 0; }
/*! * function write results in the cvs * author: Lennart Ochel **/ int ipoptDebuge(IPOPT_DATA_ *iData, double *x) { if(ACTIVE_STREAM(LOG_IPOPT)) { int i,j,k; double tmp; if(iData->index_debug_iter++ < iData->index_debug_next) return 0; iData->index_debug_next += iData->degub_step; for(j=0; j<iData->nv; ++j) { fprintf(iData->pFile[j], "\n"); fprintf(iData->pFile[j], "%ld,", iData->index_debug_iter); } for(i=0; i<iData->NV; ++i) { j = i % iData->nv; tmp = x[i]*iData->vnom[j]; fprintf(iData->pFile[j], "%.16g,", tmp); } for(j=0; j<iData->nv; ++j) fprintf(iData->pFile[j], "\n"); } return 0; }
/*! \fn printStatus * * \param [in] [solverData] * \param [in] [nfunc_evals] * \param [in] [xerror] * \param [in] [xerror_scaled] * \param [in] [logLevel] * * \author wbraun */ static void printStatus(DATA *data, DATA_HYBRD *solverData, int eqSystemNumber, const int *nfunc_evals, const double *xerror, const double *xerror_scaled, const int logLevel) { long i; if (!ACTIVE_STREAM(logLevel)) return; infoStreamPrint(logLevel, 1, "nls status"); infoStreamPrint(logLevel, 1, "variables"); for(i=0; i<solverData->n; i++) infoStreamPrint(logLevel, 0, "[%ld] %s = %.20e\n - scaling factor internal = %.16e\n" " - scaling factor external = %.16e", i+1, modelInfoGetEquation(&data->modelData->modelDataXml,eqSystemNumber).vars[i], solverData->x[i], solverData->diag[i], solverData->xScalefactors[i]); messageClose(logLevel); infoStreamPrint(logLevel, 1, "functions"); for(i=0; i<solverData->n; i++) infoStreamPrint(logLevel, 0, "res[%ld] = %.20e [scaling factor = %.16e]", i+1, solverData->fvec[i], solverData->resScaling[i]); messageClose(logLevel); infoStreamPrint(logLevel, 1, "statistics"); infoStreamPrint(logLevel, 0, "nfunc = %d\nerror = %.20e\nerror_scaled = %.20e", *nfunc_evals, *xerror, *xerror_scaled); messageClose(logLevel); messageClose(logLevel); }
void debugMatrixDoubleLS(int logName, char* matrixName, double* matrix, int n, int m) { if(ACTIVE_STREAM(logName)) { int i, j; int sparsity = 0; char *buffer = (char*)malloc(sizeof(char)*m*18); infoStreamPrint(logName, 1, "%s [%dx%d-dim]", matrixName, n, m); for(i=0; i<n;i++) { buffer[0] = 0; for(j=0; j<m; j++) { if (sparsity) { if (fabs(matrix[i + j*(m-1)])<1e-12) sprintf(buffer, "%s 0", buffer); else sprintf(buffer, "%s *", buffer); } else { sprintf(buffer, "%s%12.4g ", buffer, matrix[i + j*(m-1)]); } } infoStreamPrint(logName, 0, "%s", buffer); } messageClose(logName); free(buffer); } }
/*! \fn int newuoa_initialization(INIT_DATA *initData) * * This function performs initialization using the newuoa function, which is * a trust region method that forms quadratic models by interpolation. */ int newuoa_initialization(INIT_DATA *initData) { long IPRINT = ACTIVE_STREAM(LOG_INIT) ? 1000 : 0; long MAXFUN = 1000 * initData->nVars; double RHOEND = 1.0e-12; double RHOBEG = 10; /* This should be about one tenth of the greatest expected value of a variable. Perhaps the nominal value can be used for this. */ long NPT = 2*initData->nVars+1; double *W = (double*)calloc((NPT+13)*(NPT+initData->nVars)+3*initData->nVars*(initData->nVars+3)/2, sizeof(double)); ASSERT(W, "out of memory"); globalData = initData->simData; globalInitialResiduals = initData->initialResiduals; NEWUOA(&initData->nVars, &NPT, initData->vars, &RHOBEG, &RHOEND, &IPRINT, &MAXFUN, W, leastSquare); free(W); globalData = NULL; globalInitialResiduals = NULL; /* Calculate the residual to verify that equations are consistent. */ return reportResidualValue(initData); }
void debugIntLS(int logName, char* message, int value) { if(ACTIVE_STREAM(logName)) { infoStreamPrint(logName, 1, "%s %d", message, value); messageClose(logName); } }
void debugStringLS(int logName, char* message) { if(ACTIVE_STREAM(logName)) { infoStreamPrint(logName, 1, "%s", message); messageClose(logName); } }
static void messageCloseXML(int stream) { if(ACTIVE_STREAM(stream)) { fputs("</message>\n", stdout); fflush(stdout); } }
/*! \fn printVector * * \param [in] [vector] * \param [in] [size] * \param [in] [logLevel] * \param [in] [name] * * \author wbraun */ static void printVector(const double *vector, const integer *size, const int logLevel, const char *name) { int i; if (!ACTIVE_STREAM(logLevel)) return; infoStreamPrint(logLevel, 1, "%s", name); for(i=0; i<*size; i++) infoStreamPrint(logLevel, 0, "[%2d] %20.12g", i, vector[i]); messageClose(logLevel); }
/* * function calculates a jacobian matrix */ static int nlsDenseJac(long int N, N_Vector vecX, N_Vector vecFX, DlsMat Jac, void *userData, N_Vector tmp1, N_Vector tmp2) { NLS_KINSOL_USERDATA *kinsolUserData = (NLS_KINSOL_USERDATA*) userData; DATA* data = kinsolUserData->data; threadData_t *threadData = kinsolUserData->threadData; int sysNumber = kinsolUserData->sysNumber; NONLINEAR_SYSTEM_DATA *nlsData = &(data->simulationInfo->nonlinearSystemData[sysNumber]); NLS_KINSOL_DATA* kinsolData = (NLS_KINSOL_DATA*) nlsData->solverData; /* prepare variables */ double *x = N_VGetArrayPointer(vecX); double *fx = N_VGetArrayPointer(vecFX); double *xScaling = NV_DATA_S(kinsolData->xScale); double *fRes = NV_DATA_S(kinsolData->fRes); double xsave, xscale, sign; double delta_hh; const double delta_h = sqrt(DBL_EPSILON*2e1); long int i,j; /* performance measurement */ rt_ext_tp_tick(&nlsData->jacobianTimeClock); for(i = 0; i < N; i++) { xsave = x[i]; delta_hh = delta_h * (fabs(xsave) + 1.0); if ((xsave + delta_hh >= nlsData->max[i])) delta_hh *= -1; x[i] += delta_hh; /* Calculate difference quotient */ nlsKinsolResiduals(vecX, kinsolData->fRes, userData); /* Calculate scaled difference quotient */ delta_hh = 1. / delta_hh; for(j = 0; j < N; j++) { DENSE_ELEM(Jac, j, i) = (fRes[j] - fx[j]) * delta_hh; } x[i] = xsave; } /* debug */ if (ACTIVE_STREAM(LOG_NLS_JAC)){ infoStreamPrint(LOG_NLS_JAC, 0, "##KINSOL## omc dense matrix."); PrintMat(Jac); } /* performance measurement and statistics */ nlsData->jacobianTime += rt_ext_tp_tock(&(nlsData->jacobianTimeClock)); nlsData->numberOfJEval++; return 0; }
int MultFive_checkForDiscreteChanges(DATA *data) { int needToIterate = 0; infoStreamPrint(LOG_EVENTS_V, 1, "check for discrete changes"); if (ACTIVE_STREAM(LOG_EVENTS_V)) messageClose(LOG_EVENTS_V); return needToIterate; }
/*! \fn printRelations * * print all relations * * \param [in] [data] * \param [in] [stream] */ void printRelations(DATA *data, int stream) { TRACE_PUSH long i; if (!ACTIVE_STREAM(stream)) { TRACE_POP return; }
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); } }
/*! \fn printSparseStructure * * prints sparse structure of jacobian A * * \param [in] [data] * \param [in] [stream] * * \author lochel */ void printSparseStructure(DATA *data, int stream) { const int index = data->callback->INDEX_JAC_A; unsigned int row, col, i, j; /* Will crash with a static size array */ char *buffer = NULL; if (!ACTIVE_STREAM(stream)) return; buffer = (char*)omc_alloc_interface.malloc(sizeof(char)* 2*data->simulationInfo.analyticJacobians[index].sizeCols + 4); infoStreamPrint(stream, 1, "sparse structure of jacobian A [size: %ux%u]", data->simulationInfo.analyticJacobians[index].sizeRows, data->simulationInfo.analyticJacobians[index].sizeCols); infoStreamPrint(stream, 0, "%u nonzero elements", data->simulationInfo.analyticJacobians[index].sparsePattern.numberOfNoneZeros); /* sprintf(buffer, ""); for(row=0; row < data->simulationInfo.analyticJacobians[index].sizeRows; row++) sprintf(buffer, "%s%u ", buffer, data->simulationInfo.analyticJacobians[index].sparsePattern.leadindex[row]); infoStreamPrint(stream, 0, "leadindex: %s", buffer); sprintf(buffer, ""); for(i=0; i < data->simulationInfo.analyticJacobians[index].sparsePattern.numberOfNoneZeros; i++) sprintf(buffer, "%s%u ", buffer, data->simulationInfo.analyticJacobians[index].sparsePattern.index[i]); infoStreamPrint(stream, 0, "index: %s", buffer); */ infoStreamPrint(stream, 1, "transposed sparse structure (rows: states)"); i=0; for(row=0; row < data->simulationInfo.analyticJacobians[index].sizeRows; row++) { j=0; for(col=0; i < data->simulationInfo.analyticJacobians[index].sparsePattern.leadindex[row]; col++) { if(data->simulationInfo.analyticJacobians[index].sparsePattern.index[i] == col) { buffer[j++] = '*'; ++i; } else { buffer[j++] = ' '; } buffer[j++] = ' '; } buffer[j] = '\0'; infoStreamPrint(stream, 0, "%s", buffer); } messageClose(stream); messageClose(stream); }
/*! \fn printAllVars * * prints all variable values * * \param [in] [data] * \param [in] [ringSegment] * \param [in] [stream] * * \author wbraun */ void printAllVars(DATA *data, int ringSegment, int stream) { TRACE_PUSH long i; MODEL_DATA *mData = &(data->modelData); SIMULATION_INFO *sInfo = &(data->simulationInfo); if (!ACTIVE_STREAM(stream)) return; infoStreamPrint(stream, 1, "Print values for buffer segment %d regarding point in time : %g", ringSegment, data->localData[ringSegment]->timeValue); infoStreamPrint(stream, 1, "states variables"); for(i=0; i<mData->nStates; ++i) infoStreamPrint(stream, 0, "%ld: %s = %g (pre: %g)", i+1, mData->realVarsData[i].info.name, data->localData[ringSegment]->realVars[i], sInfo->realVarsPre[i]); messageClose(stream); infoStreamPrint(stream, 1, "derivatives variables"); for(i=mData->nStates; i<2*mData->nStates; ++i) infoStreamPrint(stream, 0, "%ld: %s = %g (pre: %g)", i+1, mData->realVarsData[i].info.name, data->localData[ringSegment]->realVars[i], sInfo->realVarsPre[i]); messageClose(stream); infoStreamPrint(stream, 1, "other real values"); for(i=2*mData->nStates; i<mData->nVariablesReal; ++i) infoStreamPrint(stream, 0, "%ld: %s = %g (pre: %g)", i+1, mData->realVarsData[i].info.name, data->localData[ringSegment]->realVars[i], sInfo->realVarsPre[i]); messageClose(stream); infoStreamPrint(stream, 1, "integer variables"); for(i=0; i<mData->nVariablesInteger; ++i) infoStreamPrint(stream, 0, "%ld: %s = %ld (pre: %ld)", i+1, mData->integerVarsData[i].info.name, data->localData[ringSegment]->integerVars[i], sInfo->integerVarsPre[i]); messageClose(stream); infoStreamPrint(stream, 1, "boolean variables"); for(i=0; i<mData->nVariablesBoolean; ++i) infoStreamPrint(stream, 0, "%ld: %s = %s (pre: %s)", i+1, mData->booleanVarsData[i].info.name, data->localData[ringSegment]->booleanVars[i] ? "true" : "false", sInfo->booleanVarsPre[i] ? "true" : "false"); messageClose(stream); infoStreamPrint(stream, 1, "string variables"); for(i=0; i<mData->nVariablesString; ++i) infoStreamPrint(stream, 0, "%ld: %s = %s (pre: %s)", i+1, mData->stringVarsData[i].info.name, MMC_STRINGDATA(data->localData[ringSegment]->stringVars[i]), MMC_STRINGDATA(sInfo->stringVarsPre[i])); messageClose(stream); messageClose(stream); TRACE_POP }
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); } }
void debugVectorDoubleLS(int logName, char* vectorName, double* vector, int n) { if(ACTIVE_STREAM(logName)) { int i; char buffer[4096]; infoStreamPrint(logName, 1, "%s [%d-dim]", vectorName, n); buffer[0] = 0; for(i=0; i<n; i++) { if (vector[i]<-1e+300) sprintf(buffer, "%s -INF ", buffer); else if (vector[i]>1e+300) sprintf(buffer, "%s +INF ", buffer); else sprintf(buffer, "%s%16.8g ", buffer, vector[i]); } infoStreamPrint(logName, 0, "%s", buffer); messageClose(logName); } }
/*! \fn solve linear system with totalpivot method * * \param [in] [data] * [sysNumber] index of the corresponing non-linear system * * \author bbachmann */ int solveTotalPivot(DATA *data, threadData_t *threadData, int sysNumber, double* aux_x) { void *dataAndThreadData[2] = {data, threadData}; int i, j; LINEAR_SYSTEM_DATA* systemData = &(data->simulationInfo->linearSystemData[sysNumber]); DATA_TOTALPIVOT* solverData = (DATA_TOTALPIVOT*) systemData->solverData[1]; int n = systemData->size, status; double fdeps = 1e-8; double xTol = 1e-8; int eqSystemNumber = systemData->equationIndex; int indexes[2] = {1,eqSystemNumber}; int rank; /* We are given the number of the linear system. * We want to look it up among all equations. */ /* int eqSystemNumber = systemData->equationIndex; */ int success = 1; double tmpJacEvalTime; infoStreamPrintWithEquationIndexes(LOG_LS, 0, indexes, "Start solving Linear System %d (size %d) at time %g with Total Pivot Solver", eqSystemNumber, (int) systemData->size, data->localData[0]->timeValue); debugVectorDoubleLS(LOG_LS_V,"SCALING",systemData->nominal,n); debugVectorDoubleLS(LOG_LS_V,"Old VALUES",aux_x,n); rt_ext_tp_tick(&(solverData->timeClock)); if (0 == systemData->method){ /* reset matrix A */ vecConstLS(n*n, 0.0, systemData->A); /* update matrix A -> first n columns of matrix Ab*/ systemData->setA(data, threadData, systemData); vecCopyLS(n*n, systemData->A, solverData->Ab); /* update vector b (rhs) -> -b is last column of matrix Ab*/ rt_ext_tp_tick(&(solverData->timeClock)); systemData->setb(data, threadData, systemData); vecScalarMultLS(n, systemData->b, -1.0, solverData->Ab + n*n); } else { /* calculate jacobian -> first n columns of matrix Ab*/ if(systemData->jacobianIndex != -1){ getAnalyticalJacobianTotalPivot(data, threadData, solverData->Ab, sysNumber); } else { assertStreamPrint(threadData, 1, "jacobian function pointer is invalid" ); } /* calculate vector b (rhs) -> -b is last column of matrix Ab */ wrapper_fvec_totalpivot(aux_x, solverData->Ab + n*n, dataAndThreadData, sysNumber); } tmpJacEvalTime = rt_ext_tp_tock(&(solverData->timeClock)); systemData->jacobianTime += tmpJacEvalTime; infoStreamPrint(LOG_LS_V, 0, "### %f time to set Matrix A and vector b.", tmpJacEvalTime); debugMatrixDoubleLS(LOG_LS_V,"LGS: matrix Ab",solverData->Ab, n, n+1); rt_ext_tp_tick(&(solverData->timeClock)); status = solveSystemWithTotalPivotSearchLS(n, solverData->x, solverData->Ab, solverData->indRow, solverData->indCol, &rank); infoStreamPrint(LOG_LS_V, 0, "Solve System: %f", rt_ext_tp_tock(&(solverData->timeClock))); if (status != 0) { warningStreamPrint(LOG_STDOUT, 0, "Error solving linear system of equations (no. %d) at time %f.", (int)systemData->equationIndex, data->localData[0]->timeValue); success = 0; } else { debugVectorDoubleLS(LOG_LS_V, "SOLUTION:", solverData->x, n+1); if (1 == systemData->method){ /* add the solution to old solution vector*/ vecAddLS(n, aux_x, solverData->x, aux_x); wrapper_fvec_totalpivot(aux_x, solverData->b, dataAndThreadData, sysNumber); } else { /* take the solution */ vecCopyLS(n, solverData->x, aux_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], aux_x[i]); } messageClose(LOG_LS_V); } } return success; }
/* * function calculates a jacobian matrix by * numerical method finite differences with coloring * into a sparse SlsMat matrix */ static int nlsSparseJac(N_Vector vecX, N_Vector vecFX, SlsMat Jac, void *userData, N_Vector tmp1, N_Vector tmp2) { NLS_KINSOL_USERDATA *kinsolUserData = (NLS_KINSOL_USERDATA*) userData; DATA* data = kinsolUserData->data; threadData_t *threadData = kinsolUserData->threadData; int sysNumber = kinsolUserData->sysNumber; NONLINEAR_SYSTEM_DATA *nlsData = &(data->simulationInfo->nonlinearSystemData[sysNumber]); NLS_KINSOL_DATA* kinsolData = (NLS_KINSOL_DATA*) nlsData->solverData; /* prepare variables */ double *x = N_VGetArrayPointer(vecX); double *fx = N_VGetArrayPointer(vecFX); double *xsave = N_VGetArrayPointer(tmp1); double *delta_hh = N_VGetArrayPointer(tmp2); double *xScaling = NV_DATA_S(kinsolData->xScale); double *fRes = NV_DATA_S(kinsolData->fRes); SPARSE_PATTERN* sparsePattern = &(nlsData->sparsePattern); const double delta_h = sqrt(DBL_EPSILON*2e1); long int i,j,ii; int nth = 0; /* performance measurement */ rt_ext_tp_tick(&nlsData->jacobianTimeClock); /* reset matrix */ SlsSetToZero(Jac); for(i = 0; i < sparsePattern->maxColors; i++) { for(ii=0; ii < kinsolData->size; ii++) { if(sparsePattern->colorCols[ii]-1 == i) { xsave[ii] = x[ii]; delta_hh[ii] = delta_h * (fabs(xsave[ii]) + 1.0); if ((xsave[ii] + delta_hh[ii] >= nlsData->max[ii])) delta_hh[ii] *= -1; x[ii] += delta_hh[ii]; /* Calculate scaled difference quotient */ delta_hh[ii] = 1. / delta_hh[ii]; } } nlsKinsolResiduals(vecX, kinsolData->fRes, userData); for(ii = 0; ii < kinsolData->size; ii++) { if(sparsePattern->colorCols[ii]-1 == i) { nth = sparsePattern->leadindex[ii]; while(nth < sparsePattern->leadindex[ii+1]) { j = sparsePattern->index[nth]; setJacElementKluSparse(j, ii, (fRes[j] - fx[j]) * delta_hh[ii], nth, Jac); nth++; }; x[ii] = xsave[ii]; } } } /* finish sparse matrix */ finishSparseColPtr(Jac); /* debug */ if (ACTIVE_STREAM(LOG_NLS_JAC)){ infoStreamPrint(LOG_NLS_JAC, 1, "##KINSOL## Sparse Matrix."); PrintSparseMat(Jac); nlsKinsolJacSumSparse(Jac); messageClose(LOG_NLS_JAC); } /* performance measurement and statistics */ nlsData->jacobianTime += rt_ext_tp_tock(&(nlsData->jacobianTimeClock)); nlsData->numberOfJEval++; return 0; }
/*! \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; }
int nlsKinsolAllocate(int size, NONLINEAR_SYSTEM_DATA *nlsData, int linearSolverMethod) { int i, flag, printLevel; NLS_KINSOL_DATA *kinsolData = (NLS_KINSOL_DATA*) malloc(sizeof(NLS_KINSOL_DATA)); /* allocate system data */ nlsData->solverData = (void*)kinsolData; kinsolData->size = size; kinsolData->linearSolverMethod = linearSolverMethod; kinsolData->solved = 0; kinsolData->fnormtol = sqrt(newtonFTol); /* function tolerance */ kinsolData->scsteptol = sqrt(newtonXTol); /* step tolerance */ kinsolData->initialGuess = N_VNew_Serial(size); kinsolData->xScale = N_VNew_Serial(size); kinsolData->fScale = N_VNew_Serial(size); kinsolData->fRes = N_VNew_Serial(size); kinsolData->kinsolMemory = KINCreate(); /* setup user defined functions */ KINSetErrHandlerFn(kinsolData->kinsolMemory, nlsKinsolErrorPrint, kinsolData); KINSetInfoHandlerFn(kinsolData->kinsolMemory, nlsKinsolInfoPrint, kinsolData); KINSetUserData(kinsolData->kinsolMemory, (void*)&(kinsolData->userData)); flag = KINInit(kinsolData->kinsolMemory, nlsKinsolResiduals, kinsolData->initialGuess); if (checkReturnFlag(flag)){ errorStreamPrint(LOG_STDOUT, 0, "##KINSOL## Something goes wrong while initialize KINSOL solver!"); } /* Specify linear solver and/or corresponding jacobian function*/ if (kinsolData->linearSolverMethod == 3) { if(nlsData->isPatternAvailable) { kinsolData->nnz = nlsData->sparsePattern.numberOfNoneZeros; flag = KINKLU(kinsolData->kinsolMemory, size, kinsolData->nnz); if (checkReturnFlag(flag)){ errorStreamPrint(LOG_STDOUT, 0, "##KINSOL## Something goes wrong while initialize KINSOL solver!"); } flag = KINSlsSetSparseJacFn(kinsolData->kinsolMemory, nlsSparseJac); if (checkReturnFlag(flag)){ errorStreamPrint(LOG_STDOUT, 0, "##KINSOL## Something goes wrong while initialize KINSOL Sparse Solver!"); } } else { flag = KINDense(kinsolData->kinsolMemory, size); if (checkReturnFlag(flag)){ errorStreamPrint(LOG_STDOUT, 0, "##KINSOL## Something goes wrong while initialize KINSOL solver!"); } } } else if (kinsolData->linearSolverMethod == 1) { flag = KINDense(kinsolData->kinsolMemory, size); if (checkReturnFlag(flag)){ errorStreamPrint(LOG_STDOUT, 0, "##KINSOL## Something goes wrong while initialize KINSOL solver!"); } } else if (kinsolData->linearSolverMethod == 2) { flag = KINDense(kinsolData->kinsolMemory, size); if (checkReturnFlag(flag)){ errorStreamPrint(LOG_STDOUT, 0, "##KINSOL## Something goes wrong while initialize KINSOL solver!"); } flag = KINDlsSetDenseJacFn(kinsolData->kinsolMemory, nlsDenseJac); if (checkReturnFlag(flag)){ errorStreamPrint(LOG_STDOUT, 0, "##KINSOL## Something goes wrong while initialize KINSOL Sparse Solver!"); } } /* configuration */ nlsKinsolConfigSetup(kinsolData); /* debug print level of kinsol */ if (ACTIVE_STREAM(LOG_NLS)) printLevel = 1; else if (ACTIVE_STREAM(LOG_NLS_V)) printLevel = 3; else printLevel = 0; KINSetPrintLevel(kinsolData->kinsolMemory, printLevel); return 0; }
/*! \fn solve non-linear system with newton method * * \param [in] [data] * [sysNumber] index of the corresponding non-linear system * * \author wbraun */ int solveNewton(DATA *data, threadData_t *threadData, int sysNumber) { NONLINEAR_SYSTEM_DATA* systemData = &(data->simulationInfo->nonlinearSystemData[sysNumber]); DATA_NEWTON* solverData = (DATA_NEWTON*)(systemData->solverData); int eqSystemNumber = 0; int i; double xerror = -1, xerror_scaled = -1; int success = 0; int nfunc_evals = 0; int continuous = 1; double local_tol = solverData->ftol; int giveUp = 0; int retries = 0; int retries2 = 0; int nonContinuousCase = 0; modelica_boolean *relationsPreBackup = NULL; int casualTearingSet = data->simulationInfo->nonlinearSystemData[sysNumber].strictTearingFunctionCall != NULL; DATA_USER* userdata = (DATA_USER*)malloc(sizeof(DATA_USER)); assert(userdata != NULL); userdata->data = (void*)data; userdata->threadData = threadData; userdata->sysNumber = sysNumber; /* * We are given the number of the non-linear system. * We want to look it up among all equations. */ eqSystemNumber = systemData->equationIndex; local_tol = solverData->ftol; relationsPreBackup = (modelica_boolean*) malloc(data->modelData->nRelations*sizeof(modelica_boolean)); solverData->nfev = 0; /* try to calculate jacobian only once at the beginning of the iteration */ solverData->calculate_jacobian = 0; // Initialize lambda variable if (data->simulationInfo->nonlinearSystemData[sysNumber].homotopySupport) { solverData->x[solverData->n] = 1.0; solverData->x_new[solverData->n] = 1.0; } else { solverData->x[solverData->n] = 0.0; solverData->x_new[solverData->n] = 0.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 with Newton Solver", eqSystemNumber, data->localData[0]->timeValue); for(i = 0; i < solverData->n; i++) { infoStreamPrint(LOG_NLS_V, 1, "x[%d] = %.15e", i, data->simulationInfo->discreteCall ? systemData->nlsx[i] : systemData->nlsxExtrapolation[i]); infoStreamPrint(LOG_NLS_V, 0, "nominal = %g +++ nlsx = %g +++ old = %g +++ extrapolated = %g", systemData->nominal[i], systemData->nlsx[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))); } /* start solving loop */ while(!giveUp && !success) { giveUp = 1; solverData->newtonStrategy = data->simulationInfo->newtonStrategy; _omc_newton(wrapper_fvec_newton, solverData, (void*)userdata); /* check for proper inputs */ if(solverData->info == 0) printErrorEqSyst(IMPROPER_INPUT, modelInfoGetEquation(&data->modelData->modelDataXml,eqSystemNumber), data->localData[0]->timeValue); /* 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; } /* check for error */ xerror_scaled = enorm_(&solverData->n, solverData->fvecScaled); xerror = enorm_(&solverData->n, solverData->fvec); /* solution found */ if((xerror <= local_tol || xerror_scaled <= local_tol) && solverData->info > 0) { success = 1; nfunc_evals += solverData->nfev; if(ACTIVE_STREAM(LOG_NLS_V)) { infoStreamPrint(LOG_NLS_V, 0, "*** System solved ***\n%d restarts", retries); infoStreamPrint(LOG_NLS_V, 0, "nfunc = %d +++ error = %.15e +++ error_scaled = %.15e", nfunc_evals, xerror, xerror_scaled); for(i = 0; i < solverData->n; i++) infoStreamPrint(LOG_NLS_V, 0, "x[%d] = %.15e\n\tresidual = %e", i, solverData->x[i], solverData->fvec[i]); } /* take the solution */ memcpy(systemData->nlsx, solverData->x, solverData->n*(sizeof(double))); /* Then try with old values (instead of extrapolating )*/ } // If this is the casual tearing set (only exists for dynamic tearing), break after first try else if(retries < 1 && casualTearingSet) { giveUp = 1; infoStreamPrint(LOG_NLS_V, 0, "### No Solution for the casual tearing set at the first try! ###"); } else if(retries < 1) { memcpy(solverData->x, systemData->nlsxOld, solverData->n*(sizeof(double))); retries++; giveUp = 0; nfunc_evals += solverData->nfev; infoStreamPrint(LOG_NLS_V, 0, " - iteration making no progress:\t try old values."); /* try to vary the initial values */ /* evaluate jacobian in every step now */ solverData->calculate_jacobian = 1; } else if(retries < 2) { for(i = 0; i < solverData->n; i++) solverData->x[i] += systemData->nominal[i] * 0.01; retries++; giveUp = 0; nfunc_evals += solverData->nfev; infoStreamPrint(LOG_NLS_V, 0, " - iteration making no progress:\t vary solution point by 1%%."); /* try to vary the initial values */ } else if(retries < 3) { for(i = 0; i < solverData->n; i++) solverData->x[i] = systemData->nominal[i]; retries++; giveUp = 0; nfunc_evals += solverData->nfev; infoStreamPrint(LOG_NLS_V, 0, " - iteration making no progress:\t try nominal values as initial solution."); } else if(retries < 4 && data->simulationInfo->discreteCall) { /* try to solve non-continuous * work-a-round: since other wise some model does * stuck in event iteration. e.g.: Modelica.Mechanics.Rotational.Examples.HeatLosses */ memcpy(solverData->x, systemData->nlsxOld, solverData->n*(sizeof(double))); retries++; /* try to solve a discontinuous system */ continuous = 0; nonContinuousCase = 1; memcpy(relationsPreBackup, data->simulationInfo->relationsPre, sizeof(modelica_boolean)*data->modelData->nRelations); giveUp = 0; nfunc_evals += solverData->nfev; infoStreamPrint(LOG_NLS_V, 0, " - iteration making no progress:\t try to solve a discontinuous system."); } else if(retries2 < 4) { memcpy(solverData->x, systemData->nlsxOld, solverData->n*(sizeof(double))); /* reduce tolarance */ local_tol = local_tol*10; retries = 0; retries2++; giveUp = 0; nfunc_evals += solverData->nfev; infoStreamPrint(LOG_NLS_V, 0, " - iteration making no progress:\t reduce the tolerance slightly to %e.", local_tol); } else { printErrorEqSyst(ERROR_AT_TIME, modelInfoGetEquation(&data->modelData->modelDataXml,eqSystemNumber), data->localData[0]->timeValue); if(ACTIVE_STREAM(LOG_NLS_V)) { infoStreamPrint(LOG_NLS_V, 0, "### No Solution! ###\n after %d restarts", retries); infoStreamPrint(LOG_NLS_V, 0, "nfunc = %d +++ error = %.15e +++ error_scaled = %.15e", nfunc_evals, xerror, xerror_scaled); if(ACTIVE_STREAM(LOG_NLS_V)) for(i = 0; i < solverData->n; i++) infoStreamPrint(LOG_NLS_V, 0, "x[%d] = %.15e\n\tresidual = %e", i, solverData->x[i], solverData->fvec[i]); } } } if(ACTIVE_STREAM(LOG_NLS_V)) messageClose(LOG_NLS_V); free(relationsPreBackup); /* write statistics */ systemData->numberOfFEval = solverData->numberOfFunctionEvaluations; systemData->numberOfIterations = solverData->numberOfIterations; 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; }
/*! \fn getAnalyticalJacobianSet * * function calculates analytical jacobian * * \param [ref] [data] ??? * \param [out] [index] ??? * * \author wbraun */ static void getAnalyticalJacobianSet(DATA* data, threadData_t *threadData, unsigned int index) { TRACE_PUSH unsigned int i, j, k, l, ii; unsigned int jacIndex = data->simulationInfo->stateSetData[index].jacobianIndex; unsigned int nrows = data->simulationInfo->analyticJacobians[jacIndex].sizeRows; unsigned int ncols = data->simulationInfo->analyticJacobians[jacIndex].sizeCols; double* jac = data->simulationInfo->stateSetData[index].J; /* set all elements to zero */ memset(jac, 0, (nrows*ncols*sizeof(double))); for(i=0; i < data->simulationInfo->analyticJacobians[jacIndex].sparsePattern.maxColors; i++) { for(ii=0; ii < data->simulationInfo->analyticJacobians[jacIndex].sizeCols; ii++) if(data->simulationInfo->analyticJacobians[jacIndex].sparsePattern.colorCols[ii]-1 == i) data->simulationInfo->analyticJacobians[jacIndex].seedVars[ii] = 1; /* if(ACTIVE_STREAM(LOG_DSS_JAC)) { infoStreamPrint(LOG_DSS_JAC, 1, "Caluculate one col:"); for(l=0; l < data->simulationInfo->analyticJacobians[jacIndex].sizeCols; l++) infoStreamPrint(LOG_DSS_JAC, 0, "seed: data->simulationInfo->analyticJacobians[index].seedVars[%d]= %f", l, data->simulationInfo->analyticJacobians[jacIndex].seedVars[l]); messageClose(LOG_DSS_JAC); } */ (data->simulationInfo->stateSetData[index].analyticalJacobianColumn)(data, threadData); for(j=0; j < data->simulationInfo->analyticJacobians[jacIndex].sizeCols; j++) { if(data->simulationInfo->analyticJacobians[jacIndex].seedVars[j] == 1) { if(j==0) ii = 0; else ii = data->simulationInfo->analyticJacobians[jacIndex].sparsePattern.leadindex[j-1]; /* infoStreamPrint(LOG_DSS_JAC, 0, "take for %d -> %d\n", j, ii); */ while(ii < data->simulationInfo->analyticJacobians[jacIndex].sparsePattern.leadindex[j]) { l = data->simulationInfo->analyticJacobians[jacIndex].sparsePattern.index[ii]; k = j*data->simulationInfo->analyticJacobians[jacIndex].sizeRows + l; jac[k] = data->simulationInfo->analyticJacobians[jacIndex].resultVars[l]; /* infoStreamPrint(LOG_DSS_JAC, 0, "write %d. in jac[%d]-[%d, %d]=%f from col[%d]=%f", ii, k, l, j, jac[k], l, data->simulationInfo->analyticJacobians[jacIndex].resultVars[l]); */ ii++; }; } } for(ii=0; ii < data->simulationInfo->analyticJacobians[jacIndex].sizeCols; ii++) if(data->simulationInfo->analyticJacobians[jacIndex].sparsePattern.colorCols[ii]-1 == i) data->simulationInfo->analyticJacobians[jacIndex].seedVars[ii] = 0; } if(ACTIVE_STREAM(LOG_DSS_JAC)) { char *buffer = (char*)malloc(sizeof(char)*data->simulationInfo->analyticJacobians[jacIndex].sizeCols*10); infoStreamPrint(LOG_DSS_JAC, 1, "jacobian %dx%d [id: %d]", data->simulationInfo->analyticJacobians[jacIndex].sizeRows, data->simulationInfo->analyticJacobians[jacIndex].sizeCols, jacIndex); for(i=0; i<data->simulationInfo->analyticJacobians[jacIndex].sizeRows; i++) { buffer[0] = 0; for(j=0; j < data->simulationInfo->analyticJacobians[jacIndex].sizeCols; j++) sprintf(buffer, "%s%.5e ", buffer, jac[i*data->simulationInfo->analyticJacobians[jacIndex].sizeCols+j]); infoStreamPrint(LOG_DSS_JAC, 0, "%s", buffer); } messageClose(LOG_DSS_JAC); free(buffer); } TRACE_POP }
/*! * 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; }
/*! \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; }
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; }
/*! \fn wrapper function of the residual Function * non-linear solver calls this subroutine fcn(n, x, fvec, iflag, data) * * */ static int wrapper_fvec_hybrj(const integer* n, const double* x, double* f, double* fjac, const integer* ldjac, const integer* iflag, void* dataAndSysNum) { int i,j; struct dataAndSys *dataSys = (struct dataAndSys*) dataAndSysNum; DATA *data = (dataSys->data); void *dataAndThreadData[2] = {data, dataSys->threadData}; NONLINEAR_SYSTEM_DATA* systemData = &(data->simulationInfo->nonlinearSystemData[dataSys->sysNumber]); DATA_HYBRD* solverData = (DATA_HYBRD*)(systemData->solverData); int continuous = data->simulationInfo->solveContinuous; switch(*iflag) { case 1: /* re-scaling x vector */ if(solverData->useXScaling) for(i=0; i<*n; i++) solverData->xScaled[i] = x[i]*solverData->xScalefactors[i]; /* debug output */ if(ACTIVE_STREAM(LOG_NLS_RES)) { infoStreamPrint(LOG_NLS_RES, 0, "-- residual function call %d -- scaling = %d", (int)solverData->nfev, solverData->useXScaling); printVector(x, n, LOG_NLS_RES, "x vector (scaled)"); printVector(solverData->xScaled, n, LOG_NLS_RES, "x vector"); } /* call residual function */ if(solverData->useXScaling){ (systemData->residualFunc)(dataAndThreadData, (const double*) solverData->xScaled, f, (const int*)iflag); } else { (systemData->residualFunc)(dataAndThreadData, x, f, (const int*)iflag); } /* debug output */ if(ACTIVE_STREAM(LOG_NLS_RES)) { printVector(f, n, LOG_NLS_RES, "residuals"); infoStreamPrint(LOG_NLS_RES, 0, "-- end of residual function call %d --", (int)solverData->nfev); } solverData->numberOfFunctionEvaluations++; break; case 2: /* set residual function continuous for jacobian calculation */ if(continuous) data->simulationInfo->solveContinuous = 0; if(ACTIVE_STREAM(LOG_NLS_RES)) infoStreamPrint(LOG_NLS_RES, 0, "-- begin calculating jacobian --"); /* call apropreated jacobian function */ if(systemData->jacobianIndex != -1){ integer iflagtmp = 1; wrapper_fvec_hybrj(n, x, f, fjac, ldjac, &iflagtmp, dataSys); getAnalyticalJacobian(dataSys, fjac); } else{ getNumericalJacobian(dataSys, fjac, x, f); } /* debug output */ if (ACTIVE_STREAM(LOG_NLS_RES)) { infoStreamPrint(LOG_NLS_RES, 0, "-- end calculating jacobian --"); if(ACTIVE_STREAM(LOG_NLS_JAC)) { char buffer[16384]; infoStreamPrint(LOG_NLS_JAC, 1, "jacobian matrix [%dx%d]", (int)*n, (int)*n); for(i=0; i<*n; i++) { buffer[0] = 0; for(j=0; j<*n; j++) sprintf(buffer, "%s%20.12g ", buffer, fjac[i*solverData->n+j]); infoStreamPrint(LOG_NLS_JAC, 0, "%s", buffer); } messageClose(LOG_NLS_JAC); } } /* reset residual function again */ if(continuous) data->simulationInfo->solveContinuous = 1; break; default: throwStreamPrint(NULL, "Well, this is embarrasing. The non-linear solver should never call this case.%d", (int)*iflag); break; } return 0; }