コード例 #1
0
ファイル: MultFive_08bnd.c プロジェクト: NENEN/CASE-Activate
int MultFive_updateBoundVariableAttributes(DATA *data)
{
  
  /* min ******************************************************** */
  
  infoStreamPrint(LOG_INIT, 1, "updating min-values");
  if (ACTIVE_STREAM(LOG_INIT)) messageClose(LOG_INIT);
  
  /* max ******************************************************** */
  
  infoStreamPrint(LOG_INIT, 1, "updating max-values");
  if (ACTIVE_STREAM(LOG_INIT)) messageClose(LOG_INIT);
  
  /* nominal **************************************************** */
  
  infoStreamPrint(LOG_INIT, 1, "updating nominal-values");
  if (ACTIVE_STREAM(LOG_INIT)) messageClose(LOG_INIT);
  
  /* start ****************************************************** */
  
  infoStreamPrint(LOG_INIT, 1, "updating start-values");
  if (ACTIVE_STREAM(LOG_INIT)) messageClose(LOG_INIT);
  
  return 0;
}
コード例 #2
0
/*!
 *  function write results in the cvs
 *  author: Lennart Ochel
 **/
int ipoptDebuge(IPOPT_DATA_ *iData, double *x)
{
  if(ACTIVE_STREAM(LOG_IPOPT))
  {
    int i,j,k;
    double tmp;
    
    if(iData->index_debug_iter++ < iData->index_debug_next)
      return 0;

    iData->index_debug_next += iData->degub_step;

    for(j=0; j<iData->nv; ++j)
    {
      fprintf(iData->pFile[j], "\n");
      fprintf(iData->pFile[j], "%ld,", iData->index_debug_iter);
    }

    for(i=0; i<iData->NV; ++i)
    {
      j = i % iData->nv;
      tmp = x[i]*iData->vnom[j];
      fprintf(iData->pFile[j], "%.16g,", tmp);
    }

    for(j=0; j<iData->nv; ++j)
      fprintf(iData->pFile[j], "\n");
  }

  return 0;
}
コード例 #3
0
/*! \fn printStatus
 *
 *  \param [in]  [solverData]
 *  \param [in]  [nfunc_evals]
 *  \param [in]  [xerror]
 *  \param [in]  [xerror_scaled]
 *  \param [in]  [logLevel]
 *
 *  \author wbraun
 */
static void printStatus(DATA *data, DATA_HYBRD *solverData, int eqSystemNumber, const int *nfunc_evals, const double *xerror, const double *xerror_scaled, const int logLevel)
{
  long i;

  if (!ACTIVE_STREAM(logLevel)) return;
  infoStreamPrint(logLevel, 1, "nls status");

  infoStreamPrint(logLevel, 1, "variables");
  for(i=0; i<solverData->n; i++)
    infoStreamPrint(logLevel, 0, "[%ld] %s  = %.20e\n - scaling factor internal = %.16e\n"
                    " - scaling factor external = %.16e", i+1,
                    modelInfoGetEquation(&data->modelData->modelDataXml,eqSystemNumber).vars[i],
                    solverData->x[i], solverData->diag[i], solverData->xScalefactors[i]);
  messageClose(logLevel);

  infoStreamPrint(logLevel, 1, "functions");
  for(i=0; i<solverData->n; i++)
    infoStreamPrint(logLevel, 0, "res[%ld] = %.20e [scaling factor = %.16e]", i+1, solverData->fvec[i], solverData->resScaling[i]);
  messageClose(logLevel);

  infoStreamPrint(logLevel, 1, "statistics");
  infoStreamPrint(logLevel, 0, "nfunc = %d\nerror = %.20e\nerror_scaled = %.20e", *nfunc_evals, *xerror, *xerror_scaled);
  messageClose(logLevel);

  messageClose(logLevel);

}
コード例 #4
0
void debugMatrixDoubleLS(int logName, char* matrixName, double* matrix, int n, int m)
{
  if(ACTIVE_STREAM(logName))
  {
    int i, j;
    int sparsity = 0;
    char *buffer = (char*)malloc(sizeof(char)*m*18);

    infoStreamPrint(logName, 1, "%s [%dx%d-dim]", matrixName, n, m);
    for(i=0; i<n;i++)
    {
      buffer[0] = 0;
      for(j=0; j<m; j++)
      {
        if (sparsity)
        {
          if (fabs(matrix[i + j*(m-1)])<1e-12)
            sprintf(buffer, "%s 0", buffer);
          else
            sprintf(buffer, "%s *", buffer);
        }
        else
        {
          sprintf(buffer, "%s%12.4g ", buffer, matrix[i + j*(m-1)]);
        }
      }
      infoStreamPrint(logName, 0, "%s", buffer);
    }
    messageClose(logName);
    free(buffer);
  }
}
コード例 #5
0
/*! \fn int newuoa_initialization(INIT_DATA *initData)
 *
 *  This function performs initialization using the newuoa function, which is
 *  a trust region method that forms quadratic models by interpolation.
 */
