예제 #1
0
static int getNsi(char*filename, const int nsi, modelica_boolean * exTimeGrid){
  int n = 0, c;
  FILE * pFile = NULL;

  *exTimeGrid = 0;
  pFile = fopen(filename,"r");
  if(pFile == NULL){
    warningStreamPrint(LOG_STDOUT, 0, "OMC can't find the file %s.", filename);
    fclose(pFile);
    return nsi;
  }
   while(1){
    c = fgetc(pFile);
    if (c==EOF) break;
    if (c=='\n') ++n;
   }
   // check if csv file is empty!
   if (n == 0){
    warningStreamPrint(LOG_STDOUT, 0, "time grid file: %s is empty", filename);
    fclose(pFile);
    return nsi;
   }
   *exTimeGrid = 1;
   return n-1;
}
예제 #2
0
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);
  }
}
예제 #3
0
static void fmtInit(DATA* data, MEASURE_TIME* mt)
{
  mt->fmtReal = NULL;
  mt->fmtInt = NULL;
  if(measure_time_flag)
  {
    size_t len = strlen(data->modelData.modelFilePrefix);
    char* filename = (char*) malloc((len+15) * sizeof(char));
    strncpy(filename,data->modelData.modelFilePrefix,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);
  }
}
예제 #4
0
/*!
 *  pick up start values from csv for states
 *  author: Vitalij Ruge
 **/
static inline void pickUpStates(OptData* optData){
  char* cflags;
  cflags = (char*)omc_flagValue[FLAG_INPUT_FILE_STATES];

  if(cflags){
    FILE * pFile = NULL;
    pFile = fopen(cflags,"r");
    if(pFile == NULL){
      warningStreamPrint(LOG_STDOUT, 0, "OMC can't find the file %s.",cflags);
    }else{
      int c, n = 0;
      modelica_boolean b;
      while(1){
          c = fgetc(pFile);
          if (c==EOF) break;
          if (c=='\n') ++n;
      }
      // check if csv file is empty!
      if(n == 0){
        fprintf(stderr, "External input file: externalInput.csv is empty!\n"); fflush(NULL);
        EXIT(1);
      }else{
        int i, j;
        double start_value;
        char buffer[200];
        const int nReal = optData->data->modelData.nVariablesReal;
        rewind(pFile);
        for(i =0; i< n; ++i){
          fscanf(pFile, "%s", buffer);
          if (fscanf(pFile, "%lf", &start_value) <= 0) continue;

          for(j = 0, b = 0; j < nReal; ++j){
            if(!strcmp(optData->data->modelData.realVarsData[j].info.name, buffer)){
              optData->data->localData[0]->realVars[j] = start_value;
              optData->data->localData[1]->realVars[j] = start_value;
              optData->data->localData[2]->realVars[j] = start_value;
              optData->v0[i] = start_value;
              b = 1;
              continue;
            }
          }
          if(!b)
            warningStreamPrint(LOG_STDOUT, 0, "it was impossible to set %s.start %g", buffer,start_value);
          else
          printf("\n[%i]set %s.start %g", i, buffer,start_value);

        }
        fclose(pFile);
        printf("\n");
        /*update system*/
        optData->data->callback->input_function(optData->data);
        /*optData->data->callback->functionDAE(optData->data);*/
        updateDiscreteSystem(optData->data);
      }
    }
  }
}
예제 #5
0
static
void nlsKinsolInfoPrint(const char *module, const char *function, char *msg, void *user_data)
{
  if (ACTIVE_STREAM(LOG_NLS_V))
  {
    warningStreamPrint(LOG_NLS_V, 1, "%s %s:", module, function);
    warningStreamPrint(LOG_NLS_V, 0, "%s", msg);

    messageClose(LOG_NLS_V);
  }
}
예제 #6
0
/*!
 *  helper for initial_guess_optimizer (pick up clfag option)
 *  author: Vitalij Ruge
 **/
static int initial_guess_ipopt_cflag(OptData *optData, char* cflags)
{
  if(!strcmp(cflags,"const") || !strcmp(cflags,"CONST"))
  {
    int i, j;
    const int nsi = optData->dim.nsi;
    const int np = optData->dim.np;
    const int nu = optData->dim.nu;
    const int nReal = optData->dim.nReal;

    for(i = 0; i< nu; ++i )
    optData->data->simulationInfo->inputVars[i] = optData->bounds.u0[i];
    for(i = 0; i < nsi; ++i){
      for(j = 0; j < np; ++j){
        memcpy(optData->v[i][j], optData->v0, nReal*sizeof(modelica_real));
      }
    }

    infoStreamPrint(LOG_IPOPT, 0, "Using const trajectory as initial guess.");
    return 0;
  }else if(!strcmp(cflags,"sim") || !strcmp(cflags,"SIM")){

    infoStreamPrint(LOG_IPOPT, 0, "Using simulation as initial guess.");
    return 1;
  }else if(!strcmp(cflags,"file") || !strcmp(cflags,"FILE")){
    infoStreamPrint(LOG_STDOUT, 0, "Using values from file as initial guess.");
    return 2;
  }

  warningStreamPrint(LOG_STDOUT, 0, "not support ipopt_init=%s", cflags);
  return 1;

}
예제 #7
0
static inline void smallIntSolverStep(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo, const double tstop){
  long double a;
  int iter;
  int err;

  solverInfo->currentTime = data->localData[0]->timeValue;
  while(solverInfo->currentTime < tstop){
    a = 1.0;
    iter = 0;

    rotateRingBuffer(data->simulationData, 1, (void**) data->localData);
    do{
      if(data->modelData->nStates < 1){
        solverInfo->currentTime = tstop;
        data->localData[0]->timeValue = tstop;
        break;
      }
      solverInfo->currentStepSize = a*(tstop - solverInfo->currentTime);
      err = dassl_step(data, threadData, solverInfo);
      a *= 0.5;
      if(++iter >  10){
        printf("\n");
        warningStreamPrint(LOG_STDOUT, 0, "Initial guess failure at time %.12g", solverInfo->currentTime);
        assert(0);
      }
    }while(err < 0);

    data->callback->updateContinuousSystem(data, threadData);

  }
}
예제 #8
0
/*! \fn check_nonlinear_solution
 *
 *   This function checks if a non-linear system
 *   is solved. Returns a warning and 1 in case it's not
 *   solved otherwise 0.
 *
 *  \param [in]  [data]
 *  \param [in]  [printFailingSystems]
 *  \param [in]  [sysNumber] index of corresponding non-linear System
 *  \param [out] [returnValue] Returns 1 if fail otherwise 0.
 *
 *  \author wbraun
 */
