// writes MAT-file matrix header to file void writeMatVer4MatrixHeader(simulation_result *self,DATA *data,const char *name, int rows, int cols, unsigned int size) { mat_data *matData = (mat_data*) self->storage; typedef struct MHeader { uint32_t type; uint32_t mrows; uint32_t ncols; uint32_t imagf; uint32_t namelen; } MHeader_t; const int endian_test = 1; MHeader_t hdr; int type = 0; if(size == 1 /* char */) type = 51; if(size == 4 /* int32 */) type = 20; /* create matrix header structure */ hdr.type = 1000*((*(char*)&endian_test) == 0) + type; hdr.mrows = rows; hdr.ncols = cols; hdr.imagf = 0; hdr.namelen = strlen(name)+1; /* write header to file */ matData->fp.write((char*)&hdr, sizeof(MHeader_t)); if(!matData->fp) throwStreamPrint(data->threadData, "Cannot write to file %s",self->filename); matData->fp.write(name, sizeof(char)*hdr.namelen); if(!matData->fp) throwStreamPrint(data->threadData, "Cannot write to file %s",self->filename); }
void modelInfoXmlInit(MODEL_DATA_XML* xml) { FILE* file = NULL; XML_Parser parser = NULL; userData_t userData = {xml, 1, 0, 0}; if (!xml->infoXMLData) { file = fopen(xml->fileName, "r"); if(!file) { const char *str = strerror(errno); throwStreamPrint(NULL, "Failed to open file %s: %s\n", xml->fileName, str); } } parser = XML_ParserCreate(NULL); if(!parser) { throwStreamPrint(NULL, "Failed to create expat object"); } xml->functionNames = (FUNCTION_INFO*) calloc(xml->nFunctions, sizeof(FUNCTION_INFO)); xml->equationInfo = (EQUATION_INFO*) calloc(1+xml->nEquations, sizeof(EQUATION_INFO)); xml->equationInfo[0].id = 0; xml->equationInfo[0].profileBlockIndex = measure_time_flag & 2 ? 0 : -1; xml->equationInfo[0].numVar = 0; xml->equationInfo[0].vars = NULL; XML_SetUserData(parser, (void*) &userData); XML_SetElementHandler(parser, startElement, endElement); if(!xml->infoXMLData) { char buf[BUFSIZ] = {0}; mmc_sint_t done; do { size_t len = fread(buf, 1, sizeof(buf), file); done = len < sizeof(buf); if(XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR) { const char *err = XML_ErrorString(XML_GetErrorCode(parser)); mmc_uint_t line = XML_GetCurrentLineNumber(parser); fclose(file); XML_ParserFree(parser); throwStreamPrint(NULL, "%s: Error: failed to read the XML file %s: %s at line %lu", __FILE__, xml->fileName, err, line); } } while(!done); fclose(file); } else { if(XML_Parse(parser, xml->infoXMLData, strlen(xml->infoXMLData), 1) == XML_STATUS_ERROR) { const char *err = XML_ErrorString(XML_GetErrorCode(parser)); mmc_uint_t line = XML_GetCurrentLineNumber(parser); XML_ParserFree(parser); throwStreamPrint(NULL, "%s: Error: failed to read the XML data %s: %s at line %lu", __FILE__, xml->infoXMLData, err, line); } } assert(xml->nEquations == userData.curIndex); xml->nProfileBlocks = measure_time_flag & 1 ? userData.curProfileIndex : measure_time_flag & 2 ? xml->nEquations : 0; /* Set the number of profile blocks to the number we read */ assert(xml->nFunctions == userData.curFunctionIndex); XML_ParserFree(parser); }
static void fmtInit(DATA* data, MEASURE_TIME* mt) { mt->fmtReal = NULL; mt->fmtInt = NULL; if(measure_time_flag) { const char* fullFileName; if (omc_flag[FLAG_OUTPUT_PATH]) { /* read the output path from the command line (if any) */ if (0 > GC_asprintf(&fullFileName, "%s/%s", omc_flagValue[FLAG_OUTPUT_PATH], data->modelData->modelFilePrefix)) { throwStreamPrint(NULL, "perform_simulation.c: Error: can not allocate memory."); } } else { fullFileName = data->modelData->modelFilePrefix; } size_t len = strlen(fullFileName); char* filename = (char*) malloc((len+15) * sizeof(char)); strncpy(filename,fullFileName,len); strncpy(&filename[len],"_prof.realdata",15); mt->fmtReal = fopen(filename, "wb"); if(!mt->fmtReal) { warningStreamPrint(LOG_STDOUT, 0, "Time measurements output file %s could not be opened: %s", filename, strerror(errno)); } strncpy(&filename[len],"_prof.intdata",14); mt->fmtInt = fopen(filename, "wb"); if(!mt->fmtInt) { warningStreamPrint(LOG_STDOUT, 0, "Time measurements output file %s could not be opened: %s", filename, strerror(errno)); fclose(mt->fmtReal); mt->fmtReal = NULL; } free(filename); } }
void plt_init(simulation_result *self,DATA *data, threadData_t *threadData) { plt_data *pltData = (plt_data*) malloc(sizeof(plt_data)); rt_tick(SIM_TIMER_OUTPUT); /* * Re-Initialization is important because the variables are global and used in every solving step */ pltData->simulationResultData = 0; pltData->currentPos = 0; pltData->actualPoints = 0; /* the number of actual points saved */ pltData->dataSize = 0; pltData->maxPoints = self->numpoints; assertStreamPrint(threadData, self->numpoints >= 0, "Automatic output steps not supported in OpenModelica yet. Set numpoints >= 0."); pltData->num_vars = calcDataSize(self,data->modelData); pltData->dataSize = calcDataSize(self,data->modelData); pltData->simulationResultData = (double*)malloc(self->numpoints * pltData->dataSize * sizeof(double)); if(!pltData->simulationResultData) { throwStreamPrint(threadData, "Error allocating simulation result data of size %ld failed",self->numpoints * pltData->dataSize); } pltData->currentPos = 0; self->storage = pltData; rt_accumulate(SIM_TIMER_OUTPUT); }
/*! \fn freeMixedSystems * * Thi function frees memory of mixed systems. * * \param [ref] [data] */ int freeMixedSystems(DATA *data, threadData_t *threadData) { int i; MIXED_SYSTEM_DATA* system = data->simulationInfo->mixedSystemData; infoStreamPrint(LOG_NLS, 1, "free mixed system solvers"); for(i=0;i<data->modelData->nMixedSystems;++i) { free(system[i].iterationVarsPtr); free(system[i].iterationPreVarsPtr); /* allocate solver data */ switch(data->simulationInfo->mixedMethod) { case MIXED_SEARCH: freeMixedSearchData(&system[i].solverData); break; default: throwStreamPrint(threadData, "unrecognized mixed solver"); } free(system[i].solverData); } messageClose(LOG_NLS); return 0; }
/*! \fn freeNonlinearSystems * * This function frees memory of nonlinear systems. * * \param [ref] [data] */ int freeNonlinearSystems(DATA *data, threadData_t *threadData) { TRACE_PUSH int i; NONLINEAR_SYSTEM_DATA* nonlinsys = data->simulationInfo.nonlinearSystemData; struct csvStats* stats; infoStreamPrint(LOG_NLS, 1, "free non-linear system solvers"); for(i=0; i<data->modelData.nNonLinearSystems; ++i) { free(nonlinsys[i].nlsx); free(nonlinsys[i].nlsxExtrapolation); free(nonlinsys[i].nlsxOld); free(nonlinsys[i].nominal); free(nonlinsys[i].min); free(nonlinsys[i].max); #if !defined(OMC_MINIMAL_RUNTIME) if (data->simulationInfo.nlsCsvInfomation) { stats = nonlinsys[i].csvData; omc_write_csv_free(stats->callStats); omc_write_csv_free(stats->iterStats); } #endif /* free solver data */ switch(data->simulationInfo.nlsMethod) { #if !defined(OMC_MINIMAL_RUNTIME) case NLS_HYBRID: freeHybrdData(&nonlinsys[i].solverData); break; case NLS_KINSOL: nls_kinsol_free(&nonlinsys[i]); break; case NLS_NEWTON: freeNewtonData(&nonlinsys[i].solverData); break; #endif case NLS_HOMOTOPY: freeHomotopyData(&nonlinsys[i].solverData); break; #if !defined(OMC_MINIMAL_RUNTIME) case NLS_MIXED: freeHomotopyData(&((struct dataNewtonAndHybrid*) nonlinsys[i].solverData)->newtonData); freeHybrdData(&((struct dataNewtonAndHybrid*) nonlinsys[i].solverData)->hybridData); break; #endif default: throwStreamPrint(threadData, "unrecognized nonlinear solver"); } free(nonlinsys[i].solverData); } messageClose(LOG_NLS); TRACE_POP return 0; }
/*! \fn int initializeMixedSystems(DATA *data) * * This function allocates memory for all mixed systems. * * \param [ref] [data] */ int initializeMixedSystems(DATA *data, threadData_t *threadData) { int i; int size; MIXED_SYSTEM_DATA *system = data->simulationInfo->mixedSystemData; infoStreamPrint(LOG_NLS, 1, "initialize mixed system solvers"); infoStreamPrint(LOG_NLS, 0, "%ld mixed systems", data->modelData->nMixedSystems); for(i=0; i<data->modelData->nMixedSystems; ++i) { size = system[i].size; system[i].iterationVarsPtr = (modelica_boolean**) malloc(size*sizeof(modelica_boolean*)); system[i].iterationPreVarsPtr = (modelica_boolean**) malloc(size*sizeof(modelica_boolean*)); /* allocate solver data */ switch(data->simulationInfo->mixedMethod) { case MIXED_SEARCH: allocateMixedSearchData(size, &system[i].solverData); break; default: throwStreamPrint(threadData, "unrecognized mixed solver"); } } messageClose(LOG_NLS); return 0; }
void writeMatVer4Matrix(simulation_result *self,DATA *data,const char *name, int rows, int cols, const void *matrixData, unsigned int size) { mat_data *matData = (mat_data*) self->storage; writeMatVer4MatrixHeader(self,data,name,rows,cols,size); /* write data */ matData->fp.write((const char*)matrixData, (size)*rows*cols); if(!matData->fp) { throwStreamPrint(data->threadData, "Cannot write to file %s",self->filename); } }
EQUATION_INFO modelInfoXmlGetEquationIndexByProfileBlock(MODEL_DATA_XML* xml, size_t ix) { mmc_sint_t i; if(xml->equationInfo == NULL) { modelInfoXmlInit(xml); } if(ix > xml->nProfileBlocks) { throwStreamPrint(NULL, "Requested equation with profiler index %ld, but we only have %ld such blocks", (long int)ix, xml->nProfileBlocks); } for(i=0; i<xml->nEquations; i++) { if(xml->equationInfo[i].profileBlockIndex == ix) { return xml->equationInfo[i]; } } throwStreamPrint(NULL, "Requested equation with profiler index %ld, but could not find it!", (long int)ix); }
/*! \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 }
void plt_emit(simulation_result *self,DATA *data, threadData_t *threadData) { plt_data *pltData = (plt_data*) self->storage; rt_tick(SIM_TIMER_OUTPUT); if(pltData->actualPoints < pltData->maxPoints) { add_result(self,data,pltData->simulationResultData,&pltData->actualPoints); /*used for non-interactive simulation */ } else { pltData->maxPoints = (long)(1.4*pltData->maxPoints + (pltData->maxPoints-pltData->actualPoints) + 2000); /* cerr << "realloc simulationResultData to a size of " << maxPoints * dataSize * sizeof(double) << endl; */ pltData->simulationResultData = (double*)realloc(pltData->simulationResultData, pltData->maxPoints * pltData->dataSize * sizeof(double)); if(!pltData->simulationResultData) { throwStreamPrint(threadData, "Error allocating simulation result data of size %ld",pltData->maxPoints * pltData->dataSize); } add_result(self,data,pltData->simulationResultData,&pltData->actualPoints); } rt_accumulate(SIM_TIMER_OUTPUT); }
/*! \fn solve mixed systems * * \param [in] [data] * [sysNumber] index of corresponding mixed System * * \author wbraun */ int solve_mixed_system(DATA *data, threadData_t *threadData, int sysNumber) { int success; MIXED_SYSTEM_DATA* system = data->simulationInfo->mixedSystemData; /* for now just use lapack solver as before */ switch(data->simulationInfo->mixedMethod) { case MIXED_SEARCH: success = solveMixedSearch(data, sysNumber); break; default: throwStreamPrint(threadData, "unrecognized mixed solver"); } system[sysNumber].solved = success; return 0; }
/*! \fn initializeStateSetJacobians * * initialize jacobians for state selection * * \param [ref] [data] ??? * * \author ??? */ void initializeStateSetJacobians(DATA *data, threadData_t *threadData) { TRACE_PUSH long i = 0; STATE_SET_DATA *set = NULL; /* go troug all state sets*/ for(i=0; i<data->modelData->nStateSets; i++) { set = &(data->simulationInfo->stateSetData[i]); if(set->initialAnalyticalJacobian(data, threadData)) { throwStreamPrint(threadData, "can not initialze Jacobians for dynamic state selection"); } } initializeStateSetPivoting(data); TRACE_POP }
void mat4_emit(simulation_result *self,DATA *data) { mat_data *matData = (mat_data*) self->storage; double datPoint=0; rt_tick(SIM_TIMER_OUTPUT); rt_accumulate(SIM_TIMER_TOTAL); double cpuTimeValue = rt_accumulated(SIM_TIMER_TOTAL); rt_tick(SIM_TIMER_TOTAL); /* this is done wrong -- a buffering should be used although ofstream does have some buffering, but it is not enough and not for this purpose */ matData->fp.write((char*)&(data->localData[0]->timeValue), sizeof(double)); if(self->cpuTime) matData->fp.write((char*)&cpuTimeValue, sizeof(double)); for(int i = 0; i < data->modelData.nVariablesReal; i++) if(!data->modelData.realVarsData[i].filterOutput) matData->fp.write((char*)&(data->localData[0]->realVars[i]),sizeof(double)); for(int i = 0; i < data->modelData.nVariablesInteger; i++) if(!data->modelData.integerVarsData[i].filterOutput) { datPoint = (double) data->localData[0]->integerVars[i]; matData->fp.write((char*)&datPoint,sizeof(double)); } for(int i = 0; i < data->modelData.nVariablesBoolean; i++) if(!data->modelData.booleanVarsData[i].filterOutput) { datPoint = (double) data->localData[0]->booleanVars[i]; matData->fp.write((char*)&datPoint,sizeof(double)); } for(int i = 0; i < data->modelData.nAliasBoolean; i++) if(!data->modelData.booleanAlias[i].filterOutput) { if(data->modelData.booleanAlias[i].negate) { datPoint = (double) (data->localData[0]->booleanVars[data->modelData.booleanAlias[i].nameID]==1?0:1); matData->fp.write((char*)&datPoint,sizeof(double)); } } if (!matData->fp) { throwStreamPrint(data->threadData, "Error while writing file %s",self->filename); } ++matData->ntimepoints; rt_accumulate(SIM_TIMER_OUTPUT); }
/*! \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; }
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; }
/* * output the result before destroying the datastructure. */ void plt_free(simulation_result *self,DATA *data, threadData_t *threadData) { plt_data *pltData = (plt_data*) self->storage; const MODEL_DATA *modelData = data->modelData; int varn = 0, i, var; FILE* f = NULL; rt_tick(SIM_TIMER_OUTPUT); f = fopen(self->filename, "w"); if(!f) { deallocResult(pltData); throwStreamPrint(threadData, "Error, couldn't create output file: [%s] because of %s", self->filename, strerror(errno)); } /* Rather ugly numbers than unneccessary rounding. f.precision(std::numeric_limits<double>::digits10 + 1); */ fprintf(f, "#Ptolemy Plot file, generated by OpenModelica\n"); fprintf(f, "#NumberofVariables=%d\n", pltData->num_vars); fprintf(f, "#IntervalSize=%ld\n", pltData->actualPoints); fprintf(f, "TitleText: OpenModelica simulation plot\n"); fprintf(f, "XLabel: t\n\n"); /* time variable. */ fprintf(f, "DataSet: time\n"); for(i = 0; i < pltData->actualPoints; ++i) printPltLine(f, pltData->simulationResultData[i*pltData->num_vars], pltData->simulationResultData[i*pltData->num_vars]); fprintf(f, "\n"); varn++; /* $cpuTime variable. */ if(self->cpuTime) { fprintf(f, "DataSet: $cpuTime\n"); for(i = 0; i < pltData->actualPoints; ++i) printPltLine(f, pltData->simulationResultData[i*pltData->num_vars], pltData->simulationResultData[i*pltData->num_vars + 1]); fprintf(f, "\n"); varn++; } for(var = 0; var < modelData->nVariablesReal; ++var) { if(!modelData->realVarsData[var].filterOutput) { fprintf(f, "DataSet: %s\n", modelData->realVarsData[var].info.name); for(i = 0; i < pltData->actualPoints; ++i) printPltLine(f, pltData->simulationResultData[i*pltData->num_vars], pltData->simulationResultData[i*pltData->num_vars + varn]); fprintf(f, "\n"); varn++; } } for(var = 0; var < modelData->nVariablesInteger; ++var) { if(!modelData->integerVarsData[var].filterOutput) { fprintf(f, "DataSet: %s\n", modelData->integerVarsData[var].info.name); for(i = 0; i < pltData->actualPoints; ++i) printPltLine(f, pltData->simulationResultData[i*pltData->num_vars], pltData->simulationResultData[i*pltData->num_vars + varn]); fprintf(f, "\n"); varn++; } } for(var = 0; var < modelData->nVariablesBoolean; ++var) { if(!modelData->booleanVarsData[var].filterOutput) { fprintf(f, "DataSet: %s\n", modelData->booleanVarsData[var].info.name); for(i = 0; i < pltData->actualPoints; ++i) printPltLine(f, pltData->simulationResultData[i*pltData->num_vars], pltData->simulationResultData[i*pltData->num_vars + varn]); fprintf(f, "\n"); varn++; } } for(var = 0; var < modelData->nAliasReal; ++var) { if(!modelData->realAlias[var].filterOutput) { fprintf(f, "DataSet: %s\n", modelData->realAlias[var].info.name); for(i = 0; i < pltData->actualPoints; ++i) printPltLine(f, pltData->simulationResultData[i*pltData->num_vars], pltData->simulationResultData[i*pltData->num_vars + varn]); fprintf(f, "\n"); varn++; } } for(var = 0; var < modelData->nAliasInteger; ++var) { if(!modelData->integerAlias[var].filterOutput) { fprintf(f, "DataSet: %s\n", modelData->integerAlias[var].info.name); for(i = 0; i < pltData->actualPoints; ++i) printPltLine(f, pltData->simulationResultData[i*pltData->num_vars], pltData->simulationResultData[i*pltData->num_vars + varn]); fprintf(f, "\n"); varn++; } } for(var = 0; var < modelData->nAliasBoolean; ++var) { if(!modelData->booleanAlias[var].filterOutput) { fprintf(f, "DataSet: %s\n", modelData->booleanAlias[var].info.name); for(i = 0; i < pltData->actualPoints; ++i) printPltLine(f, pltData->simulationResultData[i*pltData->num_vars], pltData->simulationResultData[i*pltData->num_vars + varn]); fprintf(f, "\n"); varn++; } } deallocResult(pltData); if(fclose(f)) { throwStreamPrint(threadData, "Error, couldn't write to output file %s\n", self->filename); } free(self->storage); self->storage = NULL; rt_accumulate(SIM_TIMER_OUTPUT); }
void mat4_init(simulation_result *self,DATA *data) { mat_data *matData = new mat_data(); self->storage = matData; const MODEL_DATA *mData = &(data->modelData); const char Aclass[] = "A1 bt. ir1 na Tj re ac nt so r y "; const struct VAR_INFO** names = NULL; const int nParams = mData->nParametersReal + mData->nParametersInteger + mData->nParametersBoolean; char *stringMatrix = NULL; int rows, cols; int32_t *intMatrix = NULL; double *doubleMatrix = NULL; assert(sizeof(char) == 1); rt_tick(SIM_TIMER_OUTPUT); matData->numVars = calcDataSize(self,data); names = calcDataNames(self,data,matData->numVars+nParams); matData->data1HdrPos = -1; matData->data2HdrPos = -1; matData->ntimepoints = 0; matData->startTime = data->simulationInfo.startTime; matData->stopTime = data->simulationInfo.stopTime; try { /* open file */ matData->fp.open(self->filename, std::ofstream::binary|std::ofstream::trunc); if(!matData->fp) { throwStreamPrint(data->threadData, "Cannot open File %s for writing",self->filename); } /* write `AClass' matrix */ writeMatVer4Matrix(self,data,"Aclass", 4, 11, Aclass, sizeof(int8_t)); /* flatten variables' names */ flattenStrBuf(matData->numVars+nParams, names, stringMatrix, rows, cols, false /* We cannot plot derivatives if we fix the names ... */, false); /* write `name' matrix */ writeMatVer4Matrix(self,data,"name", rows, cols, stringMatrix, sizeof(int8_t)); free(stringMatrix); stringMatrix = NULL; /* flatten variables' comments */ flattenStrBuf(matData->numVars+nParams, names, stringMatrix, rows, cols, false, true); /* write `description' matrix */ writeMatVer4Matrix(self,data,"description", rows, cols, stringMatrix, sizeof(int8_t)); free(stringMatrix); stringMatrix = NULL; /* generate dataInfo table */ generateDataInfo(self, data, intMatrix, rows, cols, matData->numVars, nParams); /* write `dataInfo' matrix */ writeMatVer4Matrix(self, data, "dataInfo", cols, rows, intMatrix, sizeof(int32_t)); /* remember data1HdrPos */ matData->data1HdrPos = matData->fp.tellp(); /* adrpo: i cannot use writeParameterData here as it would return back to dataHdr1Pos */ /* generate `data_1' matrix (with parameter data) */ generateData_1(data, doubleMatrix, rows, cols, matData->startTime, matData->stopTime); /* write `data_1' matrix */ writeMatVer4Matrix(self,data,"data_1", cols, rows, doubleMatrix, sizeof(double)); /* remember data2HdrPos */ matData->data2HdrPos = matData->fp.tellp(); /* write `data_2' header */ writeMatVer4MatrixHeader(self,data,"data_2", matData->r_indx_map.size() + matData->i_indx_map.size() + matData->b_indx_map.size() + matData->negatedboolaliases + 1 /* add one more for timeValue*/ + self->cpuTime, 0, sizeof(double)); free(doubleMatrix); free(intMatrix); doubleMatrix = NULL; intMatrix = NULL; matData->fp.flush(); } catch(...) { matData->fp.close(); free(names); names=NULL; free(stringMatrix); free(doubleMatrix); free(intMatrix); rt_accumulate(SIM_TIMER_OUTPUT); throwStreamPrint(data->threadData, "Error while writing mat file %s",self->filename); } free(names); names=NULL; rt_accumulate(SIM_TIMER_OUTPUT); }
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; }
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; }
/*! \fn int initializeNonlinearSystems(DATA *data) * * This function allocates memory for all nonlinear systems. * * \param [ref] [data] */ int initializeNonlinearSystems(DATA *data, threadData_t *threadData) { TRACE_PUSH int i,j; int size; NONLINEAR_SYSTEM_DATA *nonlinsys = data->simulationInfo->nonlinearSystemData; struct dataNewtonAndHybrid *mixedSolverData; infoStreamPrint(LOG_NLS, 1, "initialize non-linear system solvers"); for(i=0; i<data->modelData->nNonLinearSystems; ++i) { size = nonlinsys[i].size; nonlinsys[i].numberOfFEval = 0; nonlinsys[i].numberOfIterations = 0; /* check if residual function pointer are valid */ assertStreamPrint(threadData, 0 != nonlinsys[i].residualFunc, "residual function pointer is invalid" ); /* check if analytical jacobian is created */ if(nonlinsys[i].jacobianIndex != -1) { assertStreamPrint(threadData, 0 != nonlinsys[i].analyticalJacobianColumn, "jacobian function pointer is invalid" ); if(nonlinsys[i].initialAnalyticalJacobian(data, threadData)) { nonlinsys[i].jacobianIndex = -1; } } /* allocate system data */ nonlinsys[i].nlsx = (double*) malloc(size*sizeof(double)); nonlinsys[i].nlsxExtrapolation = (double*) malloc(size*sizeof(double)); nonlinsys[i].nlsxOld = (double*) malloc(size*sizeof(double)); nonlinsys[i].resValues = (double*) malloc(size*sizeof(double)); /* allocate value list*/ nonlinsys[i].oldValueList = (void*) allocValueList(1); nonlinsys[i].lastTimeSolved = 0.0; nonlinsys[i].nominal = (double*) malloc(size*sizeof(double)); nonlinsys[i].min = (double*) malloc(size*sizeof(double)); nonlinsys[i].max = (double*) malloc(size*sizeof(double)); nonlinsys[i].initializeStaticNLSData(data, threadData, &nonlinsys[i]); #if !defined(OMC_MINIMAL_RUNTIME) /* csv data call stats*/ if (data->simulationInfo->nlsCsvInfomation) { if (initializeNLScsvData(data, &nonlinsys[i])) { throwStreamPrint(threadData, "csvData initialization failed"); } else { print_csvLineCallStatsHeader(((struct csvStats*) nonlinsys[i].csvData)->callStats); print_csvLineIterStatsHeader(data, &nonlinsys[i], ((struct csvStats*) nonlinsys[i].csvData)->iterStats); } } #endif /* allocate solver data */ switch(data->simulationInfo->nlsMethod) { #if !defined(OMC_MINIMAL_RUNTIME) case NLS_HYBRID: allocateHybrdData(size, &nonlinsys[i].solverData); break; case NLS_KINSOL: nlsKinsolAllocate(size, &nonlinsys[i], data->simulationInfo->nlsLinearSolver); break; case NLS_NEWTON: allocateNewtonData(size, &nonlinsys[i].solverData); break; #endif case NLS_HOMOTOPY: allocateHomotopyData(size, &nonlinsys[i].solverData); break; #if !defined(OMC_MINIMAL_RUNTIME) case NLS_MIXED: mixedSolverData = (struct dataNewtonAndHybrid*) malloc(sizeof(struct dataNewtonAndHybrid)); allocateHomotopyData(size, &(mixedSolverData->newtonData)); allocateHybrdData(size, &(mixedSolverData->hybridData)); nonlinsys[i].solverData = (void*) mixedSolverData; break; #endif default: throwStreamPrint(threadData, "unrecognized nonlinear solver"); } } messageClose(LOG_NLS); TRACE_POP return 0; }
int nlsKinsolFree(void** solverData) { throwStreamPrint(NULL,"no sundials/kinsol support activated"); return 0; }
/*! \fn solve non-linear systems * * \param [in] [data] * \param [in] [sysNumber] index of corresponding non-linear system * * \author wbraun */ int solve_nonlinear_system(DATA *data, threadData_t *threadData, int sysNumber) { void *dataAndThreadData[2] = {data, threadData}; int success = 0, saveJumpState; NONLINEAR_SYSTEM_DATA* nonlinsys = &(data->simulationInfo->nonlinearSystemData[sysNumber]); struct dataNewtonAndHybrid *mixedSolverData; data->simulationInfo->currentNonlinearSystemIndex = sysNumber; /* enable to avoid division by zero */ data->simulationInfo->noThrowDivZero = 1; ((DATA*)data)->simulationInfo->solveContinuous = 1; /* performance measurement */ rt_ext_tp_tick(&nonlinsys->totalTimeClock); /* grab the initial guess */ infoStreamPrint(LOG_NLS_EXTRAPOLATE, 1, "############ Start new iteration for system %ld at time at %g ############", nonlinsys->equationIndex, data->localData[0]->timeValue); /* if last solving is too long ago use just old values */ if (fabs(data->localData[0]->timeValue - nonlinsys->lastTimeSolved) < 5*data->simulationInfo->stepSize) { getInitialGuess(nonlinsys, data->localData[0]->timeValue); } else { nonlinsys->getIterationVars(data, nonlinsys->nlsx); memcpy(nonlinsys->nlsx, nonlinsys->nlsxOld, nonlinsys->size*(sizeof(double))); } /* update non continuous */ if (data->simulationInfo->discreteCall) { updateInnerEquation(dataAndThreadData, sysNumber, 1); } /* try */ #ifndef OMC_EMCC MMC_TRY_INTERNAL(simulationJumpBuffer) #endif /* handle asserts */ saveJumpState = threadData->currentErrorStage; threadData->currentErrorStage = ERROR_NONLINEARSOLVER; /* use the selected solver for solving nonlinear system */ switch(data->simulationInfo->nlsMethod) { #if !defined(OMC_MINIMAL_RUNTIME) case NLS_HYBRID: success = solveHybrd(data, threadData, sysNumber); break; case NLS_KINSOL: success = nlsKinsolSolve(data, threadData, sysNumber); break; case NLS_NEWTON: success = solveNewton(data, threadData, sysNumber); /* check if solution process was successful, if not use alternative tearing set if available (dynamic tearing)*/ if (!success && nonlinsys->strictTearingFunctionCall != NULL){ debugString(LOG_DT, "Solving the casual tearing set failed! Now the strict tearing set is used."); success = nonlinsys->strictTearingFunctionCall(data, threadData); if (success) success=2; } break; #endif case NLS_HOMOTOPY: success = solveHomotopy(data, threadData, sysNumber); break; #if !defined(OMC_MINIMAL_RUNTIME) case NLS_MIXED: mixedSolverData = nonlinsys->solverData; nonlinsys->solverData = mixedSolverData->newtonData; success = solveHomotopy(data, threadData, sysNumber); /* check if solution process was successful, if not use alternative tearing set if available (dynamic tearing)*/ if (!success && nonlinsys->strictTearingFunctionCall != NULL){ debugString(LOG_DT, "Solving the casual tearing set failed! Now the strict tearing set is used."); success = nonlinsys->strictTearingFunctionCall(data, threadData); if (success){ success=2; /* update iteration variables of the causal set*/ nonlinsys->getIterationVars(data, nonlinsys->nlsx); } } if (!success) { nonlinsys->solverData = mixedSolverData->hybridData; success = solveHybrd(data, threadData, sysNumber); } nonlinsys->solverData = mixedSolverData; break; #endif default: throwStreamPrint(threadData, "unrecognized nonlinear solver"); } /* set result */ nonlinsys->solved = success; /* handle asserts */ threadData->currentErrorStage = saveJumpState; /*catch */ #ifndef OMC_EMCC MMC_CATCH_INTERNAL(simulationJumpBuffer) #endif /* update value list database */ updateInitialGuessDB(nonlinsys, data->localData[0]->timeValue, data->simulationInfo->currentContext); if (nonlinsys->solved == 1) { nonlinsys->lastTimeSolved = data->localData[0]->timeValue; } /* enable to avoid division by zero */ data->simulationInfo->noThrowDivZero = 0; ((DATA*)data)->simulationInfo->solveContinuous = 0; /* performance measurement and statistics */ nonlinsys->totalTime += rt_ext_tp_tock(&(nonlinsys->totalTimeClock)); nonlinsys->numberOfCall++; /* write csv file for debugging */ #if !defined(OMC_MINIMAL_RUNTIME) if (data->simulationInfo->nlsCsvInfomation) { print_csvLineCallStats(((struct csvStats*) nonlinsys->csvData)->callStats, nonlinsys->numberOfCall, data->localData[0]->timeValue, nonlinsys->numberOfIterations, nonlinsys->numberOfFEval, nonlinsys->totalTime, nonlinsys->solved ); } #endif return check_nonlinear_solution(data, 1, sysNumber); }
/*! \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; }
static void XMLCALL startElement(void *voidData, const char *name, const char **attr) { userData_t *userData = (userData_t*) voidData; if(0==strcmp("defines", name)) { assertStreamPrint(NULL, ((0==strcmp(attr[0], "name")) && attr[2] == NULL), "<defines> needs to have exactly one attribute: name"); if(varsBuffer == 0 || maxVarsBuffer == 0) { maxVarsBuffer = 32; varsBuffer = (const char**) malloc(sizeof(const char*)*maxVarsBuffer); } else if(userData->xml->equationInfo[userData->curIndex].numVar+2 >= maxVarsBuffer) { maxVarsBuffer *= 2; varsBuffer = realloc(varsBuffer, sizeof(const char*)*maxVarsBuffer); } varsBuffer[userData->xml->equationInfo[userData->curIndex].numVar++] = strdup(attr[1]); return; } if(0==strcmp("info", name)) { while(attr[0]) { if(0 == strcmp("file", attr[0])) { file_info.filename = strdup(attr[1]); } else if(0 == strcmp("lineStart", attr[0])) { file_info.lineStart = strtol(attr[1], NULL, 10); } else if(0 == strcmp("lineEnd", attr[0])) { file_info.lineEnd = strtol(attr[1], NULL, 10); } else if(0 == strcmp("colStart", attr[0])) { file_info.colStart = strtol(attr[1], NULL, 10); } else if(0 == strcmp("colEnd", attr[0])) { file_info.colEnd = strtol(attr[1], NULL, 10); } else if(0 == strcmp("readonly", attr[0])) { file_info.readonly = 0==strcmp(attr[1], "true"); } else { throwStreamPrint(NULL, "%s: Unknown attribute in <info>", userData->xml->fileName); } attr += 2; } return; } if(0 == strcmp("equation", name)) { mmc_sint_t ix; if(userData->curIndex > userData->xml->nEquations) { throwStreamPrint(NULL, "%s: Info XML %s contained more equations than expected (%ld)", __FILE__, userData->xml->fileName, userData->xml->nEquations); } if(!attr[0] || strcmp("index", attr[0])) { throwStreamPrint(NULL, "%s: Info XML %s contained equation without index", __FILE__, userData->xml->fileName); } ix = strtol(attr[1], NULL, 10); if (attr[2] && 0==strcmp("parent", attr[2])) { userData->xml->equationInfo[userData->curIndex].parent = strtol(attr[3], NULL, 10); } else { userData->xml->equationInfo[userData->curIndex].parent = 0; } if(userData->curIndex != ix) { throwStreamPrint(NULL, "%s: Info XML %s got equation with index %ld, expected %ld", __FILE__, userData->xml->fileName, ix, userData->curIndex); } userData->xml->equationInfo[userData->curIndex].id = userData->curIndex; userData->xml->equationInfo[userData->curIndex].profileBlockIndex = measure_time_flag & 2 ? userData->curIndex : -1; /* TODO: Set when parsing other tags */ userData->xml->equationInfo[userData->curIndex].numVar = 0; /* TODO: Set when parsing other tags */ userData->xml->equationInfo[userData->curIndex].vars = NULL; /* Set when parsing other tags (on close). */ } if(0 == strcmp("variable", name)) { var_info.name = NULL; var_info.comment = NULL; while (attr[0]) { if(0 == strcmp(attr[0], "name")) { var_info.name = strdup(attr[1]); } else if(0 == strcmp(attr[0], "comment")) { var_info.comment = strdup(attr[1]); } attr+=2; } assertStreamPrint(NULL, var_info.name && var_info.comment, "<var>-tag did not set name and comment"); var_info.id = -1; /* ??? */ var_info.info = file_info; return; } if(0 == strcmp("function", name)) { userData->xml->functionNames[userData->curFunctionIndex].id = userData->curFunctionIndex; userData->xml->functionNames[userData->curFunctionIndex].name = "#FIXME#"; userData->xml->functionNames[userData->curFunctionIndex].name = strdup(attr[1]); userData->xml->functionNames[userData->curFunctionIndex].info.filename = "TODO: Set me up!!!"; } }
int nlsKinsolAllocate(int size, NONLINEAR_SYSTEM_DATA *nlsData, int linearSolverMethod) { throwStreamPrint(NULL,"no sundials/kinsol support activated"); return 0; }
/*! \fn performSimulation(DATA* data, SOLVER_INFO* solverInfo) * * \param [ref] [data] * \param [ref] [solverInfo] * * This function performs the simulation controlled by solverInfo. */ int prefixedName_performSimulation(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo) { TRACE_PUSH int retValIntegrator=0; int retValue=0; int i, retry=0, steadStateReached=0; unsigned int __currStepNo = 0; SIMULATION_INFO *simInfo = data->simulationInfo; solverInfo->currentTime = simInfo->startTime; MEASURE_TIME fmt; fmtInit(data, &fmt); printAllVarsDebug(data, 0, LOG_DEBUG); /* ??? */ if (!compiledInDAEMode) { printSparseStructure(&(data->simulationInfo->analyticJacobians[data->callback->INDEX_JAC_A].sparsePattern), data->simulationInfo->analyticJacobians[data->callback->INDEX_JAC_A].sizeRows, data->simulationInfo->analyticJacobians[data->callback->INDEX_JAC_A].sizeCols, LOG_SOLVER, "ODE sparse pattern"); } else { printSparseStructure(data->simulationInfo->daeModeData->sparsePattern, data->simulationInfo->daeModeData->nResidualVars, data->simulationInfo->daeModeData->nResidualVars, LOG_SOLVER, "DAE sparse pattern"); } if(terminationTerminate) { printInfo(stdout, TermInfo); fputc('\n', stdout); infoStreamPrint(LOG_STDOUT, 0, "Simulation call terminate() at initialization (time %f)\nMessage : %s", data->localData[0]->timeValue, TermMsg); data->simulationInfo->stopTime = solverInfo->currentTime; } else { modelica_boolean syncStep = 0; /***** Start main simulation loop *****/ while(solverInfo->currentTime < simInfo->stopTime || !simInfo->useStopTime) { int success = 0; threadData->currentErrorStage = ERROR_SIMULATION; #ifdef USE_DEBUG_TRACE if(useStream[LOG_TRACE]) { printf("TRACE: push loop step=%u, time=%.12g\n", __currStepNo, solverInfo->currentTime); } #endif /* check for steady state */ if (omc_flag[FLAG_STEADY_STATE]) { if (0 < data->modelData->nStates) { int i; double maxDer = 0.0; double currDer; for(i=data->modelData->nStates; i<2*data->modelData->nStates; ++i) { currDer = fabs(data->localData[0]->realVars[i] / data->modelData->realVarsData[i].attribute.nominal); if(maxDer < currDer) maxDer = currDer; } if (maxDer < steadyStateTol) { steadStateReached=1; infoStreamPrint(LOG_STDOUT, 0, "steady state reached at time = %g\n * max(|d(x_i)/dt|/nominal(x_i)) = %g\n * relative tolerance = %g", solverInfo->currentTime, maxDer, steadyStateTol); break; } } else throwStreamPrint(threadData, "No states in model. Flag -steadyState can only be used if states are present."); } omc_alloc_interface.collect_a_little(); /* try */ #if !defined(OMC_EMCC) MMC_TRY_INTERNAL(simulationJumpBuffer) #endif { printAllVars(data, 0, LOG_SOLVER_V); clear_rt_step(data); if (!compiledInDAEMode) /* do not use ringbuffer for daeMode */ rotateRingBuffer(data->simulationData, 1, (void**) data->localData); modelica_boolean syncEventStep = solverInfo->didEventStep || syncStep; /***** Calculation next step size *****/ if(syncEventStep) { infoStreamPrint(LOG_SOLVER, 0, "offset value for the next step: %.16g", (solverInfo->currentTime - solverInfo->laststep)); } else { if (solverInfo->solverNoEquidistantGrid) { if (solverInfo->currentTime >= solverInfo->lastdesiredStep) { do { __currStepNo++; solverInfo->currentStepSize = (double)(__currStepNo*(simInfo->stopTime-simInfo->startTime))/(simInfo->numSteps) + simInfo->startTime - solverInfo->currentTime; } while(solverInfo->currentStepSize <= 0); } } else { __currStepNo++; } } solverInfo->currentStepSize = (double)(__currStepNo*(simInfo->stopTime-simInfo->startTime))/(simInfo->numSteps) + simInfo->startTime - solverInfo->currentTime; solverInfo->lastdesiredStep = solverInfo->currentTime + solverInfo->currentStepSize; /* if retry reduce stepsize */ if (0 != retry) { solverInfo->currentStepSize /= 2; } /***** End calculation next step size *****/ checkForSynchronous(data, solverInfo); /* check for next time event */ checkForSampleEvent(data, solverInfo); /* if regular output point and last time events are almost equals * skip that step and go further */ if (solverInfo->currentStepSize < 1e-15 && syncEventStep){ __currStepNo++; continue; } /* * integration step determine all states by a integration method * update continuous system */ infoStreamPrint(LOG_SOLVER, 1, "call solver from %g to %g (stepSize: %.15g)", solverInfo->currentTime, solverInfo->currentTime + solverInfo->currentStepSize, solverInfo->currentStepSize); retValIntegrator = simulationStep(data, threadData, solverInfo); infoStreamPrint(LOG_SOLVER, 0, "finished solver step %g", solverInfo->currentTime); messageClose(LOG_SOLVER); if (S_OPTIMIZATION == solverInfo->solverMethod) break; syncStep = simulationUpdate(data, threadData, solverInfo); retry = 0; /* reset retry */ fmtEmitStep(data, threadData, &fmt, solverInfo); saveIntegratorStats(solverInfo); checkSimulationTerminated(data, solverInfo); /* terminate for some cases: * - integrator fails * - non-linear system failed to solve * - assert was called */ if (retValIntegrator) { retValue = -1 + retValIntegrator; infoStreamPrint(LOG_STDOUT, 0, "model terminate | Integrator failed. | Simulation terminated at time %g", solverInfo->currentTime); break; } else if(check_nonlinear_solutions(data, 0)) { retValue = -2; infoStreamPrint(LOG_STDOUT, 0, "model terminate | non-linear system solver failed. | Simulation terminated at time %g", solverInfo->currentTime); break; } else if(check_linear_solutions(data, 0)) { retValue = -3; infoStreamPrint(LOG_STDOUT, 0, "model terminate | linear system solver failed. | Simulation terminated at time %g", solverInfo->currentTime); break; } else if(check_mixed_solutions(data, 0)) { retValue = -4; infoStreamPrint(LOG_STDOUT, 0, "model terminate | mixed system solver failed. | Simulation terminated at time %g", solverInfo->currentTime); break; } success = 1; } #if !defined(OMC_EMCC) MMC_CATCH_INTERNAL(simulationJumpBuffer) #endif if (!success) { /* catch */ if(0 == retry) { retrySimulationStep(data, threadData, solverInfo); retry = 1; } else { retValue = -1; infoStreamPrint(LOG_STDOUT, 0, "model terminate | Simulation terminated by an assert at time: %g", data->localData[0]->timeValue); break; } } TRACE_POP /* pop loop */ } /* end while solver */ } /* end else */ fmtClose(&fmt); if (omc_flag[FLAG_STEADY_STATE] && !steadStateReached) { warningStreamPrint(LOG_STDOUT, 0, "Steady state has not been reached.\nThis may be due to too restrictive relative tolerance (%g) or short stopTime (%g).", steadyStateTol, simInfo->stopTime); } TRACE_POP return retValue; }
int nlsKinsolSolve(DATA *data, threadData_t *threadData, int sysNumber) { throwStreamPrint(threadData,"no sundials/kinsol support activated"); return 0; }
/*! \fn int importStartValues(DATA *data, const char *pInitFile, const double initTime) * * \param [ref] [data] * \param [in] [pInitFile] * \param [in] [initTime] * * \author lochel */ int importStartValues(DATA *data, threadData_t *threadData, const char *pInitFile, const double initTime) { ModelicaMatReader reader; ModelicaMatVariable_t *pVar = NULL; double value; const char *pError = NULL; char* newVarname = NULL; MODEL_DATA *mData = data->modelData; long i; infoStreamPrint(LOG_INIT, 0, "import start values\nfile: %s\ntime: %g", pInitFile, initTime); if(!strcmp(data->modelData->resultFileName, pInitFile)) { errorStreamPrint(LOG_INIT, 0, "Cannot import a result file for initialization that is also the current output file <%s>.\nConsider redirecting the output result file (-r=<new_res.mat>) or renaming the result file that is used for initialization import.", pInitFile); return 1; } pError = omc_new_matlab4_reader(pInitFile, &reader); if(pError) { throwStreamPrint(threadData, "unable to read input-file <%s> [%s]", pInitFile, pError); return 1; } else { infoStreamPrint(LOG_INIT, 0, "import real variables"); for(i=0; i<mData->nVariablesReal; ++i) { pVar = omc_matlab4_find_var(&reader, mData->realVarsData[i].info.name); if(!pVar) { newVarname = mapToDymolaVars(mData->realVarsData[i].info.name); pVar = omc_matlab4_find_var(&reader, newVarname); free(newVarname); } if(pVar) { omc_matlab4_val(&(mData->realVarsData[i].attribute.start), &reader, pVar, initTime); infoStreamPrint(LOG_INIT, 0, "| %s(start=%g)", mData->realVarsData[i].info.name, mData->realVarsData[i].attribute.start); } else if((strlen(mData->realVarsData[i].info.name) > 0) && (mData->realVarsData[i].info.name[0] != '$') && (strncmp(mData->realVarsData[i].info.name, "der($", 5) != 0)) { /* skip warnings about self-generated variables */ warningStreamPrint(LOG_INIT, 0, "unable to import real variable %s from given file", mData->realVarsData[i].info.name); } } infoStreamPrint(LOG_INIT, 0, "import real parameters"); for(i=0; i<mData->nParametersReal; ++i) { pVar = omc_matlab4_find_var(&reader, mData->realParameterData[i].info.name); if(!pVar) { newVarname = mapToDymolaVars(mData->realParameterData[i].info.name); pVar = omc_matlab4_find_var(&reader, newVarname); free(newVarname); } if(pVar) { omc_matlab4_val(&(mData->realParameterData[i].attribute.start), &reader, pVar, initTime); data->simulationInfo->realParameter[i] = mData->realParameterData[i].attribute.start; infoStreamPrint(LOG_INIT, 0, "| %s(start=%g)", mData->realParameterData[i].info.name, mData->realParameterData[i].attribute.start); } else { warningStreamPrint(LOG_INIT, 0, "unable to import real parameter %s from given file", mData->realParameterData[i].info.name); } } infoStreamPrint(LOG_INIT, 0, "import real discrete"); for(i=mData->nVariablesReal-mData->nDiscreteReal; i<mData->nDiscreteReal; ++i) { pVar = omc_matlab4_find_var(&reader, mData->realParameterData[i].info.name); if(!pVar) { newVarname = mapToDymolaVars(mData->realParameterData[i].info.name); pVar = omc_matlab4_find_var(&reader, newVarname); free(newVarname); } if(pVar) { omc_matlab4_val(&(mData->realParameterData[i].attribute.start), &reader, pVar, initTime); infoStreamPrint(LOG_INIT, 0, "| %s(start=%g)", mData->realParameterData[i].info.name, mData->realParameterData[i].attribute.start); } else { warningStreamPrint(LOG_INIT, 0, "unable to import real parameter %s from given file", mData->realParameterData[i].info.name); } } infoStreamPrint(LOG_INIT, 0, "import integer parameters"); for(i=0; i<mData->nParametersInteger; ++i) { pVar = omc_matlab4_find_var(&reader, mData->integerParameterData[i].info.name); if (!pVar) { newVarname = mapToDymolaVars(mData->integerParameterData[i].info.name); pVar = omc_matlab4_find_var(&reader, newVarname); free(newVarname); } if (pVar) { omc_matlab4_val(&value, &reader, pVar, initTime); mData->integerParameterData[i].attribute.start = (modelica_integer)value; data->simulationInfo->integerParameter[i] = (modelica_integer)value; infoStreamPrint(LOG_INIT, 0, "| %s(start=%ld)", mData->integerParameterData[i].info.name, mData->integerParameterData[i].attribute.start); } else { warningStreamPrint(LOG_INIT, 0, "unable to import integer parameter %s from given file", mData->integerParameterData[i].info.name); } } infoStreamPrint(LOG_INIT, 0, "import boolean parameters"); for(i=0; i<mData->nParametersBoolean; ++i) { pVar = omc_matlab4_find_var(&reader, mData->booleanParameterData[i].info.name); if(!pVar) { newVarname = mapToDymolaVars(mData->booleanParameterData[i].info.name); pVar = omc_matlab4_find_var(&reader, newVarname); free(newVarname); } if(pVar) { omc_matlab4_val(&value, &reader, pVar, initTime); mData->booleanParameterData[i].attribute.start = (modelica_boolean)value; data->simulationInfo->booleanParameter[i] = (modelica_boolean)value; infoStreamPrint(LOG_INIT, 0, "| %s(start=%s)", mData->booleanParameterData[i].info.name, mData->booleanParameterData[i].attribute.start ? "true" : "false"); } else { warningStreamPrint(LOG_INIT, 0, "unable to import boolean parameter %s from given file", mData->booleanParameterData[i].info.name); } } omc_free_matlab4_reader(&reader); } return 0; }