int newuoa_initialization(INIT_DATA *initData)
{
  long IPRINT = ACTIVE_STREAM(LOG_INIT) ? 1000 : 0;
  long MAXFUN = 1000 * initData->nVars;
  double RHOEND = 1.0e-12;
  double RHOBEG = 10;     /* This should be about one tenth of the greatest
                             expected value of a variable. Perhaps the nominal
                             value can be used for this. */
  long NPT = 2*initData->nVars+1;

  double *W = (double*)calloc((NPT+13)*(NPT+initData->nVars)+3*initData->nVars*(initData->nVars+3)/2, sizeof(double));
  ASSERT(W, "out of memory");

  globalData = initData->simData;
  globalInitialResiduals = initData->initialResiduals;

  NEWUOA(&initData->nVars, &NPT, initData->vars, &RHOBEG, &RHOEND, &IPRINT, &MAXFUN, W, leastSquare);
  free(W);

  globalData = NULL;
  globalInitialResiduals = NULL;

  /* Calculate the residual to verify that equations are consistent. */
  return reportResidualValue(initData);
}
コード例 #6
0
void debugIntLS(int logName, char* message, int value)
{
  if(ACTIVE_STREAM(logName))
  {
    infoStreamPrint(logName, 1, "%s %d", message, value);
    messageClose(logName);
  }
}
コード例 #7
0
void debugStringLS(int logName, char* message)
{
  if(ACTIVE_STREAM(logName))
  {
    infoStreamPrint(logName, 1, "%s", message);
    messageClose(logName);
  }
}
コード例 #8
0
ファイル: omc_error.c プロジェクト: AntonDV235/OMCompiler
static void messageCloseXML(int stream)
{
  if(ACTIVE_STREAM(stream))
  {
    fputs("</message>\n", stdout);
    fflush(stdout);
  }
}
コード例 #9
0
/*! \fn printVector
 *
 *  \param [in]  [vector]
 *  \param [in]  [size]
 *  \param [in]  [logLevel]
 *  \param [in]  [name]
 *
 *  \author wbraun
 */
static void printVector(const double *vector, const integer *size, const int logLevel, const char *name)
{
  int i;
  if (!ACTIVE_STREAM(logLevel)) return;
  infoStreamPrint(logLevel, 1, "%s", name);
  for(i=0; i<*size; i++)
    infoStreamPrint(logLevel, 0, "[%2d] %20.12g", i, vector[i]);
  messageClose(logLevel);
}
コード例 #10
0
/*
 *  function calculates a jacobian matrix
 */
static
int nlsDenseJac(long int N, N_Vector vecX, N_Vector vecFX, DlsMat Jac, void *userData, N_Vector tmp1, N_Vector tmp2)
{
  NLS_KINSOL_USERDATA *kinsolUserData = (NLS_KINSOL_USERDATA*) userData;
  DATA* data = kinsolUserData->data;
  threadData_t *threadData = kinsolUserData->threadData;
  int sysNumber = kinsolUserData->sysNumber;
  NONLINEAR_SYSTEM_DATA *nlsData = &(data->simulationInfo->nonlinearSystemData[sysNumber]);
  NLS_KINSOL_DATA* kinsolData = (NLS_KINSOL_DATA*) nlsData->solverData;

  /* prepare variables */
  double *x = N_VGetArrayPointer(vecX);
  double *fx = N_VGetArrayPointer(vecFX);
  double *xScaling = NV_DATA_S(kinsolData->xScale);
  double *fRes = NV_DATA_S(kinsolData->fRes);
  double xsave, xscale, sign;
  double delta_hh;
  const double delta_h = sqrt(DBL_EPSILON*2e1);

  long int i,j;

  /* performance measurement */
  rt_ext_tp_tick(&nlsData->jacobianTimeClock);

  for(i = 0; i < N; i++)
  {
    xsave = x[i];
    delta_hh = delta_h * (fabs(xsave) + 1.0);
    if ((xsave + delta_hh >=  nlsData->max[i]))
      delta_hh *= -1;
    x[i] += delta_hh;

    /* Calculate difference quotient */
    nlsKinsolResiduals(vecX, kinsolData->fRes, userData);

    /* Calculate scaled difference quotient */
    delta_hh = 1. / delta_hh;

    for(j = 0; j < N; j++)
    {
      DENSE_ELEM(Jac, j, i) = (fRes[j] - fx[j]) * delta_hh;
    }
    x[i] = xsave;
  }

  /* debug */
  if (ACTIVE_STREAM(LOG_NLS_JAC)){
    infoStreamPrint(LOG_NLS_JAC, 0, "##KINSOL## omc dense matrix.");
    PrintMat(Jac);
  }

  /* performance measurement and statistics */
  nlsData->jacobianTime += rt_ext_tp_tock(&(nlsData->jacobianTimeClock));
  nlsData->numberOfJEval++;

  return 0;
}
コード例 #11
0
ファイル: MultFive_05evt.c プロジェクト: NENEN/CASE-Activate
int MultFive_checkForDiscreteChanges(DATA *data)
{
  int needToIterate = 0;

  infoStreamPrint(LOG_EVENTS_V, 1, "check for discrete changes");
  if (ACTIVE_STREAM(LOG_EVENTS_V)) messageClose(LOG_EVENTS_V);
  
  return needToIterate;
}
コード例 #12
0
ファイル: model_help.c プロジェクト: jschoenbohm/OMCompiler
/*! \fn printRelations
 *
 *  print all relations
 *
 *  \param [in]  [data]
 *  \param [in]  [stream]
 */
void printRelations(DATA *data, int stream)
{
    TRACE_PUSH
    long i;

    if (!ACTIVE_STREAM(stream))
    {
        TRACE_POP
        return;
    }
コード例 #13
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);
  }
}
コード例 #14
0
ファイル: model_help.c プロジェクト: jschoenbohm/OMCompiler
/*! \fn printSparseStructure
 *
 *  prints sparse structure of jacobian A
 *
 *  \param [in]  [data]
 *  \param [in]  [stream]
 *
 *  \author lochel
 */