int check_nonlinear_solution(DATA *data, int printFailingSystems, int sysNumber)
{
  NONLINEAR_SYSTEM_DATA* nonlinsys = data->simulationInfo->nonlinearSystemData;
  long j;
  int i = sysNumber;

  if(nonlinsys[i].solved == 0)
  {
    int index = nonlinsys[i].equationIndex, indexes[2] = {1,index};
    if (!printFailingSystems) return 1;
    warningStreamPrintWithEquationIndexes(LOG_NLS, 1, indexes, "nonlinear system %d fails: at t=%g", index, data->localData[0]->timeValue);
    if(data->simulationInfo->initial)
    {
      warningStreamPrint(LOG_NLS, 0, "proper start-values for some of the following iteration variables might help");
    }
    for(j=0; j<modelInfoGetEquation(&data->modelData->modelDataXml, (nonlinsys[i]).equationIndex).numVar; ++j) {
      int done=0;
      long k;
      const MODEL_DATA *mData = data->modelData;
      for(k=0; k<mData->nVariablesReal && !done; ++k)
      {
        if (!strcmp(mData->realVarsData[k].info.name, modelInfoGetEquation(&data->modelData->modelDataXml, (nonlinsys[i]).equationIndex).vars[j]))
        {
        done = 1;
        warningStreamPrint(LOG_NLS, 0, "[%ld] Real %s(start=%g, nominal=%g)", j+1,
                                     mData->realVarsData[k].info.name,
                                     mData->realVarsData[k].attribute.start,
                                     mData->realVarsData[k].attribute.nominal);
        }
      }
      if (!done)
      {
        warningStreamPrint(LOG_NLS, 0, "[%ld] Real %s(start=?, nominal=?)", j+1, modelInfoGetEquation(&data->modelData->modelDataXml, (nonlinsys[i]).equationIndex).vars[j]);
      }
    }
    messageCloseWarning(LOG_NLS);
    return 1;
  }
  if(nonlinsys[i].solved == 2)
  {
    nonlinsys[i].solved = 1;
    return 2;
  }


  return 0;
}
예제 #9
0
static inline void overwriteTimeGridFile(OptDataTime * time, char* filename, long double c[], const int np, const int nsi){
  int i,k;
  long double dc[np];
  const int np1 = np - 1;
  double t;
  FILE * pFile = NULL;
  pFile = fopen(filename,"r");

  fscanf(pFile, "%lf", &t);
  time->t0 = t;
  fscanf(pFile, "%lf", &t);
  time->t[0][np1] = t;
  time->dt[0] = time->t[0][np1] - time->t0;

  if(time->dt[0] <= 0){
    warningStreamPrint(LOG_STDOUT, 0, "read time grid from file fail!");
    warningStreamPrint(LOG_STDOUT, 0, "line %i: %g <= %g",0, (double)time->t[0][np1], (double)time->t0);
    EXIT(0);
  }


  for(k = 0; k < np; ++k){
    dc[k] = c[k]*time->dt[0];
    time->t[0][k] = time->t0 + dc[k];
  }

  for(i=1;i<nsi;++i){
    fscanf(pFile, "%lf", &t);
    time->t[i][np1] = t;
    time->dt[i] = time->t[i][np1] - time->t[i-1][np1];

    for(k = 0; k < np; ++k){
      dc[k] = c[k]*time->dt[i];
      time->t[i][k] = time->t[i-1][np1] + dc[k];
    }

    if(time->dt[i] <= 0){
      warningStreamPrint(LOG_STDOUT, 0, "read time grid");
      warningStreamPrint(LOG_STDOUT, 0, "line %i/%i: %g <= %g",i, nsi, (double)time->t[i][np1], (double)time->t[i-1][np1]);
      warningStreamPrint(LOG_STDOUT, 0, "failed!");
      EXIT(0);
    }

  }
  time->tf = time->t[nsi-1][np1];
  fclose(pFile);
}
예제 #10
0
static
void nlsKinsolErrorPrint(int errorCode, const char *module, const char *function, char *msg, void *userData)
{
  NLS_KINSOL_DATA *kinsolData = (NLS_KINSOL_DATA*) userData;
  DATA* data = kinsolData->userData.data;
  int sysNumber = kinsolData->userData.sysNumber;
  long eqSystemNumber = data->simulationInfo->nonlinearSystemData[sysNumber].equationIndex;

  if (ACTIVE_STREAM(LOG_NLS))
  {
    warningStreamPrint(LOG_NLS, 1, "kinsol failed for %d", modelInfoGetEquation(&data->modelData->modelDataXml,eqSystemNumber).id);
    warningStreamPrint(LOG_NLS, 0, "[module] %s | [function] %s | [error_code] %d", module, function, errorCode);
    warningStreamPrint(LOG_NLS, 0, "%s", msg);

    messageClose(LOG_NLS);
  }
}
예제 #11
0
static void fmtEmitStep(DATA* data, threadData_t *threadData, MEASURE_TIME* mt, int didEventStep)
{
  if(mt->fmtReal)
  {
    int i, flag=1;
    double tmpdbl;
    unsigned int tmpint;
    int total = data->modelData->modelDataXml.nFunctions + data->modelData->modelDataXml.nProfileBlocks;
    rt_tick(SIM_TIMER_OVERHEAD);
    rt_accumulate(SIM_TIMER_STEP);

    /* Disable time measurements if we have trouble writing to the file... */
    flag = flag && 1 == fwrite(&mt->stepNo, sizeof(unsigned int), 1, mt->fmtInt);
    mt->stepNo++;
    flag = flag && 1 == fwrite(&(data->localData[0]->timeValue), sizeof(double), 1, mt->fmtReal);
    tmpdbl = rt_accumulated(SIM_TIMER_STEP);
    flag = flag && 1 == fwrite(&tmpdbl, sizeof(double), 1, mt->fmtReal);
    flag = flag && total == fwrite(rt_ncall_arr(SIM_TIMER_FIRST_FUNCTION), sizeof(uint32_t), total, mt->fmtInt);
    for(i=0; i<data->modelData->modelDataXml.nFunctions + data->modelData->modelDataXml.nProfileBlocks; i++) {
      tmpdbl = rt_accumulated(i + SIM_TIMER_FIRST_FUNCTION);
      flag = flag && 1 == fwrite(&tmpdbl, sizeof(double), 1, mt->fmtReal);
    }
    rt_accumulate(SIM_TIMER_OVERHEAD);

    if(!flag)
    {
      warningStreamPrint(LOG_SOLVER, 0, "Disabled time measurements because the output file could not be generated: %s", strerror(errno));
      fclose(mt->fmtInt);
      fclose(mt->fmtReal);
      mt->fmtInt = NULL;
      mt->fmtReal = NULL;
    }
  }

  /* prevent emit if noEventEmit flag is used, if it's an event */
  if ((omc_flag[FLAG_NOEVENTEMIT] && didEventStep == 0) || !omc_flag[FLAG_NOEVENTEMIT]) {
    sim_result.emit(&sim_result, data, threadData);
  }
#if !defined(OMC_MINIMAL_RUNTIME)
  embedded_server_update(data->embeddedServerState, data->localData[0]->timeValue);
  if (data->real_time_sync.enabled) {
    double time = data->localData[0]->timeValue;
    int64_t res = rt_ext_tp_sync_nanosec(&data->real_time_sync.clock, (uint64_t) (data->real_time_sync.scaling*(time-data->real_time_sync.time)*1e9));
    int64_t maxLateNano = data->simulationInfo->stepSize*1e9*0.1*data->real_time_sync.scaling /* Maximum late time: 10% of step size */;
    if (res > maxLateNano) {
      int t=0,tMaxLate=0;
      const char *unit = prettyPrintNanoSec(res, &t);
      const char *unit2 = prettyPrintNanoSec(maxLateNano, &tMaxLate);
      errorStreamPrint(LOG_RT, 0, "Missed deadline at time %g; delta was %d %s (maxLate=%d %s)", time, t, unit, tMaxLate, unit2);
    }
    if (res > data->real_time_sync.maxLate) {
      data->real_time_sync.maxLate = res;
    }
  }

  printAllVarsDebug(data, 0, LOG_DEBUG);  /* ??? */
#endif
}
예제 #12
0
/*! \fn damping_heuristic
 *
 *  first damping heuristic:
 *  x_increment will be halved until the Euclidean norm of the residual function
 *  is smaller than the Euclidean norm of the current point
 *
 *  treshold for damping = 0.01
 *  compiler flag: -newton = damped
 */
void damping_heuristic(double* x, int(*f)(int*, double*, double*, void*, int),
    double current_fvec_enorm, int* n, double* fvec, double* lambda, int* k, DATA_NEWTON* solverData, void* userdata)
{
  int i,j=0;
  double enorm_new, treshold = 1e-2;

  /* calculate new function values */
  (*f)(n, solverData->x_new, fvec, userdata, 1);
  solverData->nfev++;

  enorm_new=enorm_(n,fvec);

  if (enorm_new >= current_fvec_enorm)
    infoStreamPrint(LOG_NLS_V, 1, "Start Damping: enorm_new : %e; current_fvec_enorm: %e ", enorm_new, current_fvec_enorm);

  while (enorm_new >= current_fvec_enorm)
  {
    j++;

    *lambda*=0.5;


    for (i=0; i<*n; i++)
      solverData->x_new[i]=x[i]-*lambda*solverData->x_increment[i];


    /* calculate new function values */
    (*f)(n, solverData->x_new, fvec, userdata, 1);
    solverData->nfev++;

    enorm_new=enorm_(n,fvec);

    if (*lambda <= treshold)
    {
      warningStreamPrint(LOG_NLS_V, 0, "Warning: lambda reached a threshold.");

      /* if damping is without success, trying full newton step; after 5 full newton steps try a very little step */
      if (*k >= 5)
        for (i=0; i<*n; i++)
          solverData->x_new[i]=x[i]-*lambda*solverData->x_increment[i];
      else
        for (i=0; i<*n; i++)
          solverData->x_new[i]=x[i]-solverData->x_increment[i];

      /* calculate new function values */
      (*f)(n, solverData->x_new, fvec, userdata, 1);
      solverData->nfev++;

      (*k)++;

      break;
    }
  }

  *lambda = 1;

  messageClose(LOG_NLS_V);
}
예제 #13
0
/* finish sparse matrix, by fixing colprts */
static void finishSparseColPtr(SlsMat mat)
{
  int i;
  /* finish matrix colptrs */
  mat->colptrs[mat->N] = mat->NNZ;
  for(i=1; i<mat->N+1; ++i){
    if (mat->colptrs[i] == 0){
      warningStreamPrint(LOG_STDOUT, 0, "##KINSOL## Jac row %d singular. See LOG_NLS for more infomation.", i);
      mat->colptrs[i] = mat->colptrs[i-1];
    }
  }
}
예제 #14
0
static void retrySimulationStep(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo)
{
  /* reduce step size by a half and try again */
  solverInfo->laststep = solverInfo->currentTime - solverInfo->laststep;

  /* restore old values and try another step with smaller step-size by dassl*/
  restoreOldValues(data);
  solverInfo->currentTime = data->localData[0]->timeValue;
  overwriteOldSimulationData(data);
  updateDiscreteSystem(data, threadData);
  warningStreamPrint(LOG_STDOUT, 0, "Integrator attempt to handle a problem with a called assert.");
  solverInfo->didEventStep = 1;
}
예제 #15
0
/*! \fn solveLinearSystem
 *
 *  function solves linear system J*(x_{n+1} - x_n) = f using lapack
 */
