Exemple #1
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);

  }
}
/*! \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;

  unsigned int __currStepNo = 0;

  SIMULATION_INFO *simInfo = &(data->simulationInfo);
  solverInfo->currentTime = simInfo->startTime;

  MEASURE_TIME fmt;
  fmtInit(data, &fmt);

  printAllVarsDebug(data, 0, LOG_DEBUG); /* ??? */
  printSparseStructure(data, LOG_SOLVER);

  modelica_boolean syncStep = 0;

  /***** Start main simulation loop *****/
  while(solverInfo->currentTime < simInfo->stopTime)
  {
    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

    omc_alloc_interface.collect_a_little();

    /* try */
#if !defined(OMC_EMCC)
    MMC_TRY_INTERNAL(simulationJumpBuffer)
#endif
    {
      clear_rt_step(data);
      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)
          {
            double tmpTime = solverInfo->currentTime;
            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
     */
      retValIntegrator = simulationStep(data, threadData, solverInfo);

      if (S_OPTIMIZATION == solverInfo->solverMethod) break;
      syncStep = simulationUpdate(data, threadData, solverInfo);
      retry = 0; /* reset retry */

      fmtEmitStep(data, threadData, &fmt, solverInfo->didEventStep);
      saveDasslStats(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 */

  fmtClose(&fmt);

  TRACE_POP
  return retValue;
}
Exemple #3
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;
}
Exemple #4
0
/*!
 *  create initial guess dasslColorSymJac
 *  author: Vitalij Ruge
 **/
static short initial_guess_ipopt_sim(OptData *optData, SOLVER_INFO* solverInfo, const short o)
{
  double *u0;
  int i,j,k,l;
  modelica_real ***v;
  long double tol;
  short printGuess, op=1;

  const int nx = optData->dim.nx;
  const int nu = optData->dim.nu;
  const int np = optData->dim.np;
  const int nsi = optData->dim.nsi;
  const int nReal = optData->dim.nReal;
  char *cflags = (char*)omc_flagValue[FLAG_IIF];

  DATA* data = optData->data;
  threadData_t *threadData = optData->threadData;
  SIMULATION_INFO *sInfo = data->simulationInfo;

  if(!data->simulationInfo->external_input.active){
     externalInputallocate(data);
  }

   /* Initial DASSL solver */
   DASSL_DATA* dasslData = (DASSL_DATA*) malloc(sizeof(DASSL_DATA));
   tol = data->simulationInfo->tolerance;
   data->simulationInfo->tolerance = fmin(fmax(tol,1e-8),1e-3);

   infoStreamPrint(LOG_SOLVER, 0, "Initial Guess: Initializing DASSL");
   sInfo->solverMethod = "dassl";
   solverInfo->solverMethod = S_DASSL;
   dassl_initial(data, threadData, solverInfo, dasslData);
   solverInfo->solverMethod = S_OPTIMIZATION;
   solverInfo->solverData = dasslData;

   u0 = optData->bounds.u0;
   v = optData->v;

   if(!data->simulationInfo->external_input.active)
     for(i = 0; i< nu;++i)
       data->simulationInfo->inputVars[i] = u0[i]/*optData->bounds.scalF[i + nx]*/;

   printGuess = (short)(ACTIVE_STREAM(LOG_INIT) && !ACTIVE_STREAM(LOG_SOLVER));

   if((double)data->simulationInfo->startTime < optData->time.t0){
     double t = data->simulationInfo->startTime;
     const int nBoolean = data->modelData->nVariablesBoolean;
     const int nInteger = data->modelData->nVariablesInteger;
     const int nRelations =  data->modelData->nRelations;

     FILE * pFile = optData->pFile;
     fprintf(pFile, "%lf ",(double)t);
     for(i = 0; i < nu; ++i){
       fprintf(pFile, "%lf ", (float)data->simulationInfo->inputVars[i]);
     }
     fprintf(pFile, "%s", "\n");
     if(1){
       printf("\nPreSim");
       printf("\n========================================================\n");
       printf("\ndone: time[%i] = %g",0,(double)data->simulationInfo->startTime);
     }
     while(t < optData->time.t0){
       externalInputUpdate(data);
       smallIntSolverStep(data, threadData, solverInfo, fmin(t += optData->time.dt[0], optData->time.t0));
       printf("\ndone: time[%i] = %g",0,(double)data->localData[0]->timeValue);
       sim_result.emit(&sim_result,data,threadData);
       fprintf(pFile, "%lf ",(double)data->localData[0]->timeValue);
       for(i = 0; i < nu; ++i){
         fprintf(pFile, "%lf ", (float)data->simulationInfo->inputVars[i]);
       }
       fprintf(pFile, "%s", "\n");
     }
     memcpy(optData->v0, data->localData[0]->realVars, nReal*sizeof(modelica_real));
     memcpy(optData->i0, data->localData[0]->integerVars, nInteger*sizeof(modelica_integer));
     memcpy(optData->b0, data->localData[0]->booleanVars, nBoolean*sizeof(modelica_boolean));
     memcpy(optData->i0Pre, data->simulationInfo->integerVarsPre, nInteger*sizeof(modelica_integer));
     memcpy(optData->b0Pre, data->simulationInfo->booleanVarsPre, nBoolean*sizeof(modelica_boolean));
     memcpy(optData->v0Pre, data->simulationInfo->realVarsPre, nReal*sizeof(modelica_real));
     memcpy(optData->rePre, data->simulationInfo->relationsPre, nRelations*sizeof(modelica_boolean));
     memcpy(optData->re, data->simulationInfo->relations, nRelations*sizeof(modelica_boolean));
     memcpy(optData->storeR, data->simulationInfo->storedRelations, nRelations*sizeof(modelica_boolean));

     if(1){
       printf("\n--------------------------------------------------------");
       printf("\nfinished: PreSim");
       printf("\n========================================================\n");
     }
   }

   if(o == 2 && cflags && strcmp(cflags, ""))
     op = 2;

   if(printGuess ){
     printf("\nInitial Guess");
     printf("\n========================================================\n");
     printf("\ndone: time[%i] = %g",0,(double)optData->time.t0);
   }

   for(i = 0, k=1; i < nsi; ++i){
     for(j = 0; j < np; ++j, ++k){
       externalInputUpdate(data);
       if(op==1)
         smallIntSolverStep(data, threadData, solverInfo, (double)optData->time.t[i][j]);
       else{
         rotateRingBuffer(data->simulationData, 1, (void**) data->localData);
         importStartValues(data, threadData, cflags, (double)optData->time.t[i][j]);
         for(l=0; l<nReal; ++l){
            data->localData[0]->realVars[l] = data->modelData->realVarsData[l].attribute.start;
         }
       }

       if(printGuess)
         printf("\ndone: time[%i] = %g", k, (double)optData->time.t[i][j]);

       memcpy(v[i][j], data->localData[0]->realVars, nReal*sizeof(double));
       for(l = 0; l < nx; ++l){

         if(((double) v[i][j][l] < (double)optData->bounds.vmin[l]*optData->bounds.vnom[l])
             || (double) (v[i][j][l] > (double) optData->bounds.vmax[l]*optData->bounds.vnom[l])){
           printf("\n********************************************\n");
           warningStreamPrint(LOG_STDOUT, 0, "Initial guess failure at time %g",(double)optData->time.t[i][j]);
           warningStreamPrint(LOG_STDOUT, 0, "%g<= (%s=%g) <=%g",
               (double)optData->bounds.vmin[l]*optData->bounds.vnom[l],
               data->modelData->realVarsData[l].info.name,
               (double)v[i][j][l],
               (double)optData->bounds.vmax[l]*optData->bounds.vnom[l]);
           printf("\n********************************************");
         }
       }
     }
  }

  if(printGuess){
    printf("\n--------------------------------------------------------");
    printf("\nfinished: Initial Guess");
    printf("\n========================================================\n");
  }

  dassl_deinitial(solverInfo->solverData);
  solverInfo->solverData = (void*)optData;
  sInfo->solverMethod = "optimization";
  data->simulationInfo->tolerance = tol;

  externalInputFree(data);
  return op;
}
/*! \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;
}
Exemple #6
0
/*!
 *  create initial guess
 *  author: Vitalij Ruge
 **/
int initial_guess_ipopt(IPOPT_DATA_ *iData,SOLVER_INFO* solverInfo)
{
  double *u0, *u, *x, uu,tmp ,lhs, rhs;
  int i,j,k,ii,jj,id;
  int err;
  double *v;
  DATA* data = iData->data;
  SIMULATION_DATA *sData = (SIMULATION_DATA*)data->localData[0];
  SIMULATION_INFO *sInfo = &(data->simulationInfo);
  KINODE *kinOde;

  u0 = iData->data->localData[1]->realVars + iData->index_u;
  u = iData->data->localData[0]->realVars + iData->index_u;
  x = iData->data->localData[0]->realVars;
  v = iData->v;

  for(ii=iData->nx,j=0; j < iData->nu; ++j, ++ii)
  {
    u0[j] = data->modelData.realVarsData[iData->index_u+j].attribute.start;
    u0[j] = fmin(fmax(u0[j],iData->umin[j]),iData->umax[j]);
    u[j] = u0[j];
    v[ii] = u0[j]*iData->scalVar[j + iData->nx];
  }

  solverInfo->solverData = calloc(1, sizeof(KINODE));
  kinOde = (KINODE*) solverInfo->solverData;
  refreshSimData(x, u, iData->tf, iData);
  allocateKinOde(data, solverInfo, 8, 1);

  if(ACTIVE_STREAM(LOG_IPOPT))
  {
    printf("\n****initial guess****");
      printf("\n #####done time[%i] = %f",0,iData->time[0]);
  }

  for(i=0, k=1, v=iData->v + iData->nv; i<iData->nsi; ++i)
  {
    for(jj=0; jj<iData->deg; ++jj, ++k)
    {
      solverInfo->currentStepSize = iData->time[k] - iData->time[k-1];
      iData->data->localData[1]->timeValue = iData->time[k];
      
      do
      {
        err = kinsolOde(solverInfo->solverData);

        if(err < 0)
        {
          solverInfo->currentStepSize *= 0.99;
          kinOde->kData->fnormtol *=10.0;
          kinOde->kData->scsteptol *=10.0;
          
          if(ACTIVE_STREAM(LOG_SOLVER))
          {
            printf("\n #####try time[%i] = %f",k,iData->time[k]);
          }
        }
        else
        {
          if(ACTIVE_STREAM(LOG_IPOPT))
            printf("\n #####done time[%i] = %f",k,iData->time[k]);
        }
      }while(err <0);
      
      kinOde->kData->fnormtol =iData->data->simulationInfo.tolerance;
      kinOde->kData->scsteptol =iData->data->simulationInfo.tolerance;

      for(j=0; j< iData->nx; ++j)
      {
        v[j] = sData->realVars[j] * iData->scalVar[j];
      }

      for(ii=iData->index_u; j< iData->nv; ++j, ++ii)
      {
        v[j] = sData->realVars[ii] * iData->scalVar[j];
      }

      v += iData->nv;
      /* updateContinuousSystem(iData->data); */
      rotateRingBuffer(iData->data->simulationData, 1, (void**) iData->data->localData);
    }
  }

  for(i = 0, id=0; i<iData->NV;i++,++id)
  {
    if(id >=iData->nv)
      id = 0;
      
    if(id <iData->nx)
    {
      iData->v[i] =fmin(fmax(iData->vmin[id],iData->v[i]),iData->vmax[id]);
    }
    else if(id< iData->nv)
    {
      iData->v[i] = fmin(fmax(iData->vmin[id],iData->v[i]),iData->vmax[id]);
    }
  }

  if(ACTIVE_STREAM(LOG_IPOPT))
    printf("\n*****initial guess done*****");
  freeKinOde(data, solverInfo, 8, 1);
  solverInfo->solverData = (void*)iData;

  return 0;
}