void printSparseStructure(DATA *data, int stream)
{
    const int index = data->callback->INDEX_JAC_A;
    unsigned int row, col, i, j;
    /* Will crash with a static size array */
    char *buffer = NULL;

    if (!ACTIVE_STREAM(stream))
        return;

    buffer = (char*)omc_alloc_interface.malloc(sizeof(char)* 2*data->simulationInfo.analyticJacobians[index].sizeCols + 4);

    infoStreamPrint(stream, 1, "sparse structure of jacobian A [size: %ux%u]", data->simulationInfo.analyticJacobians[index].sizeRows, data->simulationInfo.analyticJacobians[index].sizeCols);
    infoStreamPrint(stream, 0, "%u nonzero elements", data->simulationInfo.analyticJacobians[index].sparsePattern.numberOfNoneZeros);
    /*
    sprintf(buffer, "");
    for(row=0; row < data->simulationInfo.analyticJacobians[index].sizeRows; row++)
      sprintf(buffer, "%s%u ", buffer, data->simulationInfo.analyticJacobians[index].sparsePattern.leadindex[row]);
    infoStreamPrint(stream, 0, "leadindex: %s", buffer);

    sprintf(buffer, "");
    for(i=0; i < data->simulationInfo.analyticJacobians[index].sparsePattern.numberOfNoneZeros; i++)
      sprintf(buffer, "%s%u ", buffer, data->simulationInfo.analyticJacobians[index].sparsePattern.index[i]);
    infoStreamPrint(stream, 0, "index: %s", buffer);
    */
    infoStreamPrint(stream, 1, "transposed sparse structure (rows: states)");
    i=0;
    for(row=0; row < data->simulationInfo.analyticJacobians[index].sizeRows; row++)
    {
        j=0;
        for(col=0; i < data->simulationInfo.analyticJacobians[index].sparsePattern.leadindex[row]; col++)
        {
            if(data->simulationInfo.analyticJacobians[index].sparsePattern.index[i] == col)
            {
                buffer[j++] = '*';
                ++i;
            }
            else
            {
                buffer[j++] = ' ';
            }
            buffer[j++] = ' ';
        }
        buffer[j] = '\0';
        infoStreamPrint(stream, 0, "%s", buffer);
    }
    messageClose(stream);
    messageClose(stream);
}
コード例 #15
0
ファイル: model_help.c プロジェクト: jschoenbohm/OMCompiler
/*! \fn printAllVars
 *
 *  prints all variable values
 *
 *  \param [in]  [data]
 *  \param [in]  [ringSegment]
 *  \param [in]  [stream]
 *
 *  \author wbraun
 */
void printAllVars(DATA *data, int ringSegment, int stream)
{
    TRACE_PUSH
    long i;
    MODEL_DATA      *mData = &(data->modelData);
    SIMULATION_INFO *sInfo = &(data->simulationInfo);

    if (!ACTIVE_STREAM(stream)) return;

    infoStreamPrint(stream, 1, "Print values for buffer segment %d regarding point in time : %g", ringSegment, data->localData[ringSegment]->timeValue);

    infoStreamPrint(stream, 1, "states variables");
    for(i=0; i<mData->nStates; ++i)
        infoStreamPrint(stream, 0, "%ld: %s = %g (pre: %g)", i+1, mData->realVarsData[i].info.name, data->localData[ringSegment]->realVars[i], sInfo->realVarsPre[i]);
    messageClose(stream);

    infoStreamPrint(stream, 1, "derivatives variables");
    for(i=mData->nStates; i<2*mData->nStates; ++i)
        infoStreamPrint(stream, 0, "%ld: %s = %g (pre: %g)", i+1, mData->realVarsData[i].info.name, data->localData[ringSegment]->realVars[i], sInfo->realVarsPre[i]);
    messageClose(stream);

    infoStreamPrint(stream, 1, "other real values");
    for(i=2*mData->nStates; i<mData->nVariablesReal; ++i)
        infoStreamPrint(stream, 0, "%ld: %s = %g (pre: %g)", i+1, mData->realVarsData[i].info.name, data->localData[ringSegment]->realVars[i], sInfo->realVarsPre[i]);
    messageClose(stream);

    infoStreamPrint(stream, 1, "integer variables");
    for(i=0; i<mData->nVariablesInteger; ++i)
        infoStreamPrint(stream, 0, "%ld: %s = %ld (pre: %ld)", i+1, mData->integerVarsData[i].info.name, data->localData[ringSegment]->integerVars[i], sInfo->integerVarsPre[i]);
    messageClose(stream);

    infoStreamPrint(stream, 1, "boolean variables");
    for(i=0; i<mData->nVariablesBoolean; ++i)
        infoStreamPrint(stream, 0, "%ld: %s = %s (pre: %s)", i+1, mData->booleanVarsData[i].info.name, data->localData[ringSegment]->booleanVars[i] ? "true" : "false", sInfo->booleanVarsPre[i] ? "true" : "false");
    messageClose(stream);

    infoStreamPrint(stream, 1, "string variables");
    for(i=0; i<mData->nVariablesString; ++i)
        infoStreamPrint(stream, 0, "%ld: %s = %s (pre: %s)", i+1,
                        mData->stringVarsData[i].info.name,
                        MMC_STRINGDATA(data->localData[ringSegment]->stringVars[i]),
                        MMC_STRINGDATA(sInfo->stringVarsPre[i]));
    messageClose(stream);

    messageClose(stream);

    TRACE_POP
}
コード例 #16
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);
  }
}
コード例 #17
0
void debugVectorDoubleLS(int logName, char* vectorName, double* vector, int n)
{
    if(ACTIVE_STREAM(logName))
    {
        int i;
        char buffer[4096];

        infoStreamPrint(logName, 1, "%s [%d-dim]", vectorName, n);
        buffer[0] = 0;
        for(i=0; i<n; i++)
        {
            if (vector[i]<-1e+300)
                sprintf(buffer, "%s -INF ", buffer);
            else if (vector[i]>1e+300)
                sprintf(buffer, "%s +INF ", buffer);
            else
                sprintf(buffer, "%s%16.8g ", buffer, vector[i]);
        }
        infoStreamPrint(logName, 0, "%s", buffer);
        messageClose(logName);
    }
}
コード例 #18
0
/*! \fn solve linear system with totalpivot method
 *
 *  \param [in]  [data]
 *                [sysNumber] index of the corresponing non-linear system
 *
 *  \author bbachmann
 */
