/*! \fn updateDiscreteSystem * * Function to update the whole system with event iteration. * Evaluates functionDAE() * * \param [ref] [data] */ void updateDiscreteSystem(DATA *data, threadData_t *threadData) { TRACE_PUSH int IterationNum = 0; int discreteChanged = 0; modelica_boolean relationChanged = 0; data->simulationInfo.needToIterate = 0; data->simulationInfo.callStatistics.updateDiscreteSystem++; data->callback->function_updateRelations(data, threadData, 1); updateRelationsPre(data); storeRelations(data); data->callback->functionDAE(data, threadData); debugStreamPrint(LOG_EVENTS_V, 0, "updated discrete System"); relationChanged = checkRelations(data); discreteChanged = data->callback->checkForDiscreteChanges(data, threadData); while(discreteChanged || data->simulationInfo.needToIterate || relationChanged) { if(data->simulationInfo.needToIterate) { debugStreamPrint(LOG_EVENTS_V, 0, "reinit() call. Iteration needed!"); } if(relationChanged) { debugStreamPrint(LOG_EVENTS_V, 0, "relations changed. Iteration needed."); } if(discreteChanged) { debugStreamPrint(LOG_EVENTS_V, 0, "discrete Variable changed. Iteration needed."); } storePreValues(data); updateRelationsPre(data); printRelations(data, LOG_EVENTS_V); printZeroCrossings(data, LOG_EVENTS_V); data->callback->functionDAE(data, threadData); IterationNum++; if(IterationNum > IterationMax) { throwStreamPrint(threadData, "ERROR: Too many event iterations. System is inconsistent. Simulation terminate."); } relationChanged = checkRelations(data); discreteChanged = data->callback->checkForDiscreteChanges(data, threadData); } storeRelations(data); TRACE_POP }
/*! \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, 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; static state mem_state; modelica_boolean* relationsPreBackup; relationsPreBackup = (modelica_boolean*) malloc(data->modelData.nRelations*sizeof(modelica_boolean)); /* debug output */ if(ACTIVE_STREAM(LOG_NLS)) { INFO2(LOG_NLS, "start solving non-linear system >>%s<< at time %g", modelInfoXmlGetEquation(&data->modelData.modelDataXml, eqSystemNumber).name, data->localData[0]->timeValue); INDENT(LOG_NLS); for(i=0; i<solverData->n; i++) { INFO2(LOG_NLS, "x[%d] = %f", i, systemData->nlsx[i]); INDENT(LOG_NLS); INFO3(LOG_NLS, "scaling = %f\nold = %f\nextrapolated = %f", systemData->nominal[i], systemData->nlsxOld[i], systemData->nlsxExtrapolation[i]); RELEASE(LOG_NLS); } RELEASE(LOG_NLS); } /* 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]); /* evaluate with discontinuities */ { int scaling = solverData->useXScaling; if(scaling) solverData->useXScaling = 0; mem_state = get_memory_state(); /* try */ if(!setjmp(nonlinearJmpbuf)) { wrapper_fvec_hybrj(&solverData->n, solverData->x, solverData->fvec, solverData->fjac, &solverData->ldfjac, &iflag, data, sysNumber); restore_memory_state(mem_state); } else { /* catch */ restore_memory_state(mem_state); WARNING(LOG_STDOUT, "Non-Linear Solver try to handle a problem with a called assert."); } if(scaling) { solverData->useXScaling = 1; } } /* 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; mem_state = get_memory_state(); /* try */ if(!setjmp(nonlinearJmpbuf)) { _omc_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, data, sysNumber); restore_memory_state(mem_state); if(assertCalled) { INFO(LOG_NLS, "After asserts was called, values reached which avoided assert call."); memcpy(systemData->nlsxOld, solverData->x, solverData->n*(sizeof(double))); } assertRetries = 0; assertCalled = 0; } else { /* catch */ restore_memory_state(mem_state); if(!assertMessage) { INDENT(LOG_STDOUT); WARNING(LOG_STDOUT, "While solving non-linear system an assert was called."); WARNING(LOG_STDOUT, "The non-linear solver tries to solve the problem that could take some time."); WARNING(LOG_STDOUT, "It could help to provide better start-values for the iteration variables."); WARNING(LOG_STDOUT, "For more information simulate with -lv LOG_NLS"); RELEASE(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, modelInfoXmlGetEquation(&data->modelData.modelDataXml, eqSystemNumber), data->localData[0]->timeValue); } if(solverData->info != -1) { /* evaluate with discontinuities */ if(data->simulationInfo.discreteCall){ int scaling = solverData->useXScaling; if(scaling) solverData->useXScaling = 0; ((DATA*)data)->simulationInfo.solveContinuous = 0; mem_state = get_memory_state(); /* try */ if(!setjmp(nonlinearJmpbuf)) { wrapper_fvec_hybrj(&solverData->n, solverData->x, solverData->fvec, solverData->fjac, &solverData->ldfjac, &iflag, data, sysNumber); restore_memory_state(mem_state); } else { /* catch */ restore_memory_state(mem_state); WARNING(LOG_STDOUT, "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; storeRelations(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)) { INFO(LOG_NLS_V, "scaling factors for residual vector"); INDENT(LOG_NLS_V); for(i=0; i<solverData->n; i++) { INFO2(LOG_NLS_V, "scaled residual [%d] : %.20e", i, solverData->fvecScaled[i]); INDENT(LOG_NLS_V); INFO2(LOG_NLS_V, "scaling factor [%d] : %.20e", i, solverData->resScaling[i]); RELEASE(LOG_NLS_V); } RELEASE(LOG_NLS_V); } /* debug output */ if(ACTIVE_STREAM(LOG_NLS_JAC)) { char buffer[4096]; INFO2(LOG_NLS_JAC, "jacobian matrix [%dx%d]", (int)solverData->n, (int)solverData->n); INDENT(LOG_NLS_JAC); 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]); INFO1(LOG_NLS_JAC, "%s", buffer); } RELEASE(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)) { INFO(LOG_NLS, "system solved"); INDENT(LOG_NLS); INFO2(LOG_NLS, "%d retries\n%d restarts", retries, retries2+retries3); RELEASE(LOG_NLS); printStatus(solverData, &nfunc_evals, &xerror, &xerror_scaled, LOG_NLS); } scaling = solverData->useXScaling; if(scaling) solverData->useXScaling = 0; /* take the solution */ memcpy(systemData->nlsx, solverData->x, solverData->n*(sizeof(double))); mem_state = get_memory_state(); /* try */ if(!setjmp(nonlinearJmpbuf)) { wrapper_fvec_hybrj(&solverData->n, solverData->x, solverData->fvec, solverData->fjac, &solverData->ldfjac, &iflag, data, sysNumber); restore_memory_state(mem_state); } else { /* catch */ restore_memory_state(mem_state); WARNING(LOG_STDOUT, "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; } else if((solverData->info == 4 || solverData->info == 5) && assertRetries < 1+solverData->n && assertCalled) { /* case only used, when the Modelica code called an assert * then, we try to modify start values to avoid the assert call.*/ int i; memcpy(solverData->x, systemData->nlsxOld, solverData->n*(sizeof(double))); /* set all zero values to nominal values */ if(assertRetries < 1) { for(i=0; i<solverData->n; i++) { if(systemData->nlsx[i] == 0) { systemData->nlsx[i] = systemData->nominal[i]; solverData->x[i] = systemData->nominal[i]; } } } /* change initial guess values one by one */ else if(assertRetries < solverData->n+1) { i = assertRetries-1; solverData->x[i] += 0.01*systemData->nominal[i]; } giveUp = 0; nfunc_evals += solverData->nfev; assertRetries++; if(ACTIVE_STREAM(LOG_NLS)) { INFO1(LOG_NLS, " - try to handle a problem with a called assert vary initial value a bit. (Retry: %d)",assertRetries); printStatus(solverData, &nfunc_evals, &xerror, &xerror_scaled, LOG_NLS_V); } } else if((solverData->info == 4 || solverData->info == 5) && retries < 3) { /* first try to decrease factor */ /* 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))); solverData->factor = solverData->factor / 10.0; retries++; giveUp = 0; nfunc_evals += solverData->nfev; if(ACTIVE_STREAM(LOG_NLS)) { INFO1(LOG_NLS, " - iteration making no progress:\t decreasing initial step bound to %f.", solverData->factor); printStatus(solverData, &nfunc_evals, &xerror, &xerror_scaled, LOG_NLS_V); } } else if((solverData->info == 4 || solverData->info == 5) && retries < 4) { /* try to vary the initial values */ for(i = 0; i < solverData->n; i++) solverData->x[i] += systemData->nominal[i] * 0.1; solverData->factor = initial_factor; retries++; giveUp = 0; nfunc_evals += solverData->nfev; if(ACTIVE_STREAM(LOG_NLS)) { INFO(LOG_NLS, "iteration making no progress:\t vary solution point by 1%%."); printStatus(solverData, &nfunc_evals, &xerror, &xerror_scaled, LOG_NLS_V); } } else if((solverData->info == 4 || solverData->info == 5) && retries < 5) { /* try old values as x-Scaling factors */ /* 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(systemData->nlsxOld[i]), systemData->nominal[i]); retries++; giveUp = 0; nfunc_evals += solverData->nfev; if(ACTIVE_STREAM(LOG_NLS)) { INFO(LOG_NLS, "iteration making no progress:\t try old values as scaling factors."); printStatus(solverData, &nfunc_evals, &xerror, &xerror_scaled, LOG_NLS_V); } } else if((solverData->info == 4 || solverData->info == 5) && retries < 6) { int scaling = 0; /* try to disable x-Scaling */ /* 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))); scaling = solverData->useXScaling; if(scaling) solverData->useXScaling = 0; /* reset x-scalling factors */ for(i=0; i<solverData->n; i++) solverData->xScalefactors[i] = fmax(fabs(solverData->x[i]), systemData->nominal[i]); retries++; giveUp = 0; nfunc_evals += solverData->nfev; if(ACTIVE_STREAM(LOG_NLS)) { INFO(LOG_NLS, "iteration making no progress:\t try without scaling at all."); printStatus(solverData, &nfunc_evals, &xerror, &xerror_scaled, LOG_NLS_V); } } else if((solverData->info == 4 || solverData->info == 5) && retries < 7 && 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; if(ACTIVE_STREAM(LOG_NLS)) { INFO(LOG_NLS, " - iteration making no progress:\t try to solve a discontinuous system."); printStatus(solverData, &nfunc_evals, &xerror, &xerror_scaled, LOG_NLS_V); } /* Then try with old values (instead of extrapolating )*/ } else if((solverData->info == 4 || solverData->info == 5) && retries2 < 1) { int scaling = 0; /* set x vector */ memcpy(solverData->x, systemData->nlsxOld, solverData->n*(sizeof(double))); scaling = solverData->useXScaling; if(!scaling) solverData->useXScaling = 1; continuous = 1; solverData->factor = initial_factor; retries = 0; retries2++; giveUp = 0; nfunc_evals += solverData->nfev; if(ACTIVE_STREAM(LOG_NLS)) { INFO(LOG_NLS, " - iteration making no progress:\t use old values instead extrapolated."); printStatus(solverData, &nfunc_evals, &xerror, &xerror_scaled, LOG_NLS_V); } /* try to vary the initial values */ } else if((solverData->info == 4 || solverData->info == 5) && retries2 < 2) { /* 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->x[i] *= 1.01; }; retries = 0; retries2++; giveUp = 0; nfunc_evals += solverData->nfev; if(ACTIVE_STREAM(LOG_NLS)) { INFO(LOG_NLS, " - iteration making no progress:\t vary initial point by adding 1%%."); printStatus(solverData, &nfunc_evals, &xerror, &xerror_scaled, LOG_NLS_V); } /* try to vary the initial values */ } else if((solverData->info == 4 || solverData->info == 5) && retries2 < 3) { /* 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->x[i] *= 0.99; }; retries = 0; retries2++; giveUp = 0; nfunc_evals += solverData->nfev; if(ACTIVE_STREAM(LOG_NLS)) { INFO(LOG_NLS, " - iteration making no progress:\t vary initial point by -1%%."); printStatus(solverData, &nfunc_evals, &xerror, &xerror_scaled, LOG_NLS_V); } /* try to vary the initial values */ } else if((solverData->info == 4 || solverData->info == 5) && retries2 < 4) { /* set x vector */ memcpy(solverData->x, systemData->nominal, solverData->n*(sizeof(double))); retries = 0; retries2++; giveUp = 0; nfunc_evals += solverData->nfev; if(ACTIVE_STREAM(LOG_NLS)) { INFO(LOG_NLS, " - iteration making no progress:\t try scaling factor as initial point."); printStatus(solverData, &nfunc_evals, &xerror, &xerror_scaled, LOG_NLS_V); } /* try own scaling factors */ } else if((solverData->info == 4 || solverData->info == 5) && retries2 < 5 && !assertCalled) { /* 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->diag[i] = fabs(solverData->resScaling[i]); if(solverData->diag[i] <= 1e-16) solverData->diag[i] = 1e-16; } retries = 0; retries2++; giveUp = 0; solverData->mode = 2; nfunc_evals += solverData->nfev; if(ACTIVE_STREAM(LOG_NLS)) { INFO(LOG_NLS, " - iteration making no progress:\t try with own scaling factors."); printStatus(solverData, &nfunc_evals, &xerror, &xerror_scaled, LOG_NLS_V); } /* try without internal scaling */ } else if((solverData->info == 4 || solverData->info == 5) && retries3 < 1) { /* 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->diag[i] = 1.0; solverData->useXScaling = 1; retries = 0; retries2 = 0; retries3++; solverData->mode = 2; giveUp = 0; nfunc_evals += solverData->nfev; if(ACTIVE_STREAM(LOG_NLS)) { INFO(LOG_NLS, " - iteration making no progress:\t disable solver internal scaling."); printStatus(solverData, &nfunc_evals, &xerror, &xerror_scaled, LOG_NLS_V); } /* try to reduce the tolerance a bit */ } else if((solverData->info == 4 || solverData->info == 5) && retries3 < 6) { /* 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))); /* reduce tolarance */ local_tol = local_tol*10; solverData->factor = initial_factor; solverData->mode = 1; retries = 0; retries2 = 0; retries3++; giveUp = 0; nfunc_evals += solverData->nfev; if(ACTIVE_STREAM(LOG_NLS)) { INFO1(LOG_NLS, " - iteration making no progress:\t reduce the tolerance slightly to %e.", local_tol); printStatus(solverData, &nfunc_evals, &xerror, &xerror_scaled, LOG_NLS_V); } } else if(solverData->info >= 2 && solverData->info <= 5) { /* while the initialization it's ok to every time a solution */ if(!data->simulationInfo.initial){ printErrorEqSyst(ERROR_AT_TIME, modelInfoXmlGetEquation(&data->modelData.modelDataXml, eqSystemNumber), data->localData[0]->timeValue); } if(ACTIVE_STREAM(LOG_NLS)) { RELEASE(LOG_NLS); INFO1(LOG_NLS, "### No Solution! ###\n after %d restarts", retries*retries2*retries3); printStatus(solverData, &nfunc_evals, &xerror, &xerror_scaled, LOG_NLS); } /* take the best approximation */ memcpy(systemData->nlsx, solverData->x, solverData->n*(sizeof(double))); } } /* reset some solving data */ solverData->factor = initial_factor; solverData->mode = 1; free(relationsPreBackup); return success; }
/*! \fn static int symbolic_initialization(DATA *data) * * \param [ref] [data] * * \author lochel */ static int symbolic_initialization(DATA *data, threadData_t *threadData, long numLambdaSteps) { TRACE_PUSH long step; int retVal; /* initial sample and delay before initial the system */ initDelay(data, data->simulationInfo->startTime); /* initialize all relations that are ZeroCrossings */ storePreValues(data); overwriteOldSimulationData(data); if (data->callback->useHomotopy && numLambdaSteps > 1) { long i; char buffer[4096]; FILE *pFile = NULL; modelica_real* realVars = (modelica_real*)calloc(data->modelData->nVariablesReal, sizeof(modelica_real)); modelica_integer* integerVars = (modelica_integer*)calloc(data->modelData->nVariablesInteger, sizeof(modelica_integer)); modelica_boolean* booleanVars = (modelica_boolean*)calloc(data->modelData->nVariablesBoolean, sizeof(modelica_boolean)); modelica_string* stringVars = (modelica_string*) omc_alloc_interface.malloc_uncollectable(data->modelData->nVariablesString * sizeof(modelica_string)); MODEL_DATA *mData = data->modelData; assertStreamPrint(threadData, 0 != realVars, "out of memory"); assertStreamPrint(threadData, 0 != integerVars, "out of memory"); assertStreamPrint(threadData, 0 != booleanVars, "out of memory"); assertStreamPrint(threadData, 0 != stringVars, "out of memory"); for(i=0; i<mData->nVariablesReal; ++i) { realVars[i] = mData->realVarsData[i].attribute.start; } for(i=0; i<mData->nVariablesInteger; ++i) { integerVars[i] = mData->integerVarsData[i].attribute.start; } for(i=0; i<mData->nVariablesBoolean; ++i) { booleanVars[i] = mData->booleanVarsData[i].attribute.start; } for(i=0; i<mData->nVariablesString; ++i) { stringVars[i] = mData->stringVarsData[i].attribute.start; } if(ACTIVE_STREAM(LOG_INIT)) { sprintf(buffer, "%s_homotopy.csv", mData->modelFilePrefix); pFile = fopen(buffer, "wt"); fprintf(pFile, "%s,", "lambda"); for(i=0; i<mData->nVariablesReal; ++i) fprintf(pFile, "%s,", mData->realVarsData[i].info.name); fprintf(pFile, "\n"); } infoStreamPrint(LOG_INIT, 1, "homotopy process"); for(step=0; step<numLambdaSteps; ++step) { data->simulationInfo->lambda = ((double)step)/(numLambdaSteps-1); if(data->simulationInfo->lambda > 1.0) { data->simulationInfo->lambda = 1.0; } if(0 == step) data->callback->functionInitialEquations_lambda0(data, threadData); else data->callback->functionInitialEquations(data, threadData); infoStreamPrint(LOG_INIT, 0, "lambda = %g done", data->simulationInfo->lambda); if(ACTIVE_STREAM(LOG_INIT)) { fprintf(pFile, "%.16g,", data->simulationInfo->lambda); for(i=0; i<mData->nVariablesReal; ++i) fprintf(pFile, "%.16g,", data->localData[0]->realVars[i]); fprintf(pFile, "\n"); } if(check_nonlinear_solutions(data, 0) || check_linear_solutions(data, 0) || check_mixed_solutions(data, 0)) break; setAllStartToVars(data); } messageClose(LOG_INIT); if(ACTIVE_STREAM(LOG_INIT)) fclose(pFile); for(i=0; i<mData->nVariablesReal; ++i) mData->realVarsData[i].attribute.start = realVars[i]; for(i=0; i<mData->nVariablesInteger; ++i) mData->integerVarsData[i].attribute.start = integerVars[i]; for(i=0; i<mData->nVariablesBoolean; ++i) mData->booleanVarsData[i].attribute.start = booleanVars[i]; for(i=0; i<mData->nVariablesString; ++i) mData->stringVarsData[i].attribute.start = stringVars[i]; free(realVars); free(integerVars); free(booleanVars); omc_alloc_interface.free_uncollectable(stringVars); } else { data->simulationInfo->lambda = 1.0; data->callback->functionInitialEquations(data, threadData); } storeRelations(data); /* check for over-determined systems */ retVal = data->callback->functionRemovedInitialEquations(data, threadData); TRACE_POP return retVal; }