void va_warningStreamPrint(int stream, int indentNext, const char *format, va_list args) { if (ACTIVE_WARNING_STREAM(stream)) { char logBuffer[SIZE_LOG_BUFFER]; vsnprintf(logBuffer, SIZE_LOG_BUFFER, format, args); messageFunction(LOG_TYPE_WARNING, stream, indentNext, logBuffer, 0, NULL); } }
static void messageCloseXMLWarning(int stream) { if(ACTIVE_WARNING_STREAM(stream)) { fputs("</message>\n", stdout); fflush(stdout); } }
void warningStreamPrintWithEquationIndexes(int stream, int indentNext, const int *indexes, const char *format, ...) { if (ACTIVE_WARNING_STREAM(stream)) { char logBuffer[SIZE_LOG_BUFFER]; va_list args; va_start(args, format); vsnprintf(logBuffer, SIZE_LOG_BUFFER, format, args); va_end(args); messageFunction(LOG_TYPE_WARNING, stream, indentNext, logBuffer, 0, indexes); } }
/*! \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; }
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; }
static void messageCloseTextWarning(int stream) { if(ACTIVE_WARNING_STREAM(stream)) level[stream]--; }
int dassl_initial(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo, DASSL_DATA *dasslData) { TRACE_PUSH /* work arrays for DASSL */ unsigned int i; SIMULATION_DATA tmpSimData = {0}; RHSFinalFlag = 0; dasslData->liw = 40 + data->modelData.nStates; dasslData->lrw = 60 + ((maxOrder + 4) * data->modelData.nStates) + (data->modelData.nStates * data->modelData.nStates) + (3*data->modelData.nZeroCrossings); dasslData->rwork = (double*) calloc(dasslData->lrw, sizeof(double)); assertStreamPrint(threadData, 0 != dasslData->rwork,"out of memory"); dasslData->iwork = (int*) calloc(dasslData->liw, sizeof(int)); assertStreamPrint(threadData, 0 != dasslData->iwork,"out of memory"); dasslData->ng = (int) data->modelData.nZeroCrossings; dasslData->jroot = (int*) calloc(data->modelData.nZeroCrossings, sizeof(int)); dasslData->rpar = (double**) malloc(3*sizeof(double*)); dasslData->ipar = (int*) malloc(sizeof(int)); dasslData->ipar[0] = ACTIVE_STREAM(LOG_JAC); assertStreamPrint(threadData, 0 != dasslData->ipar,"out of memory"); dasslData->atol = (double*) malloc(data->modelData.nStates*sizeof(double)); dasslData->rtol = (double*) malloc(data->modelData.nStates*sizeof(double)); dasslData->info = (int*) calloc(infoLength, sizeof(int)); assertStreamPrint(threadData, 0 != dasslData->info,"out of memory"); dasslData->dasslStatistics = (unsigned int*) calloc(numStatistics, sizeof(unsigned int)); assertStreamPrint(threadData, 0 != dasslData->dasslStatistics,"out of memory"); dasslData->dasslStatisticsTmp = (unsigned int*) calloc(numStatistics, sizeof(unsigned int)); assertStreamPrint(threadData, 0 != dasslData->dasslStatisticsTmp,"out of memory"); dasslData->idid = 0; dasslData->sqrteps = sqrt(DBL_EPSILON); dasslData->ysave = (double*) malloc(data->modelData.nStates*sizeof(double)); dasslData->delta_hh = (double*) malloc(data->modelData.nStates*sizeof(double)); dasslData->newdelta = (double*) malloc(data->modelData.nStates*sizeof(double)); dasslData->stateDer = (double*) malloc(data->modelData.nStates*sizeof(double)); dasslData->currentContext = CONTEXT_UNKNOWN; /* setup internal ring buffer for dassl */ /* RingBuffer */ dasslData->simulationData = 0; dasslData->simulationData = allocRingBuffer(SIZERINGBUFFER, sizeof(SIMULATION_DATA)); if(!data->simulationData) { throwStreamPrint(threadData, "Your memory is not strong enough for our Ringbuffer!"); } /* prepare RingBuffer */ for(i=0; i<SIZERINGBUFFER; i++) { /* set time value */ tmpSimData.timeValue = 0; /* buffer for all variable values */ tmpSimData.realVars = (modelica_real*)calloc(data->modelData.nVariablesReal, sizeof(modelica_real)); assertStreamPrint(threadData, 0 != tmpSimData.realVars, "out of memory"); tmpSimData.integerVars = (modelica_integer*)calloc(data->modelData.nVariablesInteger, sizeof(modelica_integer)); assertStreamPrint(threadData, 0 != tmpSimData.integerVars, "out of memory"); tmpSimData.booleanVars = (modelica_boolean*)calloc(data->modelData.nVariablesBoolean, sizeof(modelica_boolean)); assertStreamPrint(threadData, 0 != tmpSimData.booleanVars, "out of memory"); tmpSimData.stringVars = (modelica_string*) GC_malloc_uncollectable(data->modelData.nVariablesString * sizeof(modelica_string)); assertStreamPrint(threadData, 0 != tmpSimData.stringVars, "out of memory"); appendRingData(dasslData->simulationData, &tmpSimData); } dasslData->localData = (SIMULATION_DATA**) GC_malloc_uncollectable(SIZERINGBUFFER * sizeof(SIMULATION_DATA)); memset(dasslData->localData, 0, SIZERINGBUFFER * sizeof(SIMULATION_DATA)); rotateRingBuffer(dasslData->simulationData, 0, (void**) dasslData->localData); /* end setup internal ring buffer for dassl */ /* ### start configuration of dassl ### */ infoStreamPrint(LOG_SOLVER, 1, "Configuration of the dassl code:"); /* set nominal values of the states for absolute tolerances */ dasslData->info[1] = 1; infoStreamPrint(LOG_SOLVER, 1, "The relative tolerance is %g. Following absolute tolerances are used for the states: ", data->simulationInfo.tolerance); for(i=0; i<data->modelData.nStates; ++i) { dasslData->rtol[i] = data->simulationInfo.tolerance; dasslData->atol[i] = data->simulationInfo.tolerance * fmax(fabs(data->modelData.realVarsData[i].attribute.nominal), 1e-32); infoStreamPrint(LOG_SOLVER, 0, "%d. %s -> %g", i+1, data->modelData.realVarsData[i].info.name, dasslData->atol[i]); } messageClose(LOG_SOLVER); /* let dassl return at every internal step */ dasslData->info[2] = 1; /* define maximum step size, which is dassl is allowed to go */ if (omc_flag[FLAG_MAX_STEP_SIZE]) { double maxStepSize = atof(omc_flagValue[FLAG_MAX_STEP_SIZE]); assertStreamPrint(threadData, maxStepSize >= DASSL_STEP_EPS, "Selected maximum step size %e is too small.", maxStepSize); dasslData->rwork[1] = maxStepSize; dasslData->info[6] = 1; infoStreamPrint(LOG_SOLVER, 0, "maximum step size %g", dasslData->rwork[1]); } else { infoStreamPrint(LOG_SOLVER, 0, "maximum step size not set"); } /* define initial step size, which is dassl is used every time it restarts */ if (omc_flag[FLAG_INITIAL_STEP_SIZE]) { double initialStepSize = atof(omc_flagValue[FLAG_INITIAL_STEP_SIZE]); assertStreamPrint(threadData, initialStepSize >= DASSL_STEP_EPS, "Selected initial step size %e is too small.", initialStepSize); dasslData->rwork[2] = initialStepSize; dasslData->info[7] = 1; infoStreamPrint(LOG_SOLVER, 0, "initial step size %g", dasslData->rwork[2]); } else { infoStreamPrint(LOG_SOLVER, 0, "initial step size not set"); } /* define maximum integration order of dassl */ if (omc_flag[FLAG_MAX_ORDER]) { int maxOrder = atoi(omc_flagValue[FLAG_MAX_ORDER]); assertStreamPrint(threadData, maxOrder >= 1 && maxOrder <= 5, "Selected maximum order %d is out of range (1-5).", maxOrder); dasslData->iwork[2] = maxOrder; dasslData->info[8] = 1; } infoStreamPrint(LOG_SOLVER, 0, "maximum integration order %d", dasslData->info[8]?dasslData->iwork[2]:maxOrder); /* if FLAG_NOEQUIDISTANT_GRID is set, choose dassl step method */ if (omc_flag[FLAG_NOEQUIDISTANT_GRID]) { dasslData->dasslSteps = 1; /* TRUE */ solverInfo->solverNoEquidistantGrid = 1; } else { dasslData->dasslSteps = 0; /* FALSE */ } infoStreamPrint(LOG_SOLVER, 0, "use equidistant time grid %s", dasslData->dasslSteps?"NO":"YES"); /* check if Flags FLAG_NOEQUIDISTANT_OUT_FREQ or FLAG_NOEQUIDISTANT_OUT_TIME are set */ if (dasslData->dasslSteps){ if (omc_flag[FLAG_NOEQUIDISTANT_OUT_FREQ]) { dasslData->dasslStepsFreq = atoi(omc_flagValue[FLAG_NOEQUIDISTANT_OUT_FREQ]); } else if (omc_flag[FLAG_NOEQUIDISTANT_OUT_TIME]) { dasslData->dasslStepsTime = atof(omc_flagValue[FLAG_NOEQUIDISTANT_OUT_TIME]); dasslData->rwork[1] = dasslData->dasslStepsTime; dasslData->info[6] = 1; infoStreamPrint(LOG_SOLVER, 0, "maximum step size %g", dasslData->rwork[1]); } else { dasslData->dasslStepsFreq = 1; dasslData->dasslStepsTime = 0.0; } if (omc_flag[FLAG_NOEQUIDISTANT_OUT_FREQ] && omc_flag[FLAG_NOEQUIDISTANT_OUT_TIME]){ warningStreamPrint(LOG_STDOUT, 0, "The flags are \"noEquidistantOutputFrequency\" " "and \"noEquidistantOutputTime\" are in opposition " "to each other. The flag \"noEquidistantOutputFrequency\" superiors."); } infoStreamPrint(LOG_SOLVER, 0, "as the output frequency control is used: %d", dasslData->dasslStepsFreq); infoStreamPrint(LOG_SOLVER, 0, "as the output frequency time step control is used: %f", dasslData->dasslStepsTime); } /* if FLAG_DASSL_JACOBIAN is set, choose dassl jacobian calculation method */ if (omc_flag[FLAG_DASSL_JACOBIAN]) { for(i=1; i< DASSL_JAC_MAX;i++) { if(!strcmp((const char*)omc_flagValue[FLAG_DASSL_JACOBIAN], dasslJacobianMethodStr[i])){ dasslData->dasslJacobian = (int)i; break; } } if(dasslData->dasslJacobian == DASSL_JAC_UNKNOWN) { if (ACTIVE_WARNING_STREAM(LOG_SOLVER)) { warningStreamPrint(LOG_SOLVER, 1, "unrecognized jacobian calculation method %s, current options are:", (const char*)omc_flagValue[FLAG_DASSL_JACOBIAN]); for(i=1; i < DASSL_JAC_MAX; ++i) { warningStreamPrint(LOG_SOLVER, 0, "%-15s [%s]", dasslJacobianMethodStr[i], dasslJacobianMethodDescStr[i]); } messageClose(LOG_SOLVER); } throwStreamPrint(threadData,"unrecognized jacobian calculation method %s", (const char*)omc_flagValue[FLAG_DASSL_JACOBIAN]); } /* default case colored numerical jacobian */ } else { dasslData->dasslJacobian = DASSL_COLOREDNUMJAC; } /* selects the calculation method of the jacobian */ if(dasslData->dasslJacobian == DASSL_COLOREDNUMJAC || dasslData->dasslJacobian == DASSL_COLOREDSYMJAC || dasslData->dasslJacobian == DASSL_NUMJAC || dasslData->dasslJacobian == DASSL_SYMJAC) { if (data->callback->initialAnalyticJacobianA(data, threadData)) { infoStreamPrint(LOG_STDOUT, 0, "Jacobian or SparsePattern is not generated or failed to initialize! Switch back to normal."); dasslData->dasslJacobian = DASSL_INTERNALNUMJAC; } else { dasslData->info[4] = 1; /* use sub-routine JAC */ } } /* set up the appropriate function pointer */ switch (dasslData->dasslJacobian){ case DASSL_COLOREDNUMJAC: dasslData->jacobianFunction = JacobianOwnNumColored; break; case DASSL_COLOREDSYMJAC: dasslData->jacobianFunction = JacobianSymbolicColored; break; case DASSL_SYMJAC: dasslData->jacobianFunction = JacobianSymbolic; break; case DASSL_NUMJAC: dasslData->jacobianFunction = JacobianOwnNum; break; case DASSL_INTERNALNUMJAC: dasslData->jacobianFunction = dummy_Jacobian; break; default: throwStreamPrint(threadData,"unrecognized jacobian calculation method %s", (const char*)omc_flagValue[FLAG_DASSL_JACOBIAN]); break; } infoStreamPrint(LOG_SOLVER, 0, "jacobian is calculated by %s", dasslJacobianMethodDescStr[dasslData->dasslJacobian]); /* if FLAG_DASSL_NO_ROOTFINDING is set, choose dassl with out internal root finding */ if(omc_flag[FLAG_DASSL_NO_ROOTFINDING]) { dasslData->dasslRootFinding = 0; dasslData->zeroCrossingFunction = dummy_zeroCrossing; dasslData->ng = 0; } else { solverInfo->solverRootFinding = 1; dasslData->dasslRootFinding = 1; dasslData->zeroCrossingFunction = function_ZeroCrossingsDASSL; } infoStreamPrint(LOG_SOLVER, 0, "dassl uses internal root finding method %s", dasslData->dasslRootFinding?"YES":"NO"); /* if FLAG_DASSL_NO_RESTART is set, choose dassl step method */ if (omc_flag[FLAG_DASSL_NO_RESTART]) { dasslData->dasslAvoidEventRestart = 1; /* TRUE */ } else { dasslData->dasslAvoidEventRestart = 0; /* FALSE */ } infoStreamPrint(LOG_SOLVER, 0, "dassl performs an restart after an event occurs %s", dasslData->dasslAvoidEventRestart?"NO":"YES"); /* ### end configuration of dassl ### */ messageClose(LOG_SOLVER); TRACE_POP return 0; }
int dassl_initial(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo, DASSL_DATA *dasslData) { TRACE_PUSH /* work arrays for DASSL */ unsigned int i; long N; SIMULATION_DATA tmpSimData = {0}; dasslData->residualFunction = functionODE_residual; N = data->modelData->nStates; dasslData->N = N; RHSFinalFlag = 0; dasslData->liw = 40 + N; dasslData->lrw = 60 + ((maxOrder + 4) * N) + (N * N) + (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(N*sizeof(double)); dasslData->rtol = (double*) malloc(N*sizeof(double)); dasslData->info = (int*) calloc(infoLength, sizeof(int)); assertStreamPrint(threadData, 0 != dasslData->info,"out of memory"); dasslData->idid = 0; dasslData->ysave = (double*) malloc(N*sizeof(double)); dasslData->ypsave = (double*) malloc(N*sizeof(double)); dasslData->delta_hh = (double*) malloc(N*sizeof(double)); dasslData->newdelta = (double*) malloc(N*sizeof(double)); dasslData->stateDer = (double*) calloc(N, sizeof(double)); dasslData->states = (double*) malloc(N*sizeof(double)); data->simulationInfo->currentContext = CONTEXT_ALGEBRAIC; /* ### start configuration of dassl ### */ infoStreamPrint(LOG_SOLVER, 1, "Configuration of the dassl code:"); /* set nominal values of the states for absolute tolerances */ dasslData->info[1] = 1; infoStreamPrint(LOG_SOLVER, 1, "The relative tolerance is %g. Following absolute tolerances are used for the states: ", data->simulationInfo->tolerance); for(i=0; i<dasslData->N; ++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_V, 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_JACOBIAN is set, choose dassl jacobian calculation method */ if (omc_flag[FLAG_JACOBIAN]) { for(i=1; i< JAC_MAX;i++) { if(!strcmp((const char*)omc_flagValue[FLAG_JACOBIAN], JACOBIAN_METHOD[i])){ dasslData->dasslJacobian = (int)i; break; } } if(dasslData->dasslJacobian == 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_JACOBIAN]); for(i=1; i < JAC_MAX; ++i) { warningStreamPrint(LOG_SOLVER, 0, "%-15s [%s]", JACOBIAN_METHOD[i], JACOBIAN_METHOD_DESC[i]); } messageClose(LOG_SOLVER); } throwStreamPrint(threadData,"unrecognized jacobian calculation method %s", (const char*)omc_flagValue[FLAG_JACOBIAN]); } /* default case colored numerical jacobian */ } else { dasslData->dasslJacobian = COLOREDNUMJAC; } /* selects the calculation method of the jacobian */ if(dasslData->dasslJacobian == COLOREDNUMJAC || dasslData->dasslJacobian == COLOREDSYMJAC || dasslData->dasslJacobian == SYMJAC) { ANALYTIC_JACOBIAN* jacobian = &(data->simulationInfo->analyticJacobians[data->callback->INDEX_JAC_A]); if (data->callback->initialAnalyticJacobianA(data, threadData, jacobian)) { infoStreamPrint(LOG_STDOUT, 0, "Jacobian or SparsePattern is not generated or failed to initialize! Switch back to normal."); dasslData->dasslJacobian = INTERNALNUMJAC; } else { ANALYTIC_JACOBIAN* jac = &data->simulationInfo->analyticJacobians[data->callback->INDEX_JAC_A]; infoStreamPrint(LOG_SIMULATION, 1, "Initialized colored Jacobian:"); infoStreamPrint(LOG_SIMULATION, 0, "columns: %d rows: %d", jac->sizeCols, jac->sizeRows); infoStreamPrint(LOG_SIMULATION, 0, "NNZ: %d colors: %d", jac->sparsePattern.numberOfNoneZeros, jac->sparsePattern.maxColors); messageClose(LOG_SIMULATION); } } /* default use a user sub-routine for JAC */ dasslData->info[4] = 1; /* set up the appropriate function pointer */ switch (dasslData->dasslJacobian){ case COLOREDNUMJAC: data->simulationInfo->jacobianEvals = data->simulationInfo->analyticJacobians[data->callback->INDEX_JAC_A].sparsePattern.maxColors; dasslData->jacobianFunction = jacA_numColored; break; case COLOREDSYMJAC: data->simulationInfo->jacobianEvals = data->simulationInfo->analyticJacobians[data->callback->INDEX_JAC_A].sparsePattern.maxColors; dasslData->jacobianFunction = jacA_symColored; break; case SYMJAC: dasslData->jacobianFunction = jacA_sym; break; case NUMJAC: dasslData->jacobianFunction = jacA_num; break; case 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_JACOBIAN]); break; } infoStreamPrint(LOG_SOLVER, 0, "jacobian is calculated by %s", JACOBIAN_METHOD_DESC[dasslData->dasslJacobian]); /* if FLAG_NO_ROOTFINDING is set, choose dassl with out internal root finding */ if(omc_flag[FLAG_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_NO_RESTART is set, choose dassl step method */ if (omc_flag[FLAG_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; }