int solveTotalPivot(DATA *data, threadData_t *threadData, int sysNumber, double* aux_x)
{
  void *dataAndThreadData[2] = {data, threadData};
  int i, j;
  LINEAR_SYSTEM_DATA* systemData = &(data->simulationInfo->linearSystemData[sysNumber]);
  DATA_TOTALPIVOT* solverData = (DATA_TOTALPIVOT*) systemData->solverData[1];
  int n = systemData->size, status;
  double fdeps = 1e-8;
  double xTol = 1e-8;
  int eqSystemNumber = systemData->equationIndex;
  int indexes[2] = {1,eqSystemNumber};
  int rank;

  /* We are given the number of the linear system.
   * We want to look it up among all equations. */
  /* int eqSystemNumber = systemData->equationIndex; */
  int success = 1;
  double tmpJacEvalTime;

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

  debugVectorDoubleLS(LOG_LS_V,"SCALING",systemData->nominal,n);
  debugVectorDoubleLS(LOG_LS_V,"Old VALUES",aux_x,n);

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

    /* reset matrix A */
    vecConstLS(n*n, 0.0, systemData->A);
    /* update matrix A -> first n columns of matrix Ab*/
    systemData->setA(data, threadData, systemData);
    vecCopyLS(n*n, systemData->A, solverData->Ab);

    /* update vector b (rhs) -> -b is last column of matrix Ab*/
    rt_ext_tp_tick(&(solverData->timeClock));
    systemData->setb(data, threadData, systemData);
    vecScalarMultLS(n, systemData->b, -1.0, solverData->Ab + n*n);

  } else {

    /* calculate jacobian -> first n columns of matrix Ab*/
    if(systemData->jacobianIndex != -1){
      getAnalyticalJacobianTotalPivot(data, threadData, solverData->Ab, sysNumber);
    } else {
      assertStreamPrint(threadData, 1, "jacobian function pointer is invalid" );
    }
    /* calculate vector b (rhs) -> -b is last column of matrix Ab */
    wrapper_fvec_totalpivot(aux_x, solverData->Ab + n*n, dataAndThreadData, sysNumber);
  }
  tmpJacEvalTime = rt_ext_tp_tock(&(solverData->timeClock));
  systemData->jacobianTime += tmpJacEvalTime;
  infoStreamPrint(LOG_LS_V, 0, "###  %f  time to set Matrix A and vector b.", tmpJacEvalTime);
  debugMatrixDoubleLS(LOG_LS_V,"LGS: matrix Ab",solverData->Ab, n, n+1);

  rt_ext_tp_tick(&(solverData->timeClock));
  status = solveSystemWithTotalPivotSearchLS(n, solverData->x, solverData->Ab, solverData->indRow, solverData->indCol, &rank);
  infoStreamPrint(LOG_LS_V, 0, "Solve System: %f", rt_ext_tp_tock(&(solverData->timeClock)));

  if (status != 0)
  {
    warningStreamPrint(LOG_STDOUT, 0, "Error solving linear system of equations (no. %d) at time %f.", (int)systemData->equationIndex, data->localData[0]->timeValue);
    success = 0;
  } else {

    debugVectorDoubleLS(LOG_LS_V, "SOLUTION:", solverData->x, n+1);
    if (1 == systemData->method){
      /* add the solution to old solution vector*/
      vecAddLS(n, aux_x, solverData->x, aux_x);
      wrapper_fvec_totalpivot(aux_x, solverData->b, dataAndThreadData, sysNumber);
    } else {
       /* take the solution */
       vecCopyLS(n, solverData->x, aux_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], aux_x[i]);
      }
      messageClose(LOG_LS_V);
    }
  }
  return success;
}
コード例 #19
0
/*
 *  function calculates a jacobian matrix by
 *  numerical method finite differences with coloring
 *  into a sparse SlsMat matrix
 */