int solveLinearSystem(int* n, int* iwork, double* fvec, double *fjac, DATA_NEWTON* solverData)
{
  int i, nrsh=1, lapackinfo;
  char trans = 'N';

  /* if no factorization is given, calculate it */
  if (solverData->factorization == 0)
  {
    /* solve J*(x_{n+1} - x_n)=f */
    dgetrf_(n, n, fjac, n, iwork, &lapackinfo);
    solverData->factorization = 1;
    dgetrs_(&trans, n, &nrsh, fjac, n, iwork, fvec, n, &lapackinfo);
  }
  else
  {
    dgetrs_(&trans, n, &nrsh, fjac, n, iwork, fvec, n, &lapackinfo);
  }

  if(lapackinfo > 0)
  {
    warningStreamPrint(LOG_NLS, 0, "Jacobian Matrix singular!");
    return -1;
  }
  else if(lapackinfo < 0)
  {
    warningStreamPrint(LOG_NLS, 0, "illegal  input in argument %d", (int)lapackinfo);
    return -1;
  }
  else
  {
    /* save solution of J*(x_{n+1} - x_n)=f */
    memcpy(solverData->x_increment, fvec, *n*sizeof(double));
  }

  return 0;
}
예제 #16
0
/*! \fn calculatingErrors
 *
 *  function scales the residual vector using the jacobian (heuristic)
 */
void scaling_residual_vector(DATA_NEWTON* solverData)
{
  int i,j,k;
  for(i=0, k=0; i<solverData->n; i++)
  {
    solverData->resScaling[i] = 0.0;
    for(j=0; j<solverData->n; j++, ++k)
    {
      solverData->resScaling[i] = fmax(fabs(solverData->fjac[k]), solverData->resScaling[i]);
    }
    if(solverData->resScaling[i] <= 0.0){
      warningStreamPrint(LOG_NLS_V, 1, "Jacobian matrix is singular.");
      solverData->resScaling[i] = 1e-16;
    }
    solverData->fvecScaled[i] = solverData->fvec[i] / solverData->resScaling[i];
  }
}
예제 #17
0
/*! \fn check_mixed_solutions
 *   This function checks whether some of the mixed systems
 *   are failed to solve. If one is failed it returns 1 otherwise 0.
 *
 *  \param [in]  [data]
 *  \param [in]  [printFailingSystems]
 *
 *  \author wbraun
 */
int check_mixed_solutions(DATA *data, int printFailingSystems)
{
  MIXED_SYSTEM_DATA* system = data->simulationInfo->mixedSystemData;
  int i, j, retVal=0;

  for(i=0; i<data->modelData->nMixedSystems; ++i)
    if(system[i].solved == 0)
    {
      retVal = 1;
      if(printFailingSystems && ACTIVE_WARNING_STREAM(LOG_NLS))
      {
        warningStreamPrint(LOG_NLS, 1, "mixed system fails: %d at t=%g", modelInfoGetEquation(&data->modelData->modelDataXml, system->equationIndex).id, data->localData[0]->timeValue);
        messageClose(LOG_NLS);
      }
    }

  return retVal;
}
예제 #18
0
/*! \fn updateInnerEquation
 *
 *  This function updates inner equation with the current x.
 *
 *  \param [ref] [data]
 *         [in]  [sysNumber] index of corresponding non-linear system
 */
int updateInnerEquation(void **dataIn, int sysNumber, int discrete)
{
  DATA *data = (DATA*) ((void**)dataIn[0]);
  threadData_t *threadData = (threadData_t*) ((void**)dataIn[1]);

  NONLINEAR_SYSTEM_DATA* nonlinsys = &(data->simulationInfo->nonlinearSystemData[sysNumber]);
  int success = 0;

  /* solve non continuous at discrete points*/
  if(discrete)
  {
    data->simulationInfo->solveContinuous = 0;
  }

  /* try */
#ifndef OMC_EMCC
  MMC_TRY_INTERNAL(simulationJumpBuffer)
#endif

  /* call residual function */
  nonlinsys->residualFunc((void*) dataIn, nonlinsys->nlsx, nonlinsys->resValues, (int*)&nonlinsys->size);

  /* replace extrapolated values by current x for discrete step */
  memcpy(nonlinsys->nlsxExtrapolation, nonlinsys->nlsx, nonlinsys->size*(sizeof(double)));

  success = 1;
  /*catch */
#ifndef OMC_EMCC
  MMC_CATCH_INTERNAL(simulationJumpBuffer)
#endif

  if (!success)
  {
    warningStreamPrint(LOG_STDOUT, 0, "Non-Linear Solver try to handle a problem with a called assert.");
  }

  if(discrete)
  {
    data->simulationInfo->solveContinuous = 1;
  }

  return success;
}
예제 #19
0
static void fmtEmitStep(DATA* data, threadData_t *threadData, MEASURE_TIME* mt, int didEventStep)
{
  if(mt->fmtReal)
  {
    int i, flag=1;
    double tmpdbl;
    unsigned int tmpint;
    int total = data->modelData.modelDataXml.nFunctions + data->modelData.modelDataXml.nProfileBlocks;
    rt_tick(SIM_TIMER_OVERHEAD);
    rt_accumulate(SIM_TIMER_STEP);

    /* Disable time measurements if we have trouble writing to the file... */
    flag = flag && 1 == fwrite(&mt->stepNo, sizeof(unsigned int), 1, mt->fmtInt);
    mt->stepNo++;
    flag = flag && 1 == fwrite(&(data->localData[0]->timeValue), sizeof(double), 1, mt->fmtReal);
    tmpdbl = rt_accumulated(SIM_TIMER_STEP);
    flag = flag && 1 == fwrite(&tmpdbl, sizeof(double), 1, mt->fmtReal);
    flag = flag && total == fwrite(rt_ncall_arr(SIM_TIMER_FIRST_FUNCTION), sizeof(uint32_t), total, mt->fmtInt);
    for(i=0; i<data->modelData.modelDataXml.nFunctions + data->modelData.modelDataXml.nProfileBlocks; i++) {
      tmpdbl = rt_accumulated(i + SIM_TIMER_FIRST_FUNCTION);
      flag = flag && 1 == fwrite(&tmpdbl, sizeof(double), 1, mt->fmtReal);
    }
    rt_accumulate(SIM_TIMER_OVERHEAD);

    if(!flag)
    {
      warningStreamPrint(LOG_SOLVER, 0, "Disabled time measurements because the output file could not be generated: %s", strerror(errno));
      fclose(mt->fmtInt);
      fclose(mt->fmtReal);
      mt->fmtInt = NULL;
      mt->fmtReal = NULL;
    }
  }

  /* prevent emit if noEventEmit flag is used, if it's an event */
  if ((omc_flag[FLAG_NOEVENTEMIT] && didEventStep == 0) || !omc_flag[FLAG_NOEVENTEMIT])
  {
    sim_result.emit(&sim_result, data, threadData);
  }

  printAllVarsDebug(data, 0, LOG_DEBUG);  /* ??? */
}
예제 #20
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;


  rt_ext_tp_tick(&nonlinsys->totalTimeClock);

  if(data->simulationInfo.discreteCall)
  {
    double *fvec = malloc(sizeof(double)*nonlinsys->size);
    int success = 0;

#ifndef OMC_EMCC
    /* try */
    MMC_TRY_INTERNAL(simulationJumpBuffer)
#endif

    ((DATA*)data)->simulationInfo.solveContinuous = 0;
    nonlinsys->residualFunc((void*) dataAndThreadData, nonlinsys->nlsx, fvec, (int*)&nonlinsys->size);
    ((DATA*)data)->simulationInfo.solveContinuous = 1;

    success = 1;
#ifndef OMC_EMCC
    /*catch */
    MMC_CATCH_INTERNAL(simulationJumpBuffer)
#endif
    if (!success)
    {
      warningStreamPrint(LOG_STDOUT, 0, "Non-Linear Solver try to handle a problem with a called assert.");
    }

    free(fvec);
  }
