// 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);
}
Beispiel #5
0
/*! \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;
}
Beispiel #6
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;
}
Beispiel #7
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);
}
Beispiel #10
0
/*! \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);
}
Beispiel #12
0
/*! \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;
}
Beispiel #13
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;
}
Beispiel #16
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);
}
Beispiel #19
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));

  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;
}
Beispiel #20
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;
}
Beispiel #21
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;
}
Beispiel #23
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);
}
Beispiel #24
0
/*! \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;
}
Beispiel #27
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;
}
Beispiel #29
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;
}