static
int nlsSparseJac(N_Vector vecX, N_Vector vecFX, SlsMat Jac, void *userData, N_Vector tmp1, N_Vector tmp2)
{
  NLS_KINSOL_USERDATA *kinsolUserData = (NLS_KINSOL_USERDATA*) userData;
  DATA* data = kinsolUserData->data;
  threadData_t *threadData = kinsolUserData->threadData;
  int sysNumber = kinsolUserData->sysNumber;
  NONLINEAR_SYSTEM_DATA *nlsData = &(data->simulationInfo->nonlinearSystemData[sysNumber]);
  NLS_KINSOL_DATA* kinsolData = (NLS_KINSOL_DATA*) nlsData->solverData;

  /* prepare variables */
  double *x = N_VGetArrayPointer(vecX);
  double *fx = N_VGetArrayPointer(vecFX);
  double *xsave = N_VGetArrayPointer(tmp1);
  double *delta_hh = N_VGetArrayPointer(tmp2);
  double *xScaling = NV_DATA_S(kinsolData->xScale);
  double *fRes = NV_DATA_S(kinsolData->fRes);

  SPARSE_PATTERN* sparsePattern = &(nlsData->sparsePattern);

  const double delta_h = sqrt(DBL_EPSILON*2e1);

  long int i,j,ii;
  int nth = 0;

  /* performance measurement */
  rt_ext_tp_tick(&nlsData->jacobianTimeClock);

  /* reset matrix */
  SlsSetToZero(Jac);

  for(i = 0; i < sparsePattern->maxColors; i++)
  {
    for(ii=0; ii < kinsolData->size; ii++)
    {
      if(sparsePattern->colorCols[ii]-1 == i)
      {
        xsave[ii] = x[ii];
        delta_hh[ii] = delta_h * (fabs(xsave[ii]) + 1.0);
        if ((xsave[ii] + delta_hh[ii] >=  nlsData->max[ii]))
          delta_hh[ii] *= -1;
        x[ii] += delta_hh[ii];

        /* Calculate scaled difference quotient */
        delta_hh[ii] = 1. / delta_hh[ii];
      }
    }
    nlsKinsolResiduals(vecX, kinsolData->fRes, userData);

    for(ii = 0; ii < kinsolData->size; ii++)
    {
      if(sparsePattern->colorCols[ii]-1 == i)
      {
        nth = sparsePattern->leadindex[ii];
        while(nth < sparsePattern->leadindex[ii+1])
        {
          j  =  sparsePattern->index[nth];
          setJacElementKluSparse(j, ii, (fRes[j] - fx[j]) * delta_hh[ii], nth, Jac);
          nth++;
        };
        x[ii] = xsave[ii];
      }
    }
  }
  /* finish sparse matrix */
  finishSparseColPtr(Jac);

  /* debug */
  if (ACTIVE_STREAM(LOG_NLS_JAC)){
    infoStreamPrint(LOG_NLS_JAC, 1, "##KINSOL## Sparse Matrix.");
    PrintSparseMat(Jac);
    nlsKinsolJacSumSparse(Jac);
    messageClose(LOG_NLS_JAC);
  }

  /* performance measurement and statistics */
  nlsData->jacobianTime += rt_ext_tp_tock(&(nlsData->jacobianTimeClock));
  nlsData->numberOfJEval++;

  return 0;
}
コード例 #20
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;
}
コード例 #21
0
int nlsKinsolAllocate(int size, NONLINEAR_SYSTEM_DATA *nlsData, int linearSolverMethod)
{
  int i, flag, printLevel;

  NLS_KINSOL_DATA *kinsolData = (NLS_KINSOL_DATA*) malloc(sizeof(NLS_KINSOL_DATA));

  /* allocate system data */
  nlsData->solverData = (void*)kinsolData;

  kinsolData->size = size;
  kinsolData->linearSolverMethod = linearSolverMethod;
  kinsolData->solved = 0;

  kinsolData->fnormtol  = sqrt(newtonFTol);     /* function tolerance */
  kinsolData->scsteptol = sqrt(newtonXTol);     /* step tolerance */

  kinsolData->initialGuess = N_VNew_Serial(size);
  kinsolData->xScale = N_VNew_Serial(size);
  kinsolData->fScale = N_VNew_Serial(size);
  kinsolData->fRes = N_VNew_Serial(size);

  kinsolData->kinsolMemory = KINCreate();

  /* setup user defined functions */
  KINSetErrHandlerFn(kinsolData->kinsolMemory, nlsKinsolErrorPrint, kinsolData);
  KINSetInfoHandlerFn(kinsolData->kinsolMemory, nlsKinsolInfoPrint, kinsolData);
  KINSetUserData(kinsolData->kinsolMemory, (void*)&(kinsolData->userData));
  flag = KINInit(kinsolData->kinsolMemory, nlsKinsolResiduals, kinsolData->initialGuess);
  if (checkReturnFlag(flag)){
    errorStreamPrint(LOG_STDOUT, 0, "##KINSOL## Something goes wrong while initialize KINSOL solver!");
  }

  /* Specify linear solver and/or corresponding jacobian function*/
  if (kinsolData->linearSolverMethod == 3)
  {
    if(nlsData->isPatternAvailable)
    {
      kinsolData->nnz = nlsData->sparsePattern.numberOfNoneZeros;
      flag = KINKLU(kinsolData->kinsolMemory, size, kinsolData->nnz);
      if (checkReturnFlag(flag)){
        errorStreamPrint(LOG_STDOUT, 0, "##KINSOL## Something goes wrong while initialize KINSOL solver!");
      }
      flag = KINSlsSetSparseJacFn(kinsolData->kinsolMemory, nlsSparseJac);
      if (checkReturnFlag(flag)){
        errorStreamPrint(LOG_STDOUT, 0, "##KINSOL## Something goes wrong while initialize KINSOL Sparse Solver!");
      }
    }
    else
    {
      flag = KINDense(kinsolData->kinsolMemory, size);
      if (checkReturnFlag(flag)){
        errorStreamPrint(LOG_STDOUT, 0, "##KINSOL## Something goes wrong while initialize KINSOL solver!");
      }
    }
  }
  else if (kinsolData->linearSolverMethod == 1)
  {
    flag = KINDense(kinsolData->kinsolMemory, size);
    if (checkReturnFlag(flag)){
      errorStreamPrint(LOG_STDOUT, 0, "##KINSOL## Something goes wrong while initialize KINSOL solver!");
    }
  }
  else if (kinsolData->linearSolverMethod == 2)
  {
    flag = KINDense(kinsolData->kinsolMemory, size);
    if (checkReturnFlag(flag)){
      errorStreamPrint(LOG_STDOUT, 0, "##KINSOL## Something goes wrong while initialize KINSOL solver!");
    }
    flag = KINDlsSetDenseJacFn(kinsolData->kinsolMemory, nlsDenseJac);
    if (checkReturnFlag(flag)){
      errorStreamPrint(LOG_STDOUT, 0, "##KINSOL## Something goes wrong while initialize KINSOL Sparse Solver!");
    }
  }

  /* configuration */
  nlsKinsolConfigSetup(kinsolData);

  /* debug print level of kinsol */
  if (ACTIVE_STREAM(LOG_NLS))
    printLevel = 1;
  else if (ACTIVE_STREAM(LOG_NLS_V))
    printLevel = 3;
  else
    printLevel = 0;
  KINSetPrintLevel(kinsolData->kinsolMemory, printLevel);

  return 0;
}
コード例 #22
0
/*! \fn solve non-linear system with newton method
 *
 *  \param [in]  [data]
 *                [sysNumber] index of the corresponding non-linear system
 *
 *  \author wbraun
 */