예제 #21
0
int setLogFormat(int argc, char** argv)
{
  const char* value = getOption(FLAG_NAME[FLAG_LOG_FORMAT], argc, argv);
  if (NULL == value) {
    value = getFlagValue(FLAG_NAME[FLAG_LOG_FORMAT], argc, argv);
  }

  if (NULL != value) {
    if (0 == strcmp(value, "xml")) {
      setStreamPrintXML(1);
    } else if (0 == strcmp(value, "xmltcp")) {
      setStreamPrintXML(2);
    } else if (0 == strcmp(value, "text")) {
      setStreamPrintXML(0);
    } else {
      warningStreamPrint(LOG_STDOUT, 0, "invalid command line option: -logFormat=%s, expected text, xml, or xmltcp", value);
      return 1;
    }
  }
  return 0;
}
예제 #22
0
/* pick up information(nStates...) from model data to optimizer struct
 * author: Vitalij Ruge
 */
static inline void pickUpDim(OptDataDim * dim, DATA* data, OptDataTime * time){

  char * cflags = NULL;
  cflags = (char*)omc_flagValue[FLAG_OPTIMIZER_NP];
  if(cflags){
    dim->np = atoi(cflags);
    if(dim->np != 1 && dim->np!=3){
      warningStreamPrint(LOG_STDOUT, 0, "FLAG_OPTIZER_NP is %i. Currently optimizer support only 1 and 3.\nFLAG_OPTIZER_NP set of 3", dim->np);
      dim->np = 3;
    }
  }else
    dim->np = 3; /*ToDo*/
  dim->nx = data->modelData.nStates;
  dim->nu = data->modelData.nInputVars;
  dim->nv = dim->nx + dim->nu;
  dim->nc = data->modelData.nOptimizeConstraints;
  dim->ncf = data->modelData.nOptimizeFinalConstraints;
  dim->nJ = dim->nx + dim->nc;
  dim->nJ2 = dim->nJ + 2;
  dim->nReal = data->modelData.nVariablesReal;

  cflags = (char*)omc_flagValue[FLAG_OPTIMIZER_TGRID];
  data->callback->getTimeGrid(data, &dim->nsi, &time->tt);
  time->model_grid = (modelica_boolean)(dim->nsi > 0);

  if(!time->model_grid)
    dim->nsi = data->simulationInfo.numSteps;

  if(cflags)
    dim->nsi = getNsi(cflags, dim->nsi, &dim->exTimeGrid);

  dim->nt = dim->nsi*dim->np;
  dim->NV = dim->nt*dim->nv;
  dim->NRes = dim->nt*dim->nJ + dim->ncf;
  dim->index_con = dim->nReal - (dim->nc + dim->ncf);
  dim->index_conf = dim->index_con + dim->nc;
  assert(dim->nt > 0);
}
예제 #23
0
int nlsKinsolSolve(DATA *data, threadData_t *threadData, int sysNumber)
{
  NONLINEAR_SYSTEM_DATA *nlsData = &(data->simulationInfo->nonlinearSystemData[sysNumber]);
  NLS_KINSOL_DATA *kinsolData = (NLS_KINSOL_DATA*)nlsData->solverData;
  long eqSystemNumber = nlsData->equationIndex;
  int indexes[2] = {1,eqSystemNumber};

  int flag, i;
  long nFEval;
  int success = 0;
  int retry = 0;
  double *xStart = NV_DATA_S(kinsolData->initialGuess);
  double *xScaling = NV_DATA_S(kinsolData->xScale);
  double *fScaling = NV_DATA_S(kinsolData->fScale);
  double fNormValue;


  /* set user data */
  kinsolData->userData.data = data;
  kinsolData->userData.threadData = threadData;
  kinsolData->userData.sysNumber = sysNumber;

  /* reset configuration settings */
  nlsKinsolConfigSetup(kinsolData);

  infoStreamPrint(LOG_NLS, 0, "------------------------------------------------------");
  infoStreamPrintWithEquationIndexes(LOG_NLS, 1, indexes, "Start solving non-linear system >>%ld<< using Kinsol solver at time %g", eqSystemNumber, data->localData[0]->timeValue);

  nlsKinsolResetInitial(data, kinsolData, nlsData, INITIAL_EXTRAPOLATION);

  /* set x scaling */
  nlsKinsolXScaling(data, kinsolData, nlsData, SCALING_NOMINALSTART);

  /* set f scaling */
  _omc_fillVector(_omc_createVector(nlsData->size, fScaling), 1.);

  /*  */
  do{
    /* dump configuration */
    nlsKinsolConfigPrint(kinsolData, nlsData);

    flag = KINSol(kinsolData->kinsolMemory,           /* KINSol memory block */
                  kinsolData->initialGuess,           /* initial guess on input; solution vector */
                  kinsolData->kinsolStrategy,         /* global strategy choice */
                  kinsolData->xScale,                 /* scaling vector, for the variable cc */
                  kinsolData->fScale);                /* scaling vector for function values fval */

    infoStreamPrint(LOG_NLS_V, 0, "KINSol finished with errorCode %d.", flag);
    /* check for errors */
    if(flag < 0)
    {
      retry = nlsKinsolErrorHandler(flag, data, nlsData, kinsolData);
    }

    /* solution found */
    if ((flag == KIN_SUCCESS) || (flag == KIN_INITIAL_GUESS_OK) || (flag ==  KIN_STEP_LT_STPTOL))
    {
      success = 1;
    }
    kinsolData->retries++;

    /* write statistics */
    KINGetNumNonlinSolvIters(kinsolData->kinsolMemory, &nFEval);
    nlsData->numberOfIterations += nFEval;
    nlsData->numberOfFEval += kinsolData->countResCalls;

    infoStreamPrint(LOG_NLS_V, 0, "Next try? success = %d, retry = %d, retries = %d = %s\n", success, retry, kinsolData->retries,!success && !(retry<1) && kinsolData->retries<RETRY_MAX ? "true" : "false" );
  }while(!success && !(retry<0) && kinsolData->retries < RETRY_MAX);

  /* solution found */
  if (success)
  {
    /* check if solution really solves the residuals */
    nlsKinsolResiduals(kinsolData->initialGuess, kinsolData->fRes, &kinsolData->userData);
    fNormValue = N_VWL2Norm(kinsolData->fRes, kinsolData->fRes);
    infoStreamPrint(LOG_NLS, 0, "scaled Euclidean norm of F(u) = %e", fNormValue);
    if (FTOL_WITH_LESS_ACCURANCY<fNormValue)
    {
      warningStreamPrint(LOG_NLS, 0, "False positive solution. FNorm is too small.");
      success = 0;
    }
    else /* solved system for reuse linear solver information */
    {
      kinsolData->solved = 1;
    }
    /* copy solution */
    memcpy(nlsData->nlsx, xStart, nlsData->size*(sizeof(double)));
    /* dump solution */
    if(ACTIVE_STREAM(LOG_NLS))
    {
      infoStreamPrintWithEquationIndexes(LOG_NLS, 1, indexes, "solution for NLS %ld at t=%g", eqSystemNumber, kinsolData->userData.data->localData[0]->timeValue);
      for(i=0; i<nlsData->size; ++i)
      {
        infoStreamPrintWithEquationIndexes(LOG_NLS, 0, indexes, "[%d] %s = %g", i+1, modelInfoGetEquation(&kinsolData->userData.data->modelData->modelDataXml,eqSystemNumber).vars[i], nlsData->nlsx[i]);
      }
      messageClose(LOG_NLS);
    }
  }

  messageClose(LOG_NLS);

  return success;
}
예제 #24
0
static
int nlsKinsolErrorHandler(int errorCode, DATA *data, NONLINEAR_SYSTEM_DATA *nlsData, NLS_KINSOL_DATA *kinsolData)
{
  int retValue, i, retValue2=0;
  double fNorm;
  double *xStart = NV_DATA_S(kinsolData->initialGuess);
  double *xScaling = NV_DATA_S(kinsolData->xScale);

  /* check what kind of error
   *   retValue < 0 -> a non recoverable issue
   *   retValue == 1 -> try with other settings
   */
  KINSetNoInitSetup(kinsolData->kinsolMemory, FALSE);

  switch(errorCode)
  {
  case KIN_MEM_NULL:
  case KIN_ILL_INPUT:
  case KIN_NO_MALLOC:
    errorStreamPrint(LOG_NLS, 0, "kinsol has a serious memory issue ERROR %d\n", errorCode);
    return errorCode;
    break;
  /* just retry with new initial guess */
  case KIN_MXNEWT_5X_EXCEEDED:
    warningStreamPrint(LOG_NLS, 0, "initial guess was too far away from the solution. Try again.\n");
    return 1;
    break;
  /* just retry without line search */
  case KIN_LINESEARCH_NONCONV:
    warningStreamPrint(LOG_NLS, 0, "kinsols line search did not convergence. Try without.\n");
    kinsolData->kinsolStrategy = KIN_NONE;
    return 1;
  /* maybe happened because of an out-dated factorization, so just retry  */
  case KIN_LSETUP_FAIL:
  case KIN_LSOLVE_FAIL:
    warningStreamPrint(LOG_NLS, 0, "kinsols matrix need new factorization. Try again.\n");
    KINKLUReInit(kinsolData->kinsolMemory, kinsolData->size, kinsolData->nnz, 2);
    return 1;
  case KIN_MAXITER_REACHED:
  case KIN_REPTD_SYSFUNC_ERR:
    warningStreamPrint(LOG_NLS, 0, "kinsols runs into issues retry with differnt configuration.\n");
    retValue = 1;
    break;
  default:
    errorStreamPrint(LOG_STDOUT, 0, "kinsol has a serious solving issue ERROR %d\n", errorCode);
    return errorCode;
    break;
  }

  /* check if the current solution is sufficient anyway */
  KINGetFuncNorm(kinsolData->kinsolMemory, &fNorm);
  if (fNorm<FTOL_WITH_LESS_ACCURANCY)
  {
    warningStreamPrint(LOG_NLS, 0, "Move forward with a less accurate solution.");
    KINSetFuncNormTol(kinsolData->kinsolMemory, FTOL_WITH_LESS_ACCURANCY);
    KINSetScaledStepTol(kinsolData->kinsolMemory, FTOL_WITH_LESS_ACCURANCY);
    retValue2 = 1;
  }
  else
  {
    warningStreamPrint(LOG_NLS, 0, "Current status of fx = %f", fNorm);
  }

  /* reconfigure kinsol for an other try */
  if (retValue == 1 && !retValue2)
  {
    switch(kinsolData->retries)
    {
    case 0:
      /* try without x scaling  */
      nlsKinsolXScaling(data, kinsolData, nlsData, SCALING_ONES);
      break;
    case 1:
      /* try without line-search and oldValues */
      nlsKinsolResetInitial(data, kinsolData, nlsData, INITIAL_OLDVALUES);
      kinsolData->kinsolStrategy = KIN_LINESEARCH;
      break;
    case 2:
      /* try without line-search and oldValues */
      nlsKinsolResetInitial(data, kinsolData, nlsData, INITIAL_EXTRAPOLATION);
      kinsolData->kinsolStrategy = KIN_NONE;
      break;
    case 3:
      /* try with exact newton  */
      nlsKinsolXScaling(data, kinsolData, nlsData, SCALING_NOMINALSTART);
      nlsKinsolResetInitial(data, kinsolData, nlsData, INITIAL_EXTRAPOLATION);
      KINSetMaxSetupCalls(kinsolData->kinsolMemory, 1);
      kinsolData->kinsolStrategy = KIN_LINESEARCH;
      break;
    case 4:
      /* try with exact newton to with out x scaling values */
      nlsKinsolXScaling(data, kinsolData, nlsData, SCALING_ONES);
      nlsKinsolResetInitial(data, kinsolData, nlsData, INITIAL_OLDVALUES);
      KINSetMaxSetupCalls(kinsolData->kinsolMemory, 1);
      kinsolData->kinsolStrategy = KIN_LINESEARCH;
      break;
    default:
      retValue = 0;
      break;
    }
  }

  return retValue+retValue2;
}
예제 #25
0
/*! \fn solve non-linear system with hybrd method
 *
 *  \param [in]  [data]
 *               [sysNumber] index of the corresponing non-linear system
 *
 *  \author wbraun
 */
