Ejemplo n.º 1
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;
}
Ejemplo n.º 2
0
/*! \fn solve linear system with Klu method
 *
 *  \param  [in]  [data]
 *                [sysNumber] index of the corresponding linear system
 *
 *
 * author: wbraun
 */
int
solveKlu(DATA *data, threadData_t *threadData, int sysNumber)
{
  void *dataAndThreadData[2] = {data, threadData};
  LINEAR_SYSTEM_DATA* systemData = &(data->simulationInfo->linearSystemData[sysNumber]);
  DATA_KLU* solverData = (DATA_KLU*)systemData->solverData;

  int i, j, status = 0, success = 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 Klu 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, threadData, 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, threadData, systemData);
  } else {

    solverData->Ap[0] = 0;
    /* calculate jacobian -> matrix A*/
    if(systemData->jacobianIndex != -1){
      getAnalyticalJacobian(data, threadData, sysNumber);
    } else {
      assertStreamPrint(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);
    residual_wrapper(solverData->work, systemData->b, dataAndThreadData, 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)
  {
    infoStreamPrint(LOG_LS_V, 0, "Perform analyze settings:\n - ordering used: %d\n - current status: %d", solverData->common.ordering, solverData->common.status);
    solverData->symbolic = klu_analyze(solverData->n_col, solverData->Ap, solverData->Ai, &solverData->common);
  }

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

  if (0 == solverData->common.status){
    if (1 == systemData->method){
      if (klu_solve(solverData->symbolic, solverData->numeric, solverData->n_col, 1, systemData->b, &solverData->common)){
        success = 1;
      }
    } else {
      if (klu_tsolve(solverData->symbolic, solverData->numeric, solverData->n_col, 1, systemData->b, &solverData->common)){
        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] += systemData->b[i];

      /* update inner equations */
      residual_wrapper(systemData->x, solverData->work, dataAndThreadData, sysNumber);
    } else {
      /* the solution is automatically in x */
      memcpy(systemData->x, systemData->b, sizeof(double)*systemData->size);
    }

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