int solveNewton(DATA *data, threadData_t *threadData, int sysNumber)
{
  NONLINEAR_SYSTEM_DATA* systemData = &(data->simulationInfo->nonlinearSystemData[sysNumber]);
  DATA_NEWTON* solverData = (DATA_NEWTON*)(systemData->solverData);
  int eqSystemNumber = 0;
  int i;
  double xerror = -1, xerror_scaled = -1;
  int success = 0;
  int nfunc_evals = 0;
  int continuous = 1;
  double local_tol = solverData->ftol;

  int giveUp = 0;
  int retries = 0;
  int retries2 = 0;
  int nonContinuousCase = 0;
  modelica_boolean *relationsPreBackup = NULL;
  int casualTearingSet = data->simulationInfo->nonlinearSystemData[sysNumber].strictTearingFunctionCall != NULL;

  DATA_USER* userdata = (DATA_USER*)malloc(sizeof(DATA_USER));
  assert(userdata != NULL);

  userdata->data = (void*)data;
  userdata->threadData = threadData;
  userdata->sysNumber = sysNumber;

  /*
   * We are given the number of the non-linear system.
   * We want to look it up among all equations.
   */
  eqSystemNumber = systemData->equationIndex;

  local_tol = solverData->ftol;

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

  solverData->nfev = 0;

  /* try to calculate jacobian only once at the beginning of the iteration */
  solverData->calculate_jacobian = 0;

  // Initialize lambda variable
  if (data->simulationInfo->nonlinearSystemData[sysNumber].homotopySupport) {
    solverData->x[solverData->n] = 1.0;
    solverData->x_new[solverData->n] = 1.0;
  }
  else {
    solverData->x[solverData->n] = 0.0;
    solverData->x_new[solverData->n] = 0.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 with Newton Solver",
        eqSystemNumber, data->localData[0]->timeValue);

    for(i = 0; i < solverData->n; i++) {
      infoStreamPrint(LOG_NLS_V, 1, "x[%d] = %.15e", i, data->simulationInfo->discreteCall ? systemData->nlsx[i] : systemData->nlsxExtrapolation[i]);
      infoStreamPrint(LOG_NLS_V, 0, "nominal = %g +++ nlsx = %g +++ old = %g +++ extrapolated = %g",
          systemData->nominal[i], systemData->nlsx[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)));
  }

  /* start solving loop */
  while(!giveUp && !success)
  {

    giveUp = 1;
    solverData->newtonStrategy = data->simulationInfo->newtonStrategy;
    _omc_newton(wrapper_fvec_newton, solverData, (void*)userdata);

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

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

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

    /* solution found */
    if((xerror <= local_tol || xerror_scaled <= local_tol) && solverData->info > 0)
    {
      success = 1;
      nfunc_evals += solverData->nfev;
      if(ACTIVE_STREAM(LOG_NLS_V))
      {
        infoStreamPrint(LOG_NLS_V, 0, "*** System solved ***\n%d restarts", retries);
        infoStreamPrint(LOG_NLS_V, 0, "nfunc = %d +++ error = %.15e +++ error_scaled = %.15e", nfunc_evals, xerror, xerror_scaled);
        for(i = 0; i < solverData->n; i++)
          infoStreamPrint(LOG_NLS_V, 0, "x[%d] = %.15e\n\tresidual = %e", i, solverData->x[i], solverData->fvec[i]);
      }

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

      /* Then try with old values (instead of extrapolating )*/
    }
    // If this is the casual tearing set (only exists for dynamic tearing), break after first try
    else if(retries < 1 && casualTearingSet)
    {
      giveUp = 1;
      infoStreamPrint(LOG_NLS_V, 0, "### No Solution for the casual tearing set at the first try! ###");
    }
    else if(retries < 1)
    {
      memcpy(solverData->x, systemData->nlsxOld, solverData->n*(sizeof(double)));

      retries++;
      giveUp = 0;
      nfunc_evals += solverData->nfev;
      infoStreamPrint(LOG_NLS_V, 0, " - iteration making no progress:\t try old values.");
      /* try to vary the initial values */

      /* evaluate jacobian in every step now */
      solverData->calculate_jacobian = 1;
    }
    else if(retries < 2)
    {
      for(i = 0; i < solverData->n; i++)
        solverData->x[i] += systemData->nominal[i] * 0.01;
      retries++;
      giveUp = 0;
      nfunc_evals += solverData->nfev;
      infoStreamPrint(LOG_NLS_V, 0, " - iteration making no progress:\t vary solution point by 1%%.");
      /* try to vary the initial values */
    }
    else if(retries < 3)
    {
      for(i = 0; i < solverData->n; i++)
        solverData->x[i] = systemData->nominal[i];
      retries++;
      giveUp = 0;
      nfunc_evals += solverData->nfev;
      infoStreamPrint(LOG_NLS_V, 0, " - iteration making no progress:\t try nominal values as initial solution.");
    }
    else if(retries < 4  && data->simulationInfo->discreteCall)
    {
      /* try to solve non-continuous
       * work-a-round: since other wise some model does
       * stuck in event iteration. e.g.: Modelica.Mechanics.Rotational.Examples.HeatLosses
       */

      memcpy(solverData->x, systemData->nlsxOld, solverData->n*(sizeof(double)));
      retries++;

      /* try to solve a discontinuous system */
      continuous = 0;

      nonContinuousCase = 1;
      memcpy(relationsPreBackup, data->simulationInfo->relationsPre, sizeof(modelica_boolean)*data->modelData->nRelations);

      giveUp = 0;
      nfunc_evals += solverData->nfev;
      infoStreamPrint(LOG_NLS_V, 0, " - iteration making no progress:\t try to solve a discontinuous system.");
    }
    else if(retries2 < 4)
    {
      memcpy(solverData->x, systemData->nlsxOld, solverData->n*(sizeof(double)));
      /* reduce tolarance */
      local_tol = local_tol*10;

      retries = 0;
      retries2++;
      giveUp = 0;
      nfunc_evals += solverData->nfev;
      infoStreamPrint(LOG_NLS_V, 0, " - iteration making no progress:\t reduce the tolerance slightly to %e.", local_tol);
    }
    else
    {
      printErrorEqSyst(ERROR_AT_TIME, modelInfoGetEquation(&data->modelData->modelDataXml,eqSystemNumber), data->localData[0]->timeValue);
      if(ACTIVE_STREAM(LOG_NLS_V))
      {
        infoStreamPrint(LOG_NLS_V, 0, "### No Solution! ###\n after %d restarts", retries);
        infoStreamPrint(LOG_NLS_V, 0, "nfunc = %d +++ error = %.15e +++ error_scaled = %.15e", nfunc_evals, xerror, xerror_scaled);
        if(ACTIVE_STREAM(LOG_NLS_V))
          for(i = 0; i < solverData->n; i++)
            infoStreamPrint(LOG_NLS_V, 0, "x[%d] = %.15e\n\tresidual = %e", i, solverData->x[i], solverData->fvec[i]);
      }
    }
  }
  if(ACTIVE_STREAM(LOG_NLS_V))
    messageClose(LOG_NLS_V);

  free(relationsPreBackup);

  /* write statistics */
  systemData->numberOfFEval = solverData->numberOfFunctionEvaluations;
  systemData->numberOfIterations = solverData->numberOfIterations;

  return success;
}
コード例 #23
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;
}
コード例 #24
0
ファイル: stateset.c プロジェクト: dietmarw/OMCompiler
/*! \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;
}
コード例 #25
0
ファイル: stateset.c プロジェクト: dietmarw/OMCompiler
/*! \fn getAnalyticalJacobianSet
 *
 *  function calculates analytical jacobian
 *
 *  \param [ref] [data] ???
 *  \param [out] [index] ???
 *
 *  \author wbraun
 */