int solveHybrd(DATA *data, threadData_t *threadData, int sysNumber)
{
  NONLINEAR_SYSTEM_DATA* systemData = &(data->simulationInfo->nonlinearSystemData[sysNumber]);
  DATA_HYBRD* solverData = (DATA_HYBRD*)systemData->solverData;
  /*
   * We are given the number of the non-linear system.
   * We want to look it up among all equations.
   */
  int eqSystemNumber = systemData->equationIndex;

  int i, j;
  integer iflag = 1;
  double xerror, xerror_scaled;
  int success = 0;
  double local_tol = 1e-12;
  double initial_factor = solverData->factor;
  int nfunc_evals = 0;
  int continuous = 1;
  int nonContinuousCase = 0;

  int giveUp = 0;
  int retries = 0;
  int retries2 = 0;
  int retries3 = 0;
  int assertCalled = 0;
  int assertRetries = 0;
  int assertMessage = 0;

  modelica_boolean* relationsPreBackup;

  struct dataAndSys dataAndSysNumber = {data, threadData, sysNumber};

  relationsPreBackup = (modelica_boolean*) malloc(data->modelData->nRelations*sizeof(modelica_boolean));

  solverData->numberOfFunctionEvaluations = 0;
  /* debug output */
  if(ACTIVE_STREAM(LOG_NLS_V))
  {
    int indexes[2] = {1,eqSystemNumber};
    infoStreamPrintWithEquationIndexes(LOG_NLS_V, 1, indexes, "start solving non-linear system >>%d<< at time %g", eqSystemNumber, data->localData[0]->timeValue);
    for(i=0; i<solverData->n; i++)
    {
      infoStreamPrint(LOG_NLS_V, 1, "%d. %s = %f", i+1, modelInfoGetEquation(&data->modelData->modelDataXml,eqSystemNumber).vars[i], systemData->nlsx[i]);
      infoStreamPrint(LOG_NLS_V, 0, "    nominal = %f\nold = %f\nextrapolated = %f",
          systemData->nominal[i], systemData->nlsxOld[i], systemData->nlsxExtrapolation[i]);
      messageClose(LOG_NLS_V);
    }
    messageClose(LOG_NLS_V);
  }

  /* set x vector */
  if(data->simulationInfo->discreteCall)
    memcpy(solverData->x, systemData->nlsx, solverData->n*(sizeof(double)));
  else
    memcpy(solverData->x, systemData->nlsxExtrapolation, solverData->n*(sizeof(double)));

  for(i=0; i<solverData->n; i++){
    solverData->xScalefactors[i] = fmax(fabs(solverData->x[i]), systemData->nominal[i]);
  }

  /* start solving loop */
  while(!giveUp && !success)
  {
    for(i=0; i<solverData->n; i++)
      solverData->xScalefactors[i] = fmax(fabs(solverData->x[i]), systemData->nominal[i]);

    /* debug output */
    if(ACTIVE_STREAM(LOG_NLS_V)) {
      printVector(solverData->xScalefactors, &(solverData->n), LOG_NLS_V, "scaling factors x vector");
      printVector(solverData->x, &(solverData->n), LOG_NLS_V, "Iteration variable values");
    }

    /* Scaling x vector */
    if(solverData->useXScaling) {
      for(i=0; i<solverData->n; i++) {
        solverData->x[i] = (1.0/solverData->xScalefactors[i]) * solverData->x[i];
      }
    }

    /* debug output */
    if(ACTIVE_STREAM(LOG_NLS_V))
    {
      printVector(solverData->x, &solverData->n, LOG_NLS_V, "Iteration variable values (scaled)");
    }

    /* set residual function continuous
     */
    if(continuous) {
      ((DATA*)data)->simulationInfo->solveContinuous = 1;
    } else {
      ((DATA*)data)->simulationInfo->solveContinuous = 0;
    }

    giveUp = 1;

    /* try */
    {
      int success = 0;
#ifndef OMC_EMCC
      MMC_TRY_INTERNAL(simulationJumpBuffer)
#endif
      hybrj_(wrapper_fvec_hybrj, &solverData->n, solverData->x,
          solverData->fvec, solverData->fjac, &solverData->ldfjac, &solverData->xtol,
          &solverData->maxfev, solverData->diag, &solverData->mode, &solverData->factor,
          &solverData->nprint, &solverData->info, &solverData->nfev, &solverData->njev, solverData->r__,
          &solverData->lr, solverData->qtf, solverData->wa1, solverData->wa2,
          solverData->wa3, solverData->wa4, (void*) &dataAndSysNumber);

      success = 1;
      if(assertCalled)
      {
        infoStreamPrint(LOG_NLS, 0, "After assertions failed, found a solution for which assertions did not fail.");
        /* re-scaling x vector */
        for(i=0; i<solverData->n; i++){
          if(solverData->useXScaling)
            systemData->nlsxOld[i] = solverData->x[i]*solverData->xScalefactors[i];
          else
            systemData->nlsxOld[i] = solverData->x[i];
        }
      }
      assertRetries = 0;
      assertCalled = 0;
      success = 1;
#ifndef OMC_EMCC
      MMC_CATCH_INTERNAL(simulationJumpBuffer)
#endif
      /* catch */
      if (!success)
      {
        if (!assertMessage)
        {
          if (ACTIVE_WARNING_STREAM(LOG_STDOUT))
          {
            if(data->simulationInfo->initial)
              warningStreamPrint(LOG_STDOUT, 1, "While solving non-linear system an assertion failed during initialization.");
            else
              warningStreamPrint(LOG_STDOUT, 1, "While solving non-linear system an assertion failed at time %g.", data->localData[0]->timeValue);
            warningStreamPrint(LOG_STDOUT, 0, "The non-linear solver tries to solve the problem that could take some time.");
            warningStreamPrint(LOG_STDOUT, 0, "It could help to provide better start-values for the iteration variables.");
            if (!ACTIVE_STREAM(LOG_NLS))
              warningStreamPrint(LOG_STDOUT, 0, "For more information simulate with -lv LOG_NLS");
            messageClose(LOG_STDOUT);
          }
          assertMessage = 1;
        }

        solverData->info = -1;
        xerror_scaled = 1;
        xerror = 1;
        assertCalled = 1;
      }
    }

    /* set residual function continuous */
    if(continuous)
    {
      ((DATA*)data)->simulationInfo->solveContinuous = 0;
    }
    else
    {
      ((DATA*)data)->simulationInfo->solveContinuous = 1;
    }

    /* re-scaling x vector */
    if(solverData->useXScaling)
      for(i=0; i<solverData->n; i++)
        solverData->x[i] = solverData->x[i]*solverData->xScalefactors[i];

    /* check for proper inputs */
    if(solverData->info == 0) {
      printErrorEqSyst(IMPROPER_INPUT, modelInfoGetEquation(&data->modelData->modelDataXml, eqSystemNumber),
          data->localData[0]->timeValue);
    }

    if(solverData->info != -1)
    {
      /* evaluate with discontinuities */
      if(data->simulationInfo->discreteCall){
        int scaling = solverData->useXScaling;
        int success = 0;
        if(scaling)
          solverData->useXScaling = 0;

        ((DATA*)data)->simulationInfo->solveContinuous = 0;

        /* try */
#ifndef OMC_EMCC
        MMC_TRY_INTERNAL(simulationJumpBuffer)
#endif
        wrapper_fvec_hybrj(&solverData->n, solverData->x, solverData->fvec, solverData->fjac, &solverData->ldfjac, &iflag, (void*) &dataAndSysNumber);
        success = 1;
#ifndef OMC_EMCC
        MMC_CATCH_INTERNAL(simulationJumpBuffer)
#endif
        /* catch */
        if (!success)
        {
          warningStreamPrint(LOG_STDOUT, 0, "Non-Linear Solver try to handle a problem with a called assert.");

          solverData->info = -1;
          xerror_scaled = 1;
          xerror = 1;
          assertCalled = 1;
        }

        if(scaling)
          solverData->useXScaling = 1;

        updateRelationsPre(data);
      }
    }

    if(solverData->info != -1)
    {
      /* scaling residual vector */
      {
        int l=0;
        for(i=0; i<solverData->n; i++){
          solverData->resScaling[i] = 1e-16;
          for(j=0; j<solverData->n; j++){
            solverData->resScaling[i] = (fabs(solverData->fjacobian[l]) > solverData->resScaling[i])
                    ? fabs(solverData->fjacobian[l]) : solverData->resScaling[i];
            l++;
          }
          solverData->fvecScaled[i] = solverData->fvec[i] * (1 / solverData->resScaling[i]);
        }
        /* debug output */
        if(ACTIVE_STREAM(LOG_NLS_V))
        {
          infoStreamPrint(LOG_NLS_V, 1, "scaling factors for residual vector");
          for(i=0; i<solverData->n; i++)
          {
            infoStreamPrint(LOG_NLS_V, 1, "scaled residual [%d] : %.20e", i, solverData->fvecScaled[i]);
            infoStreamPrint(LOG_NLS_V, 0, "scaling factor [%d] : %.20e", i, solverData->resScaling[i]);
            messageClose(LOG_NLS_V);
          }
          messageClose(LOG_NLS_V);
        }

        /* debug output */
        if(ACTIVE_STREAM(LOG_NLS_JAC))
        {
          char buffer[4096];

          infoStreamPrint(LOG_NLS_JAC, 1, "jacobian matrix [%dx%d]", (int)solverData->n, (int)solverData->n);
          for(i=0; i<solverData->n; i++)
          {
            buffer[0] = 0;
            for(j=0; j<solverData->n; j++)
              sprintf(buffer, "%s%10g ", buffer, solverData->fjacobian[i*solverData->n+j]);
            infoStreamPrint(LOG_NLS_JAC, 0, "%s", buffer);
          }
          messageClose(LOG_NLS_JAC);
        }

        /* check for error  */
        xerror_scaled = enorm_(&solverData->n, solverData->fvecScaled);
        xerror = enorm_(&solverData->n, solverData->fvec);
      }
    }

    /* reset non-contunuousCase */
    if(nonContinuousCase && xerror > local_tol && xerror_scaled > local_tol)
    {
      memcpy(data->simulationInfo->relationsPre, relationsPreBackup, sizeof(modelica_boolean)*data->modelData->nRelations);
      nonContinuousCase = 0;
    }

    if(solverData->info < 4 && xerror > local_tol && xerror_scaled > local_tol)
      solverData->info = 4;

    /* solution found */
    if(solverData->info == 1 || xerror <= local_tol || xerror_scaled <= local_tol)
    {
      int scaling;

      success = 1;
      nfunc_evals += solverData->nfev;
      if(ACTIVE_STREAM(LOG_NLS))
      {
        int indexes[2] = {1,eqSystemNumber};
        /* output solution */
        infoStreamPrintWithEquationIndexes(LOG_NLS, 1, indexes, "solution for NLS %d at t=%g", eqSystemNumber, data->localData[0]->timeValue);
        for(i=0; i<solverData->n; ++i)
        {
          infoStreamPrint(LOG_NLS, 0, "[%d] %s = %g", i+1, modelInfoGetEquation(&data->modelData->modelDataXml,eqSystemNumber).vars[i],  solverData->x[i]);
        }
        messageClose(LOG_NLS);
      }else if (ACTIVE_STREAM(LOG_NLS_V)){
        infoStreamPrint(LOG_NLS_V, 1, "system solved");
        infoStreamPrint(LOG_NLS_V, 0, "%d retries\n%d restarts", retries, retries2+retries3);
        messageClose(LOG_NLS_V);
        printStatus(data, solverData, eqSystemNumber, &nfunc_evals, &xerror, &xerror_scaled, LOG_NLS_V);
      }
      scaling = solverData->useXScaling;
      if(scaling)
        solverData->useXScaling = 0;

      /* take the solution */
      memcpy(systemData->nlsx, solverData->x, solverData->n*(sizeof(double)));

      /* try */
      {
        int success = 0;
#ifndef OMC_EMCC
        MMC_TRY_INTERNAL(simulationJumpBuffer)
#endif
        wrapper_fvec_hybrj(&solverData->n, solverData->x, solverData->fvec, solverData->fjac, &solverData->ldfjac, &iflag, (void*) &dataAndSysNumber);
        success = 1;
#ifndef OMC_EMCC
        MMC_CATCH_INTERNAL(simulationJumpBuffer)
#endif
        /* catch */
        if (!success) {
          warningStreamPrint(LOG_STDOUT, 0, "Non-Linear Solver try to handle a problem with a called assert.");

          solverData->info = 4;
          xerror_scaled = 1;
          xerror = 1;
          assertCalled = 1;
          success = 0;
          giveUp = 0;
        }
      }
      if(scaling)
        solverData->useXScaling = 1;
    }
예제 #26
0
/*! \fn solve linear system with lapack method
 *
 *  \param [in]  [data]
 *               [sysNumber] index of the corresponding linear system
 *
 *  \author wbraun
 */
int solveLapack(DATA *data, int sysNumber)
{
  int i, j, iflag = 1;
  LINEAR_SYSTEM_DATA* systemData = &(data->simulationInfo.linearSystemData[sysNumber]);
  DATA_LAPACK* solverData = (DATA_LAPACK*)systemData->solverData;

  int success = 1;

  /* We are given the number of the linear system.
   * We want to look it up among all equations. */
  int eqSystemNumber = systemData->equationIndex;
  int indexes[2] = {1,eqSystemNumber};
  _omc_scalar residualNorm = 0;

  infoStreamPrintWithEquationIndexes(LOG_LS, 0, indexes, "Start solving Linear System %d (size %d) at time %g with Lapack Solver",
         eqSystemNumber, (int) systemData->size,
         data->localData[0]->timeValue);


  /* set data */
  _omc_setVectorData(solverData->x, systemData->x);
  _omc_setVectorData(solverData->b, systemData->b);
  _omc_setMatrixData(solverData->A, systemData->A);


  rt_ext_tp_tick(&(solverData->timeClock));
  if (0 == systemData->method) {

    /* reset matrix A */
    memset(systemData->A, 0, (systemData->size)*(systemData->size)*sizeof(double));

    /* update matrix A */
    systemData->setA(data, systemData);

    /* update vector b (rhs) */
    systemData->setb(data, systemData);
  } else {

    /* calculate jacobian -> matrix A*/
    if(systemData->jacobianIndex != -1){
      getAnalyticalJacobianLapack(data, solverData->A->data, sysNumber);
    } else {
      assertStreamPrint(data->threadData, 1, "jacobian function pointer is invalid" );
    }

    /* calculate vector b (rhs) */
    _omc_copyVector(solverData->work, solverData->x);
    wrapper_fvec_lapack(solverData->work, solverData->b, &iflag, data, sysNumber);
  }
  infoStreamPrint(LOG_LS, 0, "###  %f  time to set Matrix A and vector b.", rt_ext_tp_tock(&(solverData->timeClock)));

  /* Log A*x=b */
  if(ACTIVE_STREAM(LOG_LS_V)){
    _omc_printVector(solverData->x, "Vector old x", LOG_LS_V);
    _omc_printMatrix(solverData->A, "Matrix A", LOG_LS_V);
    _omc_printVector(solverData->b, "Vector b", LOG_LS_V);
  }

  rt_ext_tp_tick(&(solverData->timeClock));

  /* Solve system */
  dgesv_((int*) &systemData->size,
         (int*) &solverData->nrhs,
         solverData->A->data,
         (int*) &systemData->size,
         solverData->ipiv,
         solverData->b->data,
         (int*) &systemData->size,
         &solverData->info);

  infoStreamPrint(LOG_LS, 0, "Solve System: %f", rt_ext_tp_tock(&(solverData->timeClock)));

  if(solverData->info < 0)
  {
    warningStreamPrint(LOG_LS, 0, "Error solving linear system of equations (no. %d) at time %f. Argument %d illegal.", (int)systemData->equationIndex, data->localData[0]->timeValue, (int)solverData->info);
    success = 0;
  }
  else if(solverData->info > 0)
  {
    warningStreamPrint(LOG_LS, 0,
        "Failed to solve linear system of equations (no. %d) at time %f, system is singular for U[%d, %d].",
        (int)systemData->equationIndex, data->localData[0]->timeValue, (int)solverData->info+1, (int)solverData->info+1);

    success = 0;

    /* debug output */
    if (ACTIVE_STREAM(LOG_LS)){
      _omc_printMatrix(solverData->A, "Matrix U", LOG_LS);

      _omc_printVector(solverData->b, "Output vector x", LOG_LS);
    }
  }

  if (1 == success){

    if (1 == systemData->method){
      /* take the solution */
      solverData->x = _omc_addVectorVector(solverData->x, solverData->work, solverData->b);

      /* update inner equations */
      wrapper_fvec_lapack(solverData->x, solverData->work, &iflag, data, sysNumber);
      residualNorm = _omc_euclideanVectorNorm(solverData->work);
    } else {
      /* take the solution */
      _omc_copyVector(solverData->x, solverData->b);
    }

    if (ACTIVE_STREAM(LOG_LS_V)){
      infoStreamPrint(LOG_LS_V, 1, "Residual Norm %f of solution x:", residualNorm);
      infoStreamPrint(LOG_LS_V, 0, "System %d numVars %d.", eqSystemNumber, modelInfoGetEquation(&data->modelData.modelDataXml,eqSystemNumber).numVar);

      for(i = 0; i < systemData->size; ++i) {
        infoStreamPrint(LOG_LS_V, 0, "[%d] %s = %g", i+1, modelInfoGetEquation(&data->modelData.modelDataXml,eqSystemNumber).vars[i], systemData->x[i]);
      }

      messageClose(LOG_LS_V);
    }
  }

  return success;
}
예제 #27
0
/*! \fn solve linear system with UmfPack method
 *
 *  \param  [in]  [data]
 *                [sysNumber] index of the corresponding linear system
 *
 *
 * author: kbalzereit, wbraun
 */
int
solveUmfPack(DATA *data, int sysNumber)
{
    LINEAR_SYSTEM_DATA* systemData = &(data->simulationInfo.linearSystemData[sysNumber]);
    DATA_UMFPACK* solverData = (DATA_UMFPACK*)systemData->solverData;

    int i, j, status = UMFPACK_OK, success = 0, ni=0, n = systemData->size, eqSystemNumber = systemData->equationIndex, indexes[2] = {1,eqSystemNumber};

    infoStreamPrintWithEquationIndexes(LOG_LS, 0, indexes, "Start solving Linear System %d (size %d) at time %g with UMFPACK Solver",
                                       eqSystemNumber, (int) systemData->size,
                                       data->localData[0]->timeValue);


    rt_ext_tp_tick(&(solverData->timeClock));
    if (0 == systemData->method)
    {
        /* set A matrix */
        solverData->Ap[0] = 0;
        systemData->setA(data, systemData);
        solverData->Ap[solverData->n_row] = solverData->nnz;

        if (ACTIVE_STREAM(LOG_LS_V))
        {
            infoStreamPrint(LOG_LS_V, 1, "Matrix A");
            printMatrixCSR(solverData->Ap, solverData->Ai, solverData->Ax, n);
            messageClose(LOG_LS_V);
        }

        /* set b vector */
        systemData->setb(data, systemData);
    } else {

        solverData->Ap[0] = 0;
        /* calculate jacobian -> matrix A*/
        if(systemData->jacobianIndex != -1) {
            getAnalyticalJacobianUmfPack(data, sysNumber);
        } else {
            assertStreamPrint(data->threadData, 1, "jacobian function pointer is invalid" );
        }
        solverData->Ap[solverData->n_row] = solverData->nnz;

        /* calculate vector b (rhs) */
        memcpy(solverData->work, systemData->x, sizeof(double)*solverData->n_row);
        wrapper_fvec_umfpack(solverData->work, systemData->b, data, sysNumber);
    }

    infoStreamPrint(LOG_LS, 0, "###  %f  time to set Matrix A and vector b.", rt_ext_tp_tock(&(solverData->timeClock)));

    if (ACTIVE_STREAM(LOG_LS_V))
    {
        if (ACTIVE_STREAM(LOG_LS_V))
        {
            infoStreamPrint(LOG_LS_V, 1, "Old solution x:");
            for(i = 0; i < solverData->n_row; ++i)
                infoStreamPrint(LOG_LS_V, 0, "[%d] %s = %g", i+1, modelInfoGetEquation(&data->modelData.modelDataXml,eqSystemNumber).vars[i], systemData->x[i]);

            messageClose(LOG_LS_V);
        }
        infoStreamPrint(LOG_LS_V, 1, "Matrix A n_rows = %d", solverData->n_row);
        for (i=0; i<solverData->n_row; i++) {
            infoStreamPrint(LOG_LS_V, 0, "%d. Ap => %d -> %d", i, solverData->Ap[i], solverData->Ap[i+1]);
            for (j=solverData->Ap[i]; j<solverData->Ap[i+1]; j++) {
                infoStreamPrint(LOG_LS_V, 0, "A[%d,%d] = %f", i, solverData->Ai[j], solverData->Ax[j]);

            }
        }
        messageClose(LOG_LS_V);

        for (i=0; i<solverData->n_row; i++)
            infoStreamPrint(LOG_LS_V, 0, "b[%d] = %e", i, systemData->b[i]);
    }
    rt_ext_tp_tick(&(solverData->timeClock));

    /* symbolic pre-ordering of A to reduce fill-in of L and U */
    if (0 == solverData->numberSolving)
    {
        status = umfpack_di_symbolic(solverData->n_col, solverData->n_row, solverData->Ap, solverData->Ai, solverData->Ax, &(solverData->symbolic), solverData->control, solverData->info);
    }

    /* compute the LU factorization of A */
    if (0 == status) {
        status = umfpack_di_numeric(solverData->Ap, solverData->Ai, solverData->Ax, solverData->symbolic, &(solverData->numeric), solverData->control, solverData->info);
    }

    if (0 == status) {
        if (1 == systemData->method) {
            status = umfpack_di_solve(UMFPACK_A, solverData->Ap, solverData->Ai, solverData->Ax, systemData->x, systemData->b, solverData->numeric, solverData->control, solverData->info);
        } else {
            status = umfpack_di_solve(UMFPACK_Aat, solverData->Ap, solverData->Ai, solverData->Ax, systemData->x, systemData->b, solverData->numeric, solverData->control, solverData->info);
        }
    }

    if (status == UMFPACK_OK) {
        success = 1;
    }
    else if (status == UMFPACK_WARNING_singular_matrix)
    {
        if (!solveSingularSystem(systemData))
        {
            success = 1;
        }
    }
    infoStreamPrint(LOG_LS, 0, "Solve System: %f", rt_ext_tp_tock(&(solverData->timeClock)));

    /* print solution */
    if (1 == success) {

        if (1 == systemData->method) {
            /* take the solution */
            for(i = 0; i < solverData->n_row; ++i)
                systemData->x[i] += solverData->work[i];

            /* update inner equations */
            wrapper_fvec_umfpack(systemData->x, solverData->work, data, sysNumber);
        } else {
            /* the solution is automatically in x */
        }

        if (ACTIVE_STREAM(LOG_LS_V))
        {
            infoStreamPrint(LOG_LS_V, 1, "Solution x:");
            infoStreamPrint(LOG_LS_V, 0, "System %d numVars %d.", eqSystemNumber, modelInfoGetEquation(&data->modelData.modelDataXml,eqSystemNumber).numVar);

            for(i = 0; i < systemData->size; ++i)
                infoStreamPrint(LOG_LS_V, 0, "[%d] %s = %g", i+1, modelInfoGetEquation(&data->modelData.modelDataXml,eqSystemNumber).vars[i], systemData->x[i]);

            messageClose(LOG_LS_V);
        }
    }
    else
    {
        warningStreamPrint(LOG_STDOUT, 0,
                           "Failed to solve linear system of equations (no. %d) at time %f, system status %d.",
                           (int)systemData->equationIndex, data->localData[0]->timeValue, status);
    }
    solverData->numberSolving += 1;

    return success;
}
예제 #28
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;
}
예제 #29
0
/*!
 *  run optimization with ipopt
 *  author: Vitalij Ruge
 **/
static inline void optimizationWithIpopt(OptData*optData) {
    IpoptProblem nlp = NULL;

    const int NV = optData->dim.NV;
    const int NRes = optData->dim.NRes;
    const int nsi = optData->dim.nsi;
    const int np = optData->dim.np;
    const int nx = optData->dim.nx;
    const int NJ = optData->dim.nJderx;
    const int NJf = optData->dim.nJfderx;
    const int nH0 = optData->dim.nH0_;
    const int nH1 = optData->dim.nH1_;
    const int njac = np*(NJ*nsi + nx*(np*nsi - 1)) + NJf;
    const int nhess = (nsi*np-1)*nH0+nH1;

    Number * Vmin = optData->bounds.Vmin;
    Number * Vmax = optData->bounds.Vmax;
    Number * gmin = optData->ipop.gmin;
    Number * gmax = optData->ipop.gmax;
    Number * vopt = optData->ipop.vopt;
    Number * mult_g = optData->ipop.mult_g;
    Number * mult_x_L = optData->ipop.mult_x_L;
    Number * mult_x_U = optData->ipop.mult_x_U;
    Number obj;

    char *cflags;
    int max_iter = 5000;
    int res = 0;

    nlp = CreateIpoptProblem(NV, Vmin, Vmax,
                             NRes, gmin, gmax, njac, nhess, 0, &evalfF,
                             &evalfG, &evalfDiffF, &evalfDiffG, &ipopt_h);

    /********************************************************************/
    /*******************       ipopt flags       ************************/
    /********************************************************************/

    /*tol */
    AddIpoptNumOption(nlp, "tol", optData->data->simulationInfo.tolerance);
    AddIpoptStrOption(nlp, "evaluate_orig_obj_at_resto_trial", "yes");

    /* print level */
    if(ACTIVE_STREAM(LOG_IPOPT_FULL)) {
        AddIpoptIntOption(nlp, "print_level", 7);
    } else if(ACTIVE_STREAM(LOG_IPOPT)) {
        AddIpoptIntOption(nlp, "print_level", 5);
    } else if(ACTIVE_STREAM(LOG_STATS)) {
        AddIpoptIntOption(nlp, "print_level", 3);
    } else {
        AddIpoptIntOption(nlp, "print_level", 2);
    }
    AddIpoptIntOption(nlp, "file_print_level", 0);

    /* derivative_test */
    if(ACTIVE_STREAM(LOG_IPOPT_JAC) && ACTIVE_STREAM(LOG_IPOPT_HESSE)) {
        AddIpoptIntOption(nlp, "print_level", 4);
        AddIpoptStrOption(nlp, "derivative_test", "second-order");
    } else if(ACTIVE_STREAM(LOG_IPOPT_JAC)) {
        AddIpoptIntOption(nlp, "print_level", 4);
        AddIpoptStrOption(nlp, "derivative_test", "first-order");
    } else if(ACTIVE_STREAM(LOG_IPOPT_HESSE)) {
        AddIpoptIntOption(nlp, "print_level", 4);
        AddIpoptStrOption(nlp, "derivative_test", "only-second-order");
    } else {
        AddIpoptStrOption(nlp, "derivative_test", "none");
    }


    cflags = (char*)omc_flagValue[FLAG_IPOPT_HESSE];
    if(cflags) {
        if(!strcmp(cflags,"BFGS"))
            AddIpoptStrOption(nlp, "hessian_approximation", "limited-memory");
        else if(!strcmp(cflags,"const") || !strcmp(cflags,"CONST"))
            AddIpoptStrOption(nlp, "hessian_constant", "yes");
        else if(!(!strcmp(cflags,"num") || !strcmp(cflags,"NUM")))
            warningStreamPrint(LOG_STDOUT, 0, "not support ipopt_hesse=%s",cflags);
    }

    /*linear_solver e.g. mumps, MA27, MA57,...
     * be sure HSL solver are installed if your try HSL solver*/
    cflags = (char*)omc_flagValue[FLAG_LS_IPOPT];
    if(cflags)
        AddIpoptStrOption(nlp, "linear_solver", cflags);
    AddIpoptNumOption(nlp,"mumps_pivtolmax",1e-5);


    /* max iter */
    cflags = (char*)omc_flagValue[FLAG_IPOPT_MAX_ITER];
    if(cflags) {
        char buffer[100];
        char c;
        int index_e = -1, i = 0;
        strcpy(buffer,cflags);

        while(buffer[i] != '\0') {
            if(buffer[i] == 'e') {
                index_e = i;
                break;
            }
            ++i;
        }

        if(index_e < 0) {
            max_iter = atoi(cflags);
            if(max_iter >= 0)
                AddIpoptIntOption(nlp, "max_iter", max_iter);
            printf("\nmax_iter = %i",atoi(cflags));

        } else {
            max_iter =  (atoi(cflags)*pow(10.0, (double)atoi(cflags+index_e+1)));
            if(max_iter >= 0)
                AddIpoptIntOption(nlp, "max_iter", (int)max_iter);
            printf("\nmax_iter = (int) %i | (double) %g",(int)max_iter, atoi(cflags)*pow(10.0, (double)atoi(cflags+index_e+1)));
        }
    } else
        AddIpoptIntOption(nlp, "max_iter", 5000);

    /*heuristic optition */
    {
        int ws = 0;
        cflags = (char*)omc_flagValue[FLAG_IPOPT_WARM_START];
        if(cflags) {
            ws = atoi(cflags);
        }

        if(ws > 0) {
            double shift = pow(10,-1.0*ws);
            AddIpoptNumOption(nlp,"mu_init",shift);
            AddIpoptNumOption(nlp,"bound_mult_init_val",shift);
            AddIpoptStrOption(nlp,"mu_strategy", "monotone");
            AddIpoptNumOption(nlp,"bound_push", 1e-5);
            AddIpoptNumOption(nlp,"bound_frac", 1e-5);
            AddIpoptNumOption(nlp,"slack_bound_push", 1e-5);
            AddIpoptNumOption(nlp,"constr_mult_init_max", 1e-5);
            AddIpoptStrOption(nlp,"bound_mult_init_method","mu-based");
        } else {
            AddIpoptStrOption(nlp,"mu_strategy","adaptive");
            AddIpoptStrOption(nlp,"bound_mult_init_method","constant");
        }
        AddIpoptStrOption(nlp,"fixed_variable_treatment","make_parameter");
        AddIpoptStrOption(nlp,"dependency_detection_with_rhs","yes");
        AddIpoptNumOption(nlp,"nu_init",1e-9);
        AddIpoptNumOption(nlp,"eta_phi",1e-10);
    }

    /********************************************************************/


    if(max_iter >=0) {
        optData->iter_ = 0.0;
        optData->index = 1;
        res = IpoptSolve(nlp, vopt, NULL, &obj, mult_g, mult_x_L, mult_x_U, (void*)optData);
    }
    if(res != 0 && !ACTIVE_STREAM(LOG_IPOPT))
        warningStreamPrint(LOG_STDOUT, 0, "No optimal solution found!\nUse -lv=LOG_IPOPT for more information.");
    FreeIpoptProblem(nlp);
}
예제 #30
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;
}