14eb8e494SKris Buschelman /* 24eb8e494SKris Buschelman Provides an interface to the LUSOL package of .... 34eb8e494SKris Buschelman 44eb8e494SKris Buschelman */ 5c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h> 64eb8e494SKris Buschelman 74eb8e494SKris Buschelman #if defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 84eb8e494SKris Buschelman #define LU1FAC lu1fac_ 94eb8e494SKris Buschelman #define LU6SOL lu6sol_ 104eb8e494SKris Buschelman #define M1PAGE m1page_ 114eb8e494SKris Buschelman #define M5SETX m5setx_ 124eb8e494SKris Buschelman #define M6RDEL m6rdel_ 134eb8e494SKris Buschelman #elif !defined(PETSC_HAVE_FORTRAN_CAPS) 144eb8e494SKris Buschelman #define LU1FAC lu1fac 154eb8e494SKris Buschelman #define LU6SOL lu6sol 164eb8e494SKris Buschelman #define M1PAGE m1page 174eb8e494SKris Buschelman #define M5SETX m5setx 184eb8e494SKris Buschelman #define M6RDEL m6rdel 194eb8e494SKris Buschelman #endif 204eb8e494SKris Buschelman 214eb8e494SKris Buschelman /* 224eb8e494SKris Buschelman Dummy symbols that the MINOS files mi25bfac.f and mi15blas.f may require 234eb8e494SKris Buschelman */ 24d71ae5a4SJacob Faibussowitsch PETSC_EXTERN void M1PAGE() 25d71ae5a4SJacob Faibussowitsch { 264eb8e494SKris Buschelman ; 274eb8e494SKris Buschelman } 28d71ae5a4SJacob Faibussowitsch PETSC_EXTERN void M5SETX() 29d71ae5a4SJacob Faibussowitsch { 304eb8e494SKris Buschelman ; 314eb8e494SKris Buschelman } 324eb8e494SKris Buschelman 33d71ae5a4SJacob Faibussowitsch PETSC_EXTERN void M6RDEL() 34d71ae5a4SJacob Faibussowitsch { 354eb8e494SKris Buschelman ; 364eb8e494SKris Buschelman } 374eb8e494SKris Buschelman 389371c9d4SSatish Balay PETSC_EXTERN void LU1FAC(int *m, int *n, int *nnz, int *size, int *luparm, double *parmlu, double *data, int *indc, int *indr, int *rowperm, int *colperm, int *collen, int *rowlen, int *colstart, int *rowstart, int *rploc, int *cploc, int *rpinv, int *cpinv, double *w, int *inform); 394eb8e494SKris Buschelman 409371c9d4SSatish Balay PETSC_EXTERN void LU6SOL(int *mode, int *m, int *n, double *rhs, double *x, int *size, int *luparm, double *parmlu, double *data, int *indc, int *indr, int *rowperm, int *colperm, int *collen, int *rowlen, int *colstart, int *rowstart, int *inform); 414eb8e494SKris Buschelman 4209573ac7SBarry Smith extern PetscErrorCode MatDuplicate_LUSOL(Mat, MatDuplicateOption, Mat *); 43f0c56d0fSKris Buschelman 44f0c56d0fSKris Buschelman typedef struct { 454eb8e494SKris Buschelman double *data; 464eb8e494SKris Buschelman int *indc; 474eb8e494SKris Buschelman int *indr; 484eb8e494SKris Buschelman 494eb8e494SKris Buschelman int *ip; 504eb8e494SKris Buschelman int *iq; 514eb8e494SKris Buschelman int *lenc; 524eb8e494SKris Buschelman int *lenr; 534eb8e494SKris Buschelman int *locc; 544eb8e494SKris Buschelman int *locr; 554eb8e494SKris Buschelman int *iploc; 564eb8e494SKris Buschelman int *iqloc; 574eb8e494SKris Buschelman int *ipinv; 584eb8e494SKris Buschelman int *iqinv; 594eb8e494SKris Buschelman double *mnsw; 604eb8e494SKris Buschelman double *mnsv; 614eb8e494SKris Buschelman 624eb8e494SKris Buschelman double elbowroom; 634eb8e494SKris Buschelman double luroom; /* Extra space allocated when factor fails */ 644eb8e494SKris Buschelman double parmlu[30]; /* Input/output to LUSOL */ 654eb8e494SKris Buschelman 664eb8e494SKris Buschelman int n; /* Number of rows/columns in matrix */ 674eb8e494SKris Buschelman int nz; /* Number of nonzeros */ 684eb8e494SKris Buschelman int nnz; /* Number of nonzeros allocated for factors */ 694eb8e494SKris Buschelman int luparm[30]; /* Input/output to LUSOL */ 704eb8e494SKris Buschelman 71ace3abfcSBarry Smith PetscBool CleanUpLUSOL; 724eb8e494SKris Buschelman 73f0c56d0fSKris Buschelman } Mat_LUSOL; 744eb8e494SKris Buschelman 754eb8e494SKris Buschelman /* LUSOL input/Output Parameters (Description uses C-style indexes 764eb8e494SKris Buschelman * 774eb8e494SKris Buschelman * Input parameters Typical value 784eb8e494SKris Buschelman * 794eb8e494SKris Buschelman * luparm(0) = nout File number for printed messages. 6 804eb8e494SKris Buschelman * luparm(1) = lprint Print level. 0 814eb8e494SKris Buschelman * < 0 suppresses output. 824eb8e494SKris Buschelman * = 0 gives error messages. 834eb8e494SKris Buschelman * = 1 gives debug output from some of the 844eb8e494SKris Buschelman * other routines in LUSOL. 854eb8e494SKris Buschelman * >= 2 gives the pivot row and column and the 864eb8e494SKris Buschelman * no. of rows and columns involved at 874eb8e494SKris Buschelman * each elimination step in lu1fac. 884eb8e494SKris Buschelman * luparm(2) = maxcol lu1fac: maximum number of columns 5 894eb8e494SKris Buschelman * searched allowed in a Markowitz-type 904eb8e494SKris Buschelman * search for the next pivot element. 914eb8e494SKris Buschelman * For some of the factorization, the 924eb8e494SKris Buschelman * number of rows searched is 934eb8e494SKris Buschelman * maxrow = maxcol - 1. 944eb8e494SKris Buschelman * 954eb8e494SKris Buschelman * 967a7aea1fSJed Brown * Output parameters: 974eb8e494SKris Buschelman * 984eb8e494SKris Buschelman * luparm(9) = inform Return code from last call to any LU routine. 994eb8e494SKris Buschelman * luparm(10) = nsing No. of singularities marked in the 1004eb8e494SKris Buschelman * output array w(*). 1014eb8e494SKris Buschelman * luparm(11) = jsing Column index of last singularity. 1024eb8e494SKris Buschelman * luparm(12) = minlen Minimum recommended value for lena. 1034eb8e494SKris Buschelman * luparm(13) = maxlen ? 1044eb8e494SKris Buschelman * luparm(14) = nupdat No. of updates performed by the lu8 routines. 1054eb8e494SKris Buschelman * luparm(15) = nrank No. of nonempty rows of U. 1064eb8e494SKris Buschelman * luparm(16) = ndens1 No. of columns remaining when the density of 1074eb8e494SKris Buschelman * the matrix being factorized reached dens1. 1084eb8e494SKris Buschelman * luparm(17) = ndens2 No. of columns remaining when the density of 1094eb8e494SKris Buschelman * the matrix being factorized reached dens2. 1104eb8e494SKris Buschelman * luparm(18) = jumin The column index associated with dumin. 1114eb8e494SKris Buschelman * luparm(19) = numl0 No. of columns in initial L. 1124eb8e494SKris Buschelman * luparm(20) = lenl0 Size of initial L (no. of nonzeros). 1134eb8e494SKris Buschelman * luparm(21) = lenu0 Size of initial U. 1144eb8e494SKris Buschelman * luparm(22) = lenl Size of current L. 1154eb8e494SKris Buschelman * luparm(23) = lenu Size of current U. 1164eb8e494SKris Buschelman * luparm(24) = lrow Length of row file. 1174eb8e494SKris Buschelman * luparm(25) = ncp No. of compressions of LU data structures. 1184eb8e494SKris Buschelman * luparm(26) = mersum lu1fac: sum of Markowitz merit counts. 1194eb8e494SKris Buschelman * luparm(27) = nutri lu1fac: triangular rows in U. 1204eb8e494SKris Buschelman * luparm(28) = nltri lu1fac: triangular rows in L. 1214eb8e494SKris Buschelman * luparm(29) = 1224eb8e494SKris Buschelman * 1234eb8e494SKris Buschelman * 1244eb8e494SKris Buschelman * Input parameters Typical value 1254eb8e494SKris Buschelman * 1264eb8e494SKris Buschelman * parmlu(0) = elmax1 Max multiplier allowed in L 10.0 1274eb8e494SKris Buschelman * during factor. 1284eb8e494SKris Buschelman * parmlu(1) = elmax2 Max multiplier allowed in L 10.0 1294eb8e494SKris Buschelman * during updates. 1304eb8e494SKris Buschelman * parmlu(2) = small Absolute tolerance for eps**0.8 1314eb8e494SKris Buschelman * treating reals as zero. IBM double: 3.0d-13 1324eb8e494SKris Buschelman * parmlu(3) = utol1 Absolute tol for flagging eps**0.66667 1334eb8e494SKris Buschelman * small diagonals of U. IBM double: 3.7d-11 1344eb8e494SKris Buschelman * parmlu(4) = utol2 Relative tol for flagging eps**0.66667 1354eb8e494SKris Buschelman * small diagonals of U. IBM double: 3.7d-11 1364eb8e494SKris Buschelman * parmlu(5) = uspace Factor limiting waste space in U. 3.0 1374eb8e494SKris Buschelman * In lu1fac, the row or column lists 1384eb8e494SKris Buschelman * are compressed if their length 1394eb8e494SKris Buschelman * exceeds uspace times the length of 1404eb8e494SKris Buschelman * either file after the last compression. 1414eb8e494SKris Buschelman * parmlu(6) = dens1 The density at which the Markowitz 0.3 1424eb8e494SKris Buschelman * strategy should search maxcol columns 1434eb8e494SKris Buschelman * and no rows. 1444eb8e494SKris Buschelman * parmlu(7) = dens2 the density at which the Markowitz 0.6 1454eb8e494SKris Buschelman * strategy should search only 1 column 1464eb8e494SKris Buschelman * or (preferably) use a dense LU for 1474eb8e494SKris Buschelman * all the remaining rows and columns. 1484eb8e494SKris Buschelman * 1494eb8e494SKris Buschelman * 1507a7aea1fSJed Brown * Output parameters: 1514eb8e494SKris Buschelman * 1524eb8e494SKris Buschelman * parmlu(9) = amax Maximum element in A. 1534eb8e494SKris Buschelman * parmlu(10) = elmax Maximum multiplier in current L. 1544eb8e494SKris Buschelman * parmlu(11) = umax Maximum element in current U. 1554eb8e494SKris Buschelman * parmlu(12) = dumax Maximum diagonal in U. 1564eb8e494SKris Buschelman * parmlu(13) = dumin Minimum diagonal in U. 1574eb8e494SKris Buschelman * parmlu(14) = 1584eb8e494SKris Buschelman * parmlu(15) = 1594eb8e494SKris Buschelman * parmlu(16) = 1604eb8e494SKris Buschelman * parmlu(17) = 1614eb8e494SKris Buschelman * parmlu(18) = 1624eb8e494SKris Buschelman * parmlu(19) = resid lu6sol: residual after solve with U or U'. 1634eb8e494SKris Buschelman * ... 1644eb8e494SKris Buschelman * parmlu(29) = 1654eb8e494SKris Buschelman */ 1664eb8e494SKris Buschelman 1674eb8e494SKris Buschelman #define Factorization_Tolerance 1e-1 1684eb8e494SKris Buschelman #define Factorization_Pivot_Tolerance pow(2.2204460492503131E-16, 2.0 / 3.0) 1694eb8e494SKris Buschelman #define Factorization_Small_Tolerance 1e-15 /* pow(DBL_EPSILON, 0.8) */ 1704eb8e494SKris Buschelman 17166976f2fSJacob Faibussowitsch static PetscErrorCode MatDestroy_LUSOL(Mat A) 172d71ae5a4SJacob Faibussowitsch { 173f0c56d0fSKris Buschelman Mat_LUSOL *lusol = (Mat_LUSOL *)A->spptr; 1744eb8e494SKris Buschelman 1754eb8e494SKris Buschelman PetscFunctionBegin; 176bf0cc555SLisandro Dalcin if (lusol && lusol->CleanUpLUSOL) { 1779566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->ip)); 1789566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->iq)); 1799566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->lenc)); 1809566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->lenr)); 1819566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->locc)); 1829566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->locr)); 1839566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->iploc)); 1849566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->iqloc)); 1859566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->ipinv)); 1869566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->iqinv)); 1879566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->mnsw)); 1889566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->mnsv)); 1899566063dSJacob Faibussowitsch PetscCall(PetscFree3(lusol->data, lusol->indc, lusol->indr)); 1904eb8e494SKris Buschelman } 1919566063dSJacob Faibussowitsch PetscCall(PetscFree(A->spptr)); 1929566063dSJacob Faibussowitsch PetscCall(MatDestroy_SeqAIJ(A)); 1933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1944eb8e494SKris Buschelman } 1954eb8e494SKris Buschelman 19666976f2fSJacob Faibussowitsch static PetscErrorCode MatSolve_LUSOL(Mat A, Vec b, Vec x) 197d71ae5a4SJacob Faibussowitsch { 198f0c56d0fSKris Buschelman Mat_LUSOL *lusol = (Mat_LUSOL *)A->spptr; 199d9ca1df4SBarry Smith double *xx; 200d9ca1df4SBarry Smith const double *bb; 2014eb8e494SKris Buschelman int mode = 5; 2026849ba73SBarry Smith int i, m, n, nnz, status; 2034eb8e494SKris Buschelman 2044eb8e494SKris Buschelman PetscFunctionBegin; 2059566063dSJacob Faibussowitsch PetscCall(VecGetArray(x, &xx)); 2069566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(b, &bb)); 2074eb8e494SKris Buschelman 2084eb8e494SKris Buschelman m = n = lusol->n; 2094eb8e494SKris Buschelman nnz = lusol->nnz; 2104eb8e494SKris Buschelman 2112205254eSKarl Rupp for (i = 0; i < m; i++) lusol->mnsv[i] = bb[i]; 2124eb8e494SKris Buschelman 2139371c9d4SSatish Balay LU6SOL(&mode, &m, &n, lusol->mnsv, xx, &nnz, lusol->luparm, lusol->parmlu, lusol->data, lusol->indc, lusol->indr, lusol->ip, lusol->iq, lusol->lenc, lusol->lenr, lusol->locc, lusol->locr, &status); 2144eb8e494SKris Buschelman 21528b400f6SJacob Faibussowitsch PetscCheck(!status, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "solve failed, error code %d", status); 2164eb8e494SKris Buschelman 2179566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(x, &xx)); 2189566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(b, &bb)); 2193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2204eb8e494SKris Buschelman } 2214eb8e494SKris Buschelman 22266976f2fSJacob Faibussowitsch static PetscErrorCode MatLUFactorNumeric_LUSOL(Mat F, Mat A, const MatFactorInfo *info) 223d71ae5a4SJacob Faibussowitsch { 2244eb8e494SKris Buschelman Mat_SeqAIJ *a; 225719d5645SBarry Smith Mat_LUSOL *lusol = (Mat_LUSOL *)F->spptr; 2264eb8e494SKris Buschelman int m, n, nz, nnz, status; 2276849ba73SBarry Smith int i, rs, re; 2284eb8e494SKris Buschelman int factorizations; 2294eb8e494SKris Buschelman 2304eb8e494SKris Buschelman PetscFunctionBegin; 2319566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 2324eb8e494SKris Buschelman a = (Mat_SeqAIJ *)A->data; 2334eb8e494SKris Buschelman 23408401ef6SPierre Jolivet PetscCheck(m == lusol->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "factorization struct inconsistent"); 2354eb8e494SKris Buschelman 2364eb8e494SKris Buschelman factorizations = 0; 2372205254eSKarl Rupp do { 2384eb8e494SKris Buschelman /*******************************************************************/ 2394eb8e494SKris Buschelman /* Check the workspace allocation. */ 2404eb8e494SKris Buschelman /*******************************************************************/ 2414eb8e494SKris Buschelman 2424eb8e494SKris Buschelman nz = a->nz; 2434eb8e494SKris Buschelman nnz = PetscMax(lusol->nnz, (int)(lusol->elbowroom * nz)); 2444eb8e494SKris Buschelman nnz = PetscMax(nnz, 5 * n); 2454eb8e494SKris Buschelman 2464eb8e494SKris Buschelman if (nnz < lusol->luparm[12]) { 2474eb8e494SKris Buschelman nnz = (int)(lusol->luroom * lusol->luparm[12]); 2484eb8e494SKris Buschelman } else if ((factorizations > 0) && (lusol->luroom < 6)) { 2494eb8e494SKris Buschelman lusol->luroom += 0.1; 2504eb8e494SKris Buschelman } 2514eb8e494SKris Buschelman 2524eb8e494SKris Buschelman nnz = PetscMax(nnz, (int)(lusol->luroom * (lusol->luparm[22] + lusol->luparm[23]))); 2534eb8e494SKris Buschelman 2544eb8e494SKris Buschelman if (nnz > lusol->nnz) { 2559566063dSJacob Faibussowitsch PetscCall(PetscFree3(lusol->data, lusol->indc, lusol->indr)); 2569566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(nnz, &lusol->data, nnz, &lusol->indc, nnz, &lusol->indr)); 2574eb8e494SKris Buschelman lusol->nnz = nnz; 2584eb8e494SKris Buschelman } 2594eb8e494SKris Buschelman 2604eb8e494SKris Buschelman /*******************************************************************/ 2614eb8e494SKris Buschelman /* Fill in the data for the problem. (1-based Fortran style) */ 2624eb8e494SKris Buschelman /*******************************************************************/ 2634eb8e494SKris Buschelman 2644eb8e494SKris Buschelman nz = 0; 2652205254eSKarl Rupp for (i = 0; i < n; i++) { 2664eb8e494SKris Buschelman rs = a->i[i]; 2674eb8e494SKris Buschelman re = a->i[i + 1]; 2684eb8e494SKris Buschelman 2692205254eSKarl Rupp while (rs < re) { 2702205254eSKarl Rupp if (a->a[rs] != 0.0) { 2714eb8e494SKris Buschelman lusol->indc[nz] = i + 1; 2724eb8e494SKris Buschelman lusol->indr[nz] = a->j[rs] + 1; 2734eb8e494SKris Buschelman lusol->data[nz] = a->a[rs]; 2744eb8e494SKris Buschelman nz++; 2754eb8e494SKris Buschelman } 2764eb8e494SKris Buschelman rs++; 2774eb8e494SKris Buschelman } 2784eb8e494SKris Buschelman } 2794eb8e494SKris Buschelman 2804eb8e494SKris Buschelman /*******************************************************************/ 2814eb8e494SKris Buschelman /* Do the factorization. */ 2824eb8e494SKris Buschelman /*******************************************************************/ 2834eb8e494SKris Buschelman 2849371c9d4SSatish Balay LU1FAC(&m, &n, &nz, &nnz, lusol->luparm, lusol->parmlu, lusol->data, lusol->indc, lusol->indr, lusol->ip, lusol->iq, lusol->lenc, lusol->lenr, lusol->locc, lusol->locr, lusol->iploc, lusol->iqloc, lusol->ipinv, lusol->iqinv, lusol->mnsw, &status); 2854eb8e494SKris Buschelman 2862205254eSKarl Rupp switch (status) { 287d71ae5a4SJacob Faibussowitsch case 0: /* factored */ 288d71ae5a4SJacob Faibussowitsch break; 2894eb8e494SKris Buschelman 290d71ae5a4SJacob Faibussowitsch case 7: /* insufficient memory */ 291d71ae5a4SJacob Faibussowitsch break; 2924eb8e494SKris Buschelman 2934eb8e494SKris Buschelman case 1: 294d71ae5a4SJacob Faibussowitsch case -1: /* singular */ 295d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Singular matrix"); 2964eb8e494SKris Buschelman 2974eb8e494SKris Buschelman case 3: 298d71ae5a4SJacob Faibussowitsch case 4: /* error conditions */ 299d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "matrix error"); 3004eb8e494SKris Buschelman 301d71ae5a4SJacob Faibussowitsch default: /* unknown condition */ 302d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "matrix unknown return code"); 3034eb8e494SKris Buschelman } 3044eb8e494SKris Buschelman 3054eb8e494SKris Buschelman factorizations++; 3064eb8e494SKris Buschelman } while (status == 7); 307719d5645SBarry Smith F->ops->solve = MatSolve_LUSOL; 308719d5645SBarry Smith F->assembled = PETSC_TRUE; 309719d5645SBarry Smith F->preallocated = PETSC_TRUE; 3103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3114eb8e494SKris Buschelman } 3124eb8e494SKris Buschelman 31366976f2fSJacob Faibussowitsch static PetscErrorCode MatLUFactorSymbolic_LUSOL(Mat F, Mat A, IS r, IS c, const MatFactorInfo *info) 314d71ae5a4SJacob Faibussowitsch { 3154eb8e494SKris Buschelman /************************************************************************/ 3164eb8e494SKris Buschelman /* Input */ 3174eb8e494SKris Buschelman /* A - matrix to factor */ 3184eb8e494SKris Buschelman /* r - row permutation (ignored) */ 3194eb8e494SKris Buschelman /* c - column permutation (ignored) */ 3204eb8e494SKris Buschelman /* */ 3214eb8e494SKris Buschelman /* Output */ 3224eb8e494SKris Buschelman /* F - matrix storing the factorization; */ 3234eb8e494SKris Buschelman /************************************************************************/ 324f0c56d0fSKris Buschelman Mat_LUSOL *lusol; 325dfbe8321SBarry Smith int i, m, n, nz, nnz; 3264eb8e494SKris Buschelman 3274eb8e494SKris Buschelman PetscFunctionBegin; 3284eb8e494SKris Buschelman /************************************************************************/ 3294eb8e494SKris Buschelman /* Check the arguments. */ 3304eb8e494SKris Buschelman /************************************************************************/ 3314eb8e494SKris Buschelman 3329566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 3334eb8e494SKris Buschelman nz = ((Mat_SeqAIJ *)A->data)->nz; 3344eb8e494SKris Buschelman 3354eb8e494SKris Buschelman /************************************************************************/ 3364eb8e494SKris Buschelman /* Create the factorization. */ 3374eb8e494SKris Buschelman /************************************************************************/ 3384eb8e494SKris Buschelman 33935bd34faSBarry Smith F->ops->lufactornumeric = MatLUFactorNumeric_LUSOL; 340*f4f49eeaSPierre Jolivet lusol = (Mat_LUSOL *)F->spptr; 3414eb8e494SKris Buschelman 3424eb8e494SKris Buschelman /************************************************************************/ 3434eb8e494SKris Buschelman /* Initialize parameters */ 3444eb8e494SKris Buschelman /************************************************************************/ 3454eb8e494SKris Buschelman 3462205254eSKarl Rupp for (i = 0; i < 30; i++) { 3474eb8e494SKris Buschelman lusol->luparm[i] = 0; 3484eb8e494SKris Buschelman lusol->parmlu[i] = 0; 3494eb8e494SKris Buschelman } 3504eb8e494SKris Buschelman 3514eb8e494SKris Buschelman lusol->luparm[1] = -1; 3524eb8e494SKris Buschelman lusol->luparm[2] = 5; 3534eb8e494SKris Buschelman lusol->luparm[7] = 1; 3544eb8e494SKris Buschelman 3554eb8e494SKris Buschelman lusol->parmlu[0] = 1 / Factorization_Tolerance; 3564eb8e494SKris Buschelman lusol->parmlu[1] = 1 / Factorization_Tolerance; 3574eb8e494SKris Buschelman lusol->parmlu[2] = Factorization_Small_Tolerance; 3584eb8e494SKris Buschelman lusol->parmlu[3] = Factorization_Pivot_Tolerance; 3594eb8e494SKris Buschelman lusol->parmlu[4] = Factorization_Pivot_Tolerance; 3604eb8e494SKris Buschelman lusol->parmlu[5] = 3.0; 3614eb8e494SKris Buschelman lusol->parmlu[6] = 0.3; 3624eb8e494SKris Buschelman lusol->parmlu[7] = 0.6; 3634eb8e494SKris Buschelman 3644eb8e494SKris Buschelman /************************************************************************/ 3654eb8e494SKris Buschelman /* Allocate the workspace needed by LUSOL. */ 3664eb8e494SKris Buschelman /************************************************************************/ 3674eb8e494SKris Buschelman 3684eb8e494SKris Buschelman lusol->elbowroom = PetscMax(lusol->elbowroom, info->fill); 3694eb8e494SKris Buschelman nnz = PetscMax((int)(lusol->elbowroom * nz), 5 * n); 3704eb8e494SKris Buschelman 3714eb8e494SKris Buschelman lusol->n = n; 3724eb8e494SKris Buschelman lusol->nz = nz; 3734eb8e494SKris Buschelman lusol->nnz = nnz; 3744eb8e494SKris Buschelman lusol->luroom = 1.75; 3754eb8e494SKris Buschelman 376d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->ip)); 377d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->iq)); 378d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->lenc)); 379d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->lenr)); 380d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->locc)); 381d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->locr)); 382d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->iploc)); 383d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->iqloc)); 384d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->ipinv)); 385d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->iqinv)); 386d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(double) * n, &lusol->mnsw)); 387d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(double) * n, &lusol->mnsv)); 3889566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(nnz, &lusol->data, nnz, &lusol->indc, nnz, &lusol->indr)); 3892205254eSKarl Rupp 3904eb8e494SKris Buschelman lusol->CleanUpLUSOL = PETSC_TRUE; 39135bd34faSBarry Smith F->ops->lufactornumeric = MatLUFactorNumeric_LUSOL; 3923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3934eb8e494SKris Buschelman } 3944eb8e494SKris Buschelman 39566976f2fSJacob Faibussowitsch static PetscErrorCode MatFactorGetSolverType_seqaij_lusol(Mat A, MatSolverType *type) 396d71ae5a4SJacob Faibussowitsch { 39735bd34faSBarry Smith PetscFunctionBegin; 3982692d6eeSBarry Smith *type = MATSOLVERLUSOL; 3993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40035bd34faSBarry Smith } 40135bd34faSBarry Smith 402d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_lusol(Mat A, MatFactorType ftype, Mat *F) 403d71ae5a4SJacob Faibussowitsch { 404b24902e0SBarry Smith Mat B; 405f0c56d0fSKris Buschelman Mat_LUSOL *lusol; 40635bd34faSBarry Smith int m, n; 4074eb8e494SKris Buschelman 4084eb8e494SKris Buschelman PetscFunctionBegin; 4099566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 4109566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 4119566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, PETSC_DECIDE, PETSC_DECIDE, m, n)); 4129566063dSJacob Faibussowitsch PetscCall(MatSetType(B, ((PetscObject)A)->type_name)); 4139566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(B, 0, NULL)); 4144eb8e494SKris Buschelman 4154dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&lusol)); 416b24902e0SBarry Smith B->spptr = lusol; 4172f71e704SKris Buschelman 41866e17bc3SBarry Smith B->trivialsymbolic = PETSC_TRUE; 419f0c56d0fSKris Buschelman B->ops->lufactorsymbolic = MatLUFactorSymbolic_LUSOL; 420f0c56d0fSKris Buschelman B->ops->destroy = MatDestroy_LUSOL; 4212205254eSKarl Rupp 4229566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatFactorGetSolverType_C", MatFactorGetSolverType_seqaij_lusol)); 4232205254eSKarl Rupp 424d5f3da31SBarry Smith B->factortype = MAT_FACTOR_LU; 4259566063dSJacob Faibussowitsch PetscCall(PetscFree(B->solvertype)); 4269566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERLUSOL, &B->solvertype)); 4273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 428f0c56d0fSKris Buschelman } 429f0c56d0fSKris Buschelman 430d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatSolverTypeRegister_Lusol(void) 431d71ae5a4SJacob Faibussowitsch { 43242c9c57cSBarry Smith PetscFunctionBegin; 4339566063dSJacob Faibussowitsch PetscCall(MatSolverTypeRegister(MATSOLVERLUSOL, MATSEQAIJ, MAT_FACTOR_LU, MatGetFactor_seqaij_lusol)); 4343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 43542c9c57cSBarry Smith } 43642c9c57cSBarry Smith 4372f71e704SKris Buschelman /*MC 43811a5261eSBarry Smith MATSOLVERLUSOL - "lusol" - Provides direct solvers, LU, for sequential matrices 4392f71e704SKris Buschelman via the external package LUSOL. 4402f71e704SKris Buschelman 44111a5261eSBarry Smith Works with `MATSEQAIJ` matrices 4422f71e704SKris Buschelman 4432f71e704SKris Buschelman Level: beginner 4442f71e704SKris Buschelman 4451cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `PCLU`, `PCFactorSetMatSolverType()`, `MatSolverType` 4462f71e704SKris Buschelman M*/ 447