static void getAnalyticalJacobianSet(DATA* data, threadData_t *threadData, unsigned int index)
{
  TRACE_PUSH
  unsigned int i, j, k, l, ii;
  unsigned int jacIndex = data->simulationInfo->stateSetData[index].jacobianIndex;
  unsigned int nrows = data->simulationInfo->analyticJacobians[jacIndex].sizeRows;
  unsigned int ncols = data->simulationInfo->analyticJacobians[jacIndex].sizeCols;
  double* jac = data->simulationInfo->stateSetData[index].J;

  /* set all elements to zero */
  memset(jac, 0, (nrows*ncols*sizeof(double)));

  for(i=0; i < data->simulationInfo->analyticJacobians[jacIndex].sparsePattern.maxColors; i++)
  {
    for(ii=0; ii < data->simulationInfo->analyticJacobians[jacIndex].sizeCols; ii++)
      if(data->simulationInfo->analyticJacobians[jacIndex].sparsePattern.colorCols[ii]-1 == i)
        data->simulationInfo->analyticJacobians[jacIndex].seedVars[ii] = 1;

/*
    if(ACTIVE_STREAM(LOG_DSS_JAC))
    {
      infoStreamPrint(LOG_DSS_JAC, 1, "Caluculate one col:");
      for(l=0; l < data->simulationInfo->analyticJacobians[jacIndex].sizeCols; l++)
        infoStreamPrint(LOG_DSS_JAC, 0, "seed: data->simulationInfo->analyticJacobians[index].seedVars[%d]= %f", l, data->simulationInfo->analyticJacobians[jacIndex].seedVars[l]);
      messageClose(LOG_DSS_JAC);
    }
*/
    (data->simulationInfo->stateSetData[index].analyticalJacobianColumn)(data, threadData);

    for(j=0; j < data->simulationInfo->analyticJacobians[jacIndex].sizeCols; j++)
    {
      if(data->simulationInfo->analyticJacobians[jacIndex].seedVars[j] == 1)
      {
        if(j==0)
          ii = 0;
        else
          ii = data->simulationInfo->analyticJacobians[jacIndex].sparsePattern.leadindex[j-1];

        /* infoStreamPrint(LOG_DSS_JAC, 0, "take for %d -> %d\n", j, ii); */

        while(ii < data->simulationInfo->analyticJacobians[jacIndex].sparsePattern.leadindex[j])
        {
          l  = data->simulationInfo->analyticJacobians[jacIndex].sparsePattern.index[ii];
          k  = j*data->simulationInfo->analyticJacobians[jacIndex].sizeRows + l;
          jac[k] = data->simulationInfo->analyticJacobians[jacIndex].resultVars[l];
          /* infoStreamPrint(LOG_DSS_JAC, 0, "write %d. in jac[%d]-[%d, %d]=%f from col[%d]=%f", ii, k, l, j, jac[k], l, data->simulationInfo->analyticJacobians[jacIndex].resultVars[l]); */
          ii++;
        };
      }
    }
    for(ii=0; ii < data->simulationInfo->analyticJacobians[jacIndex].sizeCols; ii++)
      if(data->simulationInfo->analyticJacobians[jacIndex].sparsePattern.colorCols[ii]-1 == i)
        data->simulationInfo->analyticJacobians[jacIndex].seedVars[ii] = 0;
  }

  if(ACTIVE_STREAM(LOG_DSS_JAC))
  {
    char *buffer = (char*)malloc(sizeof(char)*data->simulationInfo->analyticJacobians[jacIndex].sizeCols*10);

    infoStreamPrint(LOG_DSS_JAC, 1, "jacobian %dx%d [id: %d]", data->simulationInfo->analyticJacobians[jacIndex].sizeRows, data->simulationInfo->analyticJacobians[jacIndex].sizeCols, jacIndex);
    for(i=0; i<data->simulationInfo->analyticJacobians[jacIndex].sizeRows; i++)
    {
      buffer[0] = 0;
      for(j=0; j < data->simulationInfo->analyticJacobians[jacIndex].sizeCols; j++)
        sprintf(buffer, "%s%.5e ", buffer, jac[i*data->simulationInfo->analyticJacobians[jacIndex].sizeCols+j]);
      infoStreamPrint(LOG_DSS_JAC, 0, "%s", buffer);
    }
    messageClose(LOG_DSS_JAC);
    free(buffer);

  }

  TRACE_POP
}
コード例 #26
0
ファイル: optimizer_main.c プロジェクト: adeas31/OMCompiler
/*!
 *  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);
}
コード例 #27
0
ファイル: dassl.c プロジェクト: AntonDV235/OMCompiler
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;
}
コード例 #28
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;
    }
コード例 #29
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;
}
コード例 #30
0
/*! \fn wrapper function of the residual Function
 *   non-linear solver calls this subroutine fcn(n, x, fvec, iflag, data)
 *
 *
 */
