From fff2ee55318e6378b494a98e7f400c62dbf174d9 Mon Sep 17 00:00:00 2001 From: Willi Braun Date: Thu, 12 Nov 2015 02:18:59 +0100 Subject: [PATCH] - added new linear solver klu from suitespase --- Compiler/runtime/omc_config.h | 2 +- SimulationRuntime/c/Makefile.objs | 2 +- .../c/simulation/solver/linearSolverKlu.c | 370 ++++++++++++++++++ .../c/simulation/solver/linearSolverKlu.h | 68 ++++ .../c/simulation/solver/linearSystem.c | 27 ++ SimulationRuntime/c/util/simulation_options.c | 2 + SimulationRuntime/c/util/simulation_options.h | 1 + configure.ac | 2 +- 8 files changed, 471 insertions(+), 3 deletions(-) create mode 100644 SimulationRuntime/c/simulation/solver/linearSolverKlu.c create mode 100644 SimulationRuntime/c/simulation/solver/linearSolverKlu.h diff --git a/Compiler/runtime/omc_config.h b/Compiler/runtime/omc_config.h index 3b7d80739da..03deb68003b 100644 --- a/Compiler/runtime/omc_config.h +++ b/Compiler/runtime/omc_config.h @@ -55,7 +55,7 @@ #endif /* adrpo: add -loleaut32 as is used by ExternalMedia */ -#define BASIC_LDFLAGS_RT " -lomcgc -lexpat -lregex -static-libgcc -luuid -loleaut32 -lole32 -lws2_32 -llis -lumfpack -lamd -lsundials_kinsol -lsundials_nvecserial -lipopt -lcoinmumps -lpthread -lm -lgfortranbegin -lgfortran -lmingw32 -lgcc_eh -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 -ladvapi32 -lshell32 -llapack-mingw -lcminpack -ltmglib-mingw -lblas-mingw -lf2c" +#define BASIC_LDFLAGS_RT " -lomcgc -lexpat -lregex -static-libgcc -luuid -loleaut32 -lole32 -lws2_32 -llis -lumfpack -lklu -lcolamd -lbtf -lamd -lsundials_kinsol -lsundials_nvecserial -lipopt -lcoinmumps -lpthread -lm -lgfortranbegin -lgfortran -lmingw32 -lgcc_eh -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 -ladvapi32 -lshell32 -llapack-mingw -lcminpack -ltmglib-mingw -lblas-mingw -lf2c" #define LDFLAGS_RT " -lOpenModelicaRuntimeC" BASIC_LDFLAGS_RT #define LDFLAGS_RT_SIM " -lSimulationRuntimeC" BASIC_LDFLAGS_RT " -lwsock32 -lstdc++" #define LDFLAGS_RT_SOURCE_FMU " -lregex -static-libgcc -lpthread -lm -lgfortranbegin -lgfortran -lmingw32 -lgcc_eh -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 -ladvapi32 -lshell32 -llapack-mingw -ltmglib-mingw -lblas-mingw -lf2c" diff --git a/SimulationRuntime/c/Makefile.objs b/SimulationRuntime/c/Makefile.objs index 913f4138869..761e6212f17 100644 --- a/SimulationRuntime/c/Makefile.objs +++ b/SimulationRuntime/c/Makefile.objs @@ -43,7 +43,7 @@ else SOLVER_OBJS_MINIMAL=$(SOLVER_OBJS_FMU) endif ifeq ($(OMC_MINIMAL_RUNTIME),) -SOLVER_OBJS=$(SOLVER_OBJS_MINIMAL) kinsolSolver$(OBJ_EXT) linearSolverLis$(OBJ_EXT) linearSolverUmfpack$(OBJ_EXT) dassl$(OBJ_EXT) radau$(OBJ_EXT) sym_imp_euler$(OBJ_EXT) nonlinearSolverNewton$(OBJ_EXT) newtonIteration$(OBJ_EXT) +SOLVER_OBJS=$(SOLVER_OBJS_MINIMAL) kinsolSolver$(OBJ_EXT) linearSolverKlu$(OBJ_EXT) linearSolverLis$(OBJ_EXT) linearSolverUmfpack$(OBJ_EXT) dassl$(OBJ_EXT) radau$(OBJ_EXT) sym_imp_euler$(OBJ_EXT) nonlinearSolverNewton$(OBJ_EXT) newtonIteration$(OBJ_EXT) else SOLVER_OBJS=$(SOLVER_OBJS_MINIMAL) endif diff --git a/SimulationRuntime/c/simulation/solver/linearSolverKlu.c b/SimulationRuntime/c/simulation/solver/linearSolverKlu.c new file mode 100644 index 00000000000..5972b4fcc4b --- /dev/null +++ b/SimulationRuntime/c/simulation/solver/linearSolverKlu.c @@ -0,0 +1,370 @@ +/* + * This file is part of OpenModelica. + * + * Copyright (c) 1998-2014, Open Source Modelica Consortium (OSMC), + * c/o Linköpings universitet, Department of Computer and Information Science, + * SE-58183 Linköping, Sweden. + * + * All rights reserved. + * + * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THE BSD NEW LICENSE OR THE + * GPL VERSION 3 LICENSE OR THE OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2. + * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES + * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3, + * ACCORDING TO RECIPIENTS CHOICE. + * + * The OpenModelica software and the OSMC (Open Source Modelica Consortium) + * Public License (OSMC-PL) are obtained from OSMC, either from the above + * address, from the URLs: http://www.openmodelica.org or + * http://www.ida.liu.se/projects/OpenModelica, and in the OpenModelica + * distribution. GNU version 3 is obtained from: + * http://www.gnu.org/copyleft/gpl.html. The New BSD License is obtained from: + * http://www.opensource.org/licenses/BSD-3-Clause. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, EXCEPT AS + * EXPRESSLY SET FORTH IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE + * CONDITIONS OF OSMC-PL. + * + */ + +/*! \file linearSolverKlu.c + */ + +#include "omc_config.h" + +#ifdef WITH_UMFPACK +#include +#include +#include + +#include "simulation_data.h" +#include "simulation/simulation_info_json.h" +#include "util/omc_error.h" +#include "util/varinfo.h" +#include "model_help.h" + +#include "linearSystem.h" +#include "linearSolverKlu.h" + + +static void printMatrixCSC(int* Ap, int* Ai, double* Ax, int n); +static void printMatrixCSR(int* Ap, int* Ai, double* Ax, int n); + +/*! \fn allocate memory for linear system solver Klu + * + */ +int +allocateKluData(int n_row, int n_col, int nz, void** voiddata) +{ + DATA_KLU* data = (DATA_KLU*) malloc(sizeof(DATA_KLU)); + assertStreamPrint(NULL, 0 != data, "Could not allocate data for linear solver Klu."); + + data->symbolic = NULL; + data->numeric = NULL; + + data->n_col = n_col; + data->n_row = n_row; + data->nnz = nz; + + data->Ap = (int*) calloc((n_row+1),sizeof(int)); + + data->Ai = (int*) calloc(nz,sizeof(int)); + data->Ax = (double*) calloc(nz,sizeof(double)); + data->work = (double*) calloc(n_col,sizeof(double)); + + data->numberSolving = 0; + klu_defaults(&(data->common)); + + *voiddata = (void*)data; + + return 0; +} + + +/*! \fn free memory for linear system solver Klu + * + */ +int +freeKluData(void **voiddata) +{ + TRACE_PUSH + + DATA_KLU* data = (DATA_KLU*) *voiddata; + + free(data->Ap); + free(data->Ai); + free(data->Ax); + free(data->work); + + if(data->symbolic) + klu_free_symbolic(&data->symbolic, &data->common); + if(data->numeric) + klu_free_numeric(&data->numeric, &data->common); + + TRACE_POP + return 0; +} + +/*! \fn getAnalyticalJacobian + * + * function calculates analytical jacobian + * + * \param [ref] [data] + * \param [in] [sysNumber] + * + * \author wbraun + * + */ +static +int getAnalyticalJacobian(DATA* data, threadData_t *threadData, int sysNumber) +{ + int i,ii,j,k,l; + LINEAR_SYSTEM_DATA* systemData = &(((DATA*)data)->simulationInfo.linearSystemData[sysNumber]); + + const int index = systemData->jacobianIndex; + int nth = 0; + int nnz = data->simulationInfo.analyticJacobians[index].sparsePattern.numberOfNoneZeros; + + for(i=0; i < data->simulationInfo.analyticJacobians[index].sizeRows; i++) + { + data->simulationInfo.analyticJacobians[index].seedVars[i] = 1; + + ((systemData->analyticalJacobianColumn))(data, threadData); + + for(j = 0; j < data->simulationInfo.analyticJacobians[index].sizeCols; j++) + { + if(data->simulationInfo.analyticJacobians[index].seedVars[j] == 1) + { + if(j==0) + ii = 0; + else + ii = data->simulationInfo.analyticJacobians[index].sparsePattern.leadindex[j-1]; + while(ii < data->simulationInfo.analyticJacobians[index].sparsePattern.leadindex[j]) + { + l = data->simulationInfo.analyticJacobians[index].sparsePattern.index[ii]; + systemData->setAElement(i, l, -data->simulationInfo.analyticJacobians[index].resultVars[l], nth, (void*) systemData, threadData); + nth++; + ii++; + }; + } + }; + + /* de-activate seed variable for the corresponding color */ + data->simulationInfo.analyticJacobians[index].seedVars[i] = 0; + } + + return 0; +} + +/*! \fn residual_wrapper for the residual function + * + */ +static int residual_wrapper(double* x, double* f, void** data, int sysNumber) +{ + int iflag = 0; + + (*((DATA*)data[0])->simulationInfo.linearSystemData[sysNumber].residualFunc)(data, x, f, &iflag); + return 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; in_row; i++){ + infoStreamPrint(LOG_LS_V, 0, "%d. Ap => %d -> %d", i, solverData->Ap[i], solverData->Ap[i+1]); + for (j=solverData->Ap[i]; jAp[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; in_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; +} + +static +void printMatrixCSC(int* Ap, int* Ai, double* Ax, int n) +{ + int i, j, k, l; + + char buffer[400][4096] = {0}; + + k = 0; + for (i = 0; i < n; i++) + { + for (j = 0; j < n; j++) + { + if ((k < Ap[i + 1]) && (Ai[k] == j)) + { + sprintf(buffer[j], "%s %5g ", buffer[j], Ax[k]); + k++; + } + else + { + sprintf(buffer[j], "%s %5g ", buffer[j], 0.0); + } + } + } + for (l = 0; l < n; l++) + { + infoStreamPrint(LOG_LS_V, 0, "%s", buffer[l]); + } + +} + +static +void printMatrixCSR(int* Ap, int* Ai, double* Ax, int n) +{ + int i, j, k; + char buffer[1024] = {0}; + k = 0; + for (i = 0; i < n; i++) + { + for (j = 0; j < n; j++) + { + if ((k < Ap[i + 1]) && (Ai[k] == j)) + { + sprintf(buffer, "%s %5.2g ", buffer, Ax[k]); + k++; + } + else + { + sprintf(buffer, "%s %5.2g ", buffer, 0.0); + } + } + infoStreamPrint(LOG_LS_V, 0, "%s", buffer); + memset(buffer, 0, 1024); + } +} + +#endif diff --git a/SimulationRuntime/c/simulation/solver/linearSolverKlu.h b/SimulationRuntime/c/simulation/solver/linearSolverKlu.h new file mode 100644 index 00000000000..e6c8f7859ab --- /dev/null +++ b/SimulationRuntime/c/simulation/solver/linearSolverKlu.h @@ -0,0 +1,68 @@ +/* + * This file is part of OpenModelica. + * + * Copyright (c) 1998-CurrentYear, Open Source Modelica Consortium (OSMC), + * c/o Linköpings universitet, Department of Computer and Information Science, + * SE-58183 Linköping, Sweden. + * + * All rights reserved. + * + * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THE BSD NEW LICENSE OR THE + * GPL VERSION 3 LICENSE OR THE OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2. + * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES + * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3, + * ACCORDING TO RECIPIENTS CHOICE. + * + * The OpenModelica software and the OSMC (Open Source Modelica Consortium) + * Public License (OSMC-PL) are obtained from OSMC, either from the above + * address, from the URLs: http://www.openmodelica.org or + * http://www.ida.liu.se/projects/OpenModelica, and in the OpenModelica + * distribution. GNU version 3 is obtained from: + * http://www.gnu.org/copyleft/gpl.html. The New BSD License is obtained from: + * http://www.opensource.org/licenses/BSD-3-Clause. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, EXCEPT AS + * EXPRESSLY SET FORTH IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE + * CONDITIONS OF OSMC-PL. + * + */ + +/*! \file linearSolverKlu.h + */ + +#include "omc_config.h" + +#ifdef WITH_UMFPACK +#ifndef _LINEARSOLVERKLU_H_ +#define _LINEARSOLVERKLU_H_ + +#include "simulation_data.h" +#include "suitesparse/Include/amd.h" +#include "suitesparse/Include/klu.h" + +typedef struct DATA_KLU +{ + int *Ap; + int *Ai; + double *Ax; + int n_col; + int n_row; + int nnz; + klu_symbolic *symbolic; + klu_numeric *numeric; + klu_common common; + + double* work; + + rtclock_t timeClock; /* time clock */ + int numberSolving; + +} DATA_KLU; + +int allocateKluData(int n_row, int n_col, int nz, void **data); +int freeKluData(void **data); +int solveKlu(DATA *data, threadData_t *threadData, int sysNumber); + +#endif +#endif diff --git a/SimulationRuntime/c/simulation/solver/linearSystem.c b/SimulationRuntime/c/simulation/solver/linearSystem.c index 30880f8e593..06866ecfb8a 100644 --- a/SimulationRuntime/c/simulation/solver/linearSystem.c +++ b/SimulationRuntime/c/simulation/solver/linearSystem.c @@ -39,6 +39,7 @@ #include "linearSystem.h" #include "linearSolverLapack.h" #if !defined(OMC_MINIMAL_RUNTIME) +#include "linearSolverKlu.h" #include "linearSolverLis.h" #include "linearSolverUmfpack.h" #endif @@ -48,6 +49,7 @@ static void setAElement(int row, int col, double value, int nth, void *data, threadData_t *); static void setAElementLis(int row, int col, double value, int nth, void *data, threadData_t *); static void setAElementUmfpack(int row, int col, double value, int nth, void *data, threadData_t *); +static void setAElementKlu(int row, int col, double value, int nth, void *data, threadData_t *); static void setBElement(int row, double value, void *data, threadData_t*); static void setBElementLis(int row, double value, void *data, threadData_t*); @@ -136,6 +138,11 @@ int initializeLinearSystems(DATA *data, threadData_t *threadData) linsys[i].setBElement = setBElement; allocateUmfPackData(size, size, nnz, &linsys[i].solverData); break; + case LS_KLU: + linsys[i].setAElement = setAElementKlu; + linsys[i].setBElement = setBElement; + allocateKluData(size, size, nnz, &linsys[i].solverData); + break; #else case LS_UMFPACK: throwStreamPrint(threadData, "OMC is compiled without UMFPACK, if you want use umfpack please compile OMC with UMFPACK."); @@ -256,6 +263,9 @@ int freeLinearSystems(DATA *data, threadData_t *threadData) case LS_UMFPACK: freeUmfPackData(&linsys[i].solverData); break; + case LS_KLU: + freeKluData(&linsys[i].solverData); + break; #else case LS_UMFPACK: throwStreamPrint(threadData, "OMC is compiled without UMFPACK, if you want use umfpack please compile OMC with UMFPACK."); @@ -315,6 +325,9 @@ int solve_linear_system(DATA *data, threadData_t *threadData, int sysNumber) break; #endif #ifdef WITH_UMFPACK + case LS_KLU: + success = solveKlu(data, threadData, sysNumber); + break; case LS_UMFPACK: success = solveUmfPack(data, threadData, sysNumber); break; @@ -510,4 +523,18 @@ static void setAElementUmfpack(int row, int col, double value, int nth, void *da sData->Ai[nth] = col; sData->Ax[nth] = value; } +static void setAElementKlu(int row, int col, double value, int nth, void *data, threadData_t *threadData) +{ + LINEAR_SYSTEM_DATA* linSys = (LINEAR_SYSTEM_DATA*) data; + DATA_KLU* sData = (DATA_KLU*) linSys->solverData; + + if (row > 0){ + if (sData->Ap[row] == 0){ + sData->Ap[row] = nth; + } + } + + sData->Ai[nth] = col; + sData->Ax[nth] = value; +} #endif diff --git a/SimulationRuntime/c/util/simulation_options.c b/SimulationRuntime/c/util/simulation_options.c index 59694c74ec9..174dee6e52c 100644 --- a/SimulationRuntime/c/util/simulation_options.c +++ b/SimulationRuntime/c/util/simulation_options.c @@ -389,6 +389,7 @@ const char *LS_NAME[LS_MAX+1] = { #if !defined(OMC_MINIMAL_RUNTIME) /* LS_LIS */ "lis", #endif + /* LS_KLU */ "klu", /* LS_UMFPACK */ "umfpack", /* LS_TOTALPIVOT */ "totalpivot", /* LS_DEFAULT */ "default", @@ -403,6 +404,7 @@ const char *LS_DESC[LS_MAX+1] = { #if !defined(OMC_MINIMAL_RUNTIME) /* LS_LIS */ "method using iterativ solver Lis", #endif + /* LS_KLU */ "method using klu sparse linear solver", /* LS_UMFPACK */ "method using umfpack sparse linear solver", /* LS_TOTALPIVOT */ "method using a total pivoting LU factorization for underdetermination systems", /* LS_DEFAULT */ "default method - lapack with total pivoting as fallback", diff --git a/SimulationRuntime/c/util/simulation_options.h b/SimulationRuntime/c/util/simulation_options.h index 40af30e1fc8..a04202858f5 100644 --- a/SimulationRuntime/c/util/simulation_options.h +++ b/SimulationRuntime/c/util/simulation_options.h @@ -152,6 +152,7 @@ enum LINEAR_SOLVER #if !defined(OMC_MINIMAL_RUNTIME) LS_LIS, #endif + LS_KLU, LS_UMFPACK, LS_TOTALPIVOT, LS_DEFAULT, diff --git a/configure.ac b/configure.ac index c9e6c57f139..2858ae858ea 100644 --- a/configure.ac +++ b/configure.ac @@ -596,7 +596,7 @@ AS_IF([test "x$with_UMFPACK" = xyes], FINAL_MESSAGES="$FINAL_MESSAGES\nSimulations may use UMFPACK: Yes" UMFPACK_TARGET="umfpack"; WITH_UMFPACK="#define WITH_UMFPACK" - UMFPACK_LDFLAGS="-lumfpack -lamd" + UMFPACK_LDFLAGS="-lumfpack -lklu -lbtf -lcolamd -lamd" ],[ FINAL_MESSAGES="$FINAL_MESSAGES\nSimulations may use UMFPACK: No" UMFPACK_TARGET="";