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