static int wrapper_fvec_hybrj(const integer* n, const double* x, double* f, double* fjac, const integer* ldjac, const integer* iflag, void* dataAndSysNum)
{
  int i,j;
  struct dataAndSys *dataSys = (struct dataAndSys*) dataAndSysNum;
  DATA *data = (dataSys->data);
  void *dataAndThreadData[2] = {data, dataSys->threadData};
  NONLINEAR_SYSTEM_DATA* systemData = &(data->simulationInfo->nonlinearSystemData[dataSys->sysNumber]);
  DATA_HYBRD* solverData = (DATA_HYBRD*)(systemData->solverData);
  int continuous = data->simulationInfo->solveContinuous;

  switch(*iflag)
  {
  case 1:
    /* re-scaling x vector */
    if(solverData->useXScaling)
      for(i=0; i<*n; i++)
        solverData->xScaled[i] = x[i]*solverData->xScalefactors[i];

    /* debug output */
    if(ACTIVE_STREAM(LOG_NLS_RES)) {
      infoStreamPrint(LOG_NLS_RES, 0, "-- residual function call %d -- scaling = %d", (int)solverData->nfev, solverData->useXScaling);
      printVector(x, n, LOG_NLS_RES, "x vector (scaled)");
      printVector(solverData->xScaled, n, LOG_NLS_RES, "x vector");
    }

    /* call residual function */
    if(solverData->useXScaling){
      (systemData->residualFunc)(dataAndThreadData, (const double*) solverData->xScaled, f, (const int*)iflag);
    } else {
      (systemData->residualFunc)(dataAndThreadData, x, f, (const int*)iflag);
    }

    /* debug output */
    if(ACTIVE_STREAM(LOG_NLS_RES)) {
      printVector(f, n, LOG_NLS_RES, "residuals");
      infoStreamPrint(LOG_NLS_RES, 0, "-- end of residual function call %d --", (int)solverData->nfev);
    }

    solverData->numberOfFunctionEvaluations++;
    break;
  case 2:
    /* set residual function continuous for jacobian calculation */
    if(continuous)
      data->simulationInfo->solveContinuous = 0;

    if(ACTIVE_STREAM(LOG_NLS_RES))
      infoStreamPrint(LOG_NLS_RES, 0, "-- begin calculating jacobian --");

    /* call apropreated jacobian function */
    if(systemData->jacobianIndex != -1){
      integer iflagtmp = 1;
      wrapper_fvec_hybrj(n, x, f, fjac, ldjac, &iflagtmp, dataSys);

      getAnalyticalJacobian(dataSys, fjac);
    }
    else{
      getNumericalJacobian(dataSys, fjac, x, f);
    }

    /* debug output */
    if (ACTIVE_STREAM(LOG_NLS_RES)) {
      infoStreamPrint(LOG_NLS_RES, 0, "-- end calculating jacobian --");

      if(ACTIVE_STREAM(LOG_NLS_JAC))
      {
        char buffer[16384];
        infoStreamPrint(LOG_NLS_JAC, 1, "jacobian matrix [%dx%d]", (int)*n, (int)*n);
        for(i=0; i<*n; i++)
        {
          buffer[0] = 0;
          for(j=0; j<*n; j++)
            sprintf(buffer, "%s%20.12g ", buffer, fjac[i*solverData->n+j]);
          infoStreamPrint(LOG_NLS_JAC, 0, "%s", buffer);
        }
        messageClose(LOG_NLS_JAC);
      }
    }
    /* reset residual function again */
    if(continuous)
      data->simulationInfo->solveContinuous = 1;
    break;

  default:
    throwStreamPrint(NULL, "Well, this is embarrasing. The non-linear solver should never call this case.%d", (int)*iflag);
    break;
  }

  return 0;
}