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 75*4ee01570SBarry Smith /* 76*4ee01570SBarry Smith LUSOL input/Output Parameters (Description uses C-style indexes 77*4ee01570SBarry Smith 78*4ee01570SBarry Smith Input parameters Typical value 79*4ee01570SBarry Smith luparm(0) = nout File number for printed messages. 6 80*4ee01570SBarry Smith luparm(1) = lprint Print level. 0 81*4ee01570SBarry Smith < 0 suppresses output. 82*4ee01570SBarry Smith = 0 gives error messages. 83*4ee01570SBarry Smith = 1 gives debug output from some of the 84*4ee01570SBarry Smith other routines in LUSOL. 85*4ee01570SBarry Smith >= 2 gives the pivot row and column and the 86*4ee01570SBarry Smith no. of rows and columns involved at 87*4ee01570SBarry Smith each elimination step in lu1fac. 88*4ee01570SBarry Smith luparm(2) = maxcol lu1fac: maximum number of columns 5 89*4ee01570SBarry Smith searched allowed in a Markowitz-type 90*4ee01570SBarry Smith search for the next pivot element. 91*4ee01570SBarry Smith For some of the factorization, the 92*4ee01570SBarry Smith number of rows searched is 93*4ee01570SBarry Smith maxrow = maxcol - 1. 94*4ee01570SBarry Smith 95*4ee01570SBarry Smith Output parameters: 96*4ee01570SBarry Smith 97*4ee01570SBarry Smith luparm(9) = inform Return code from last call to any LU routine. 98*4ee01570SBarry Smith luparm(10) = nsing No. of singularities marked in the 99*4ee01570SBarry Smith output array w(*). 100*4ee01570SBarry Smith luparm(11) = jsing Column index of last singularity. 101*4ee01570SBarry Smith luparm(12) = minlen Minimum recommended value for lena. 102*4ee01570SBarry Smith luparm(13) = maxlen ? 103*4ee01570SBarry Smith luparm(14) = nupdat No. of updates performed by the lu8 routines. 104*4ee01570SBarry Smith luparm(15) = nrank No. of nonempty rows of U. 105*4ee01570SBarry Smith luparm(16) = ndens1 No. of columns remaining when the density of 106*4ee01570SBarry Smith the matrix being factorized reached dens1. 107*4ee01570SBarry Smith luparm(17) = ndens2 No. of columns remaining when the density of 108*4ee01570SBarry Smith the matrix being factorized reached dens2. 109*4ee01570SBarry Smith luparm(18) = jumin The column index associated with dumin. 110*4ee01570SBarry Smith luparm(19) = numl0 No. of columns in initial L. 111*4ee01570SBarry Smith luparm(20) = lenl0 Size of initial L (no. of nonzeros). 112*4ee01570SBarry Smith luparm(21) = lenu0 Size of initial U. 113*4ee01570SBarry Smith luparm(22) = lenl Size of current L. 114*4ee01570SBarry Smith luparm(23) = lenu Size of current U. 115*4ee01570SBarry Smith luparm(24) = lrow Length of row file. 116*4ee01570SBarry Smith luparm(25) = ncp No. of compressions of LU data structures. 117*4ee01570SBarry Smith luparm(26) = mersum lu1fac: sum of Markowitz merit counts. 118*4ee01570SBarry Smith luparm(27) = nutri lu1fac: triangular rows in U. 119*4ee01570SBarry Smith luparm(28) = nltri lu1fac: triangular rows in L. 120*4ee01570SBarry Smith luparm(29) = 121*4ee01570SBarry Smith 122*4ee01570SBarry Smith Input parameters Typical value 123*4ee01570SBarry Smith parmlu(0) = elmax1 Max multiplier allowed in L 10.0 124*4ee01570SBarry Smith during factor. 125*4ee01570SBarry Smith parmlu(1) = elmax2 Max multiplier allowed in L 10.0 126*4ee01570SBarry Smith during updates. 127*4ee01570SBarry Smith parmlu(2) = small Absolute tolerance for eps**0.8 128*4ee01570SBarry Smith treating reals as zero. IBM double: 3.0d-13 129*4ee01570SBarry Smith parmlu(3) = utol1 Absolute tol for flagging eps**0.66667 130*4ee01570SBarry Smith small diagonals of U. IBM double: 3.7d-11 131*4ee01570SBarry Smith parmlu(4) = utol2 Relative tol for flagging eps**0.66667 132*4ee01570SBarry Smith small diagonals of U. IBM double: 3.7d-11 133*4ee01570SBarry Smith parmlu(5) = uspace Factor limiting waste space in U. 3.0 134*4ee01570SBarry Smith In lu1fac, the row or column lists 135*4ee01570SBarry Smith are compressed if their length 136*4ee01570SBarry Smith exceeds uspace times the length of 137*4ee01570SBarry Smith either file after the last compression. 138*4ee01570SBarry Smith parmlu(6) = dens1 The density at which the Markowitz 0.3 139*4ee01570SBarry Smith strategy should search maxcol columns 140*4ee01570SBarry Smith and no rows. 141*4ee01570SBarry Smith parmlu(7) = dens2 the density at which the Markowitz 0.6 142*4ee01570SBarry Smith strategy should search only 1 column 143*4ee01570SBarry Smith or (preferably) use a dense LU for 144*4ee01570SBarry Smith all the remaining rows and columns. 145*4ee01570SBarry Smith 146*4ee01570SBarry Smith Output parameters: 147*4ee01570SBarry Smith parmlu(9) = amax Maximum element in A. 148*4ee01570SBarry Smith parmlu(10) = elmax Maximum multiplier in current L. 149*4ee01570SBarry Smith parmlu(11) = umax Maximum element in current U. 150*4ee01570SBarry Smith parmlu(12) = dumax Maximum diagonal in U. 151*4ee01570SBarry Smith parmlu(13) = dumin Minimum diagonal in U. 152*4ee01570SBarry Smith parmlu(14) = 153*4ee01570SBarry Smith parmlu(15) = 154*4ee01570SBarry Smith parmlu(16) = 155*4ee01570SBarry Smith parmlu(17) = 156*4ee01570SBarry Smith parmlu(18) = 157*4ee01570SBarry Smith parmlu(19) = resid lu6sol: residual after solve with U or U'. 158*4ee01570SBarry Smith ... 159*4ee01570SBarry Smith parmlu(29) = 1604eb8e494SKris Buschelman */ 1614eb8e494SKris Buschelman 1624eb8e494SKris Buschelman #define Factorization_Tolerance 1e-1 1634eb8e494SKris Buschelman #define Factorization_Pivot_Tolerance pow(2.2204460492503131E-16, 2.0 / 3.0) 1644eb8e494SKris Buschelman #define Factorization_Small_Tolerance 1e-15 /* pow(DBL_EPSILON, 0.8) */ 1654eb8e494SKris Buschelman 16666976f2fSJacob Faibussowitsch static PetscErrorCode MatDestroy_LUSOL(Mat A) 167d71ae5a4SJacob Faibussowitsch { 168f0c56d0fSKris Buschelman Mat_LUSOL *lusol = (Mat_LUSOL *)A->spptr; 1694eb8e494SKris Buschelman 1704eb8e494SKris Buschelman PetscFunctionBegin; 171bf0cc555SLisandro Dalcin if (lusol && lusol->CleanUpLUSOL) { 1729566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->ip)); 1739566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->iq)); 1749566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->lenc)); 1759566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->lenr)); 1769566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->locc)); 1779566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->locr)); 1789566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->iploc)); 1799566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->iqloc)); 1809566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->ipinv)); 1819566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->iqinv)); 1829566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->mnsw)); 1839566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->mnsv)); 1849566063dSJacob Faibussowitsch PetscCall(PetscFree3(lusol->data, lusol->indc, lusol->indr)); 1854eb8e494SKris Buschelman } 1869566063dSJacob Faibussowitsch PetscCall(PetscFree(A->spptr)); 1879566063dSJacob Faibussowitsch PetscCall(MatDestroy_SeqAIJ(A)); 1883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1894eb8e494SKris Buschelman } 1904eb8e494SKris Buschelman 19166976f2fSJacob Faibussowitsch static PetscErrorCode MatSolve_LUSOL(Mat A, Vec b, Vec x) 192d71ae5a4SJacob Faibussowitsch { 193f0c56d0fSKris Buschelman Mat_LUSOL *lusol = (Mat_LUSOL *)A->spptr; 194d9ca1df4SBarry Smith double *xx; 195d9ca1df4SBarry Smith const double *bb; 1964eb8e494SKris Buschelman int mode = 5; 1976849ba73SBarry Smith int i, m, n, nnz, status; 1984eb8e494SKris Buschelman 1994eb8e494SKris Buschelman PetscFunctionBegin; 2009566063dSJacob Faibussowitsch PetscCall(VecGetArray(x, &xx)); 2019566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(b, &bb)); 2024eb8e494SKris Buschelman 2034eb8e494SKris Buschelman m = n = lusol->n; 2044eb8e494SKris Buschelman nnz = lusol->nnz; 2054eb8e494SKris Buschelman 2062205254eSKarl Rupp for (i = 0; i < m; i++) lusol->mnsv[i] = bb[i]; 2074eb8e494SKris Buschelman 2089371c9d4SSatish 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); 2094eb8e494SKris Buschelman 21028b400f6SJacob Faibussowitsch PetscCheck(!status, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "solve failed, error code %d", status); 2114eb8e494SKris Buschelman 2129566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(x, &xx)); 2139566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(b, &bb)); 2143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2154eb8e494SKris Buschelman } 2164eb8e494SKris Buschelman 21766976f2fSJacob Faibussowitsch static PetscErrorCode MatLUFactorNumeric_LUSOL(Mat F, Mat A, const MatFactorInfo *info) 218d71ae5a4SJacob Faibussowitsch { 2194eb8e494SKris Buschelman Mat_SeqAIJ *a; 220719d5645SBarry Smith Mat_LUSOL *lusol = (Mat_LUSOL *)F->spptr; 2214eb8e494SKris Buschelman int m, n, nz, nnz, status; 2226849ba73SBarry Smith int i, rs, re; 2234eb8e494SKris Buschelman int factorizations; 2244eb8e494SKris Buschelman 2254eb8e494SKris Buschelman PetscFunctionBegin; 2269566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 2274eb8e494SKris Buschelman a = (Mat_SeqAIJ *)A->data; 2284eb8e494SKris Buschelman 22908401ef6SPierre Jolivet PetscCheck(m == lusol->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "factorization struct inconsistent"); 2304eb8e494SKris Buschelman 2314eb8e494SKris Buschelman factorizations = 0; 2322205254eSKarl Rupp do { 2334eb8e494SKris Buschelman /*******************************************************************/ 2344eb8e494SKris Buschelman /* Check the workspace allocation. */ 2354eb8e494SKris Buschelman /*******************************************************************/ 2364eb8e494SKris Buschelman 2374eb8e494SKris Buschelman nz = a->nz; 2384eb8e494SKris Buschelman nnz = PetscMax(lusol->nnz, (int)(lusol->elbowroom * nz)); 2394eb8e494SKris Buschelman nnz = PetscMax(nnz, 5 * n); 2404eb8e494SKris Buschelman 2414eb8e494SKris Buschelman if (nnz < lusol->luparm[12]) { 2424eb8e494SKris Buschelman nnz = (int)(lusol->luroom * lusol->luparm[12]); 2434eb8e494SKris Buschelman } else if ((factorizations > 0) && (lusol->luroom < 6)) { 2444eb8e494SKris Buschelman lusol->luroom += 0.1; 2454eb8e494SKris Buschelman } 2464eb8e494SKris Buschelman 2474eb8e494SKris Buschelman nnz = PetscMax(nnz, (int)(lusol->luroom * (lusol->luparm[22] + lusol->luparm[23]))); 2484eb8e494SKris Buschelman 2494eb8e494SKris Buschelman if (nnz > lusol->nnz) { 2509566063dSJacob Faibussowitsch PetscCall(PetscFree3(lusol->data, lusol->indc, lusol->indr)); 2519566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(nnz, &lusol->data, nnz, &lusol->indc, nnz, &lusol->indr)); 2524eb8e494SKris Buschelman lusol->nnz = nnz; 2534eb8e494SKris Buschelman } 2544eb8e494SKris Buschelman 2554eb8e494SKris Buschelman /* Fill in the data for the problem. (1-based Fortran style) */ 2564eb8e494SKris Buschelman nz = 0; 2572205254eSKarl Rupp for (i = 0; i < n; i++) { 2584eb8e494SKris Buschelman rs = a->i[i]; 2594eb8e494SKris Buschelman re = a->i[i + 1]; 2604eb8e494SKris Buschelman 2612205254eSKarl Rupp while (rs < re) { 2622205254eSKarl Rupp if (a->a[rs] != 0.0) { 2634eb8e494SKris Buschelman lusol->indc[nz] = i + 1; 2644eb8e494SKris Buschelman lusol->indr[nz] = a->j[rs] + 1; 2654eb8e494SKris Buschelman lusol->data[nz] = a->a[rs]; 2664eb8e494SKris Buschelman nz++; 2674eb8e494SKris Buschelman } 2684eb8e494SKris Buschelman rs++; 2694eb8e494SKris Buschelman } 2704eb8e494SKris Buschelman } 2714eb8e494SKris Buschelman 2724eb8e494SKris Buschelman /* Do the factorization. */ 2739371c9d4SSatish 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); 2744eb8e494SKris Buschelman 2752205254eSKarl Rupp switch (status) { 276d71ae5a4SJacob Faibussowitsch case 0: /* factored */ 277d71ae5a4SJacob Faibussowitsch break; 2784eb8e494SKris Buschelman 279d71ae5a4SJacob Faibussowitsch case 7: /* insufficient memory */ 280d71ae5a4SJacob Faibussowitsch break; 2814eb8e494SKris Buschelman 2824eb8e494SKris Buschelman case 1: 283d71ae5a4SJacob Faibussowitsch case -1: /* singular */ 284d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Singular matrix"); 2854eb8e494SKris Buschelman 2864eb8e494SKris Buschelman case 3: 287d71ae5a4SJacob Faibussowitsch case 4: /* error conditions */ 288d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "matrix error"); 2894eb8e494SKris Buschelman 290d71ae5a4SJacob Faibussowitsch default: /* unknown condition */ 291d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "matrix unknown return code"); 2924eb8e494SKris Buschelman } 2934eb8e494SKris Buschelman 2944eb8e494SKris Buschelman factorizations++; 2954eb8e494SKris Buschelman } while (status == 7); 296719d5645SBarry Smith F->ops->solve = MatSolve_LUSOL; 297719d5645SBarry Smith F->assembled = PETSC_TRUE; 298719d5645SBarry Smith F->preallocated = PETSC_TRUE; 2993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3004eb8e494SKris Buschelman } 3014eb8e494SKris Buschelman 30266976f2fSJacob Faibussowitsch static PetscErrorCode MatLUFactorSymbolic_LUSOL(Mat F, Mat A, IS r, IS c, const MatFactorInfo *info) 303d71ae5a4SJacob Faibussowitsch { 304*4ee01570SBarry Smith /* 305*4ee01570SBarry Smith Input 306*4ee01570SBarry Smith A - matrix to factor 307*4ee01570SBarry Smith r - row permutation (ignored) 308*4ee01570SBarry Smith c - column permutation (ignored) 309*4ee01570SBarry Smith 310*4ee01570SBarry Smith Output 311*4ee01570SBarry Smith F - matrix storing the factorization; 312*4ee01570SBarry Smith */ 313f0c56d0fSKris Buschelman Mat_LUSOL *lusol; 314dfbe8321SBarry Smith int i, m, n, nz, nnz; 3154eb8e494SKris Buschelman 3164eb8e494SKris Buschelman PetscFunctionBegin; 3174eb8e494SKris Buschelman /* Check the arguments. */ 3189566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 3194eb8e494SKris Buschelman nz = ((Mat_SeqAIJ *)A->data)->nz; 3204eb8e494SKris Buschelman 3214eb8e494SKris Buschelman /* Create the factorization. */ 32235bd34faSBarry Smith F->ops->lufactornumeric = MatLUFactorNumeric_LUSOL; 323f4f49eeaSPierre Jolivet lusol = (Mat_LUSOL *)F->spptr; 3244eb8e494SKris Buschelman 3254eb8e494SKris Buschelman /* Initialize parameters */ 3262205254eSKarl Rupp for (i = 0; i < 30; i++) { 3274eb8e494SKris Buschelman lusol->luparm[i] = 0; 3284eb8e494SKris Buschelman lusol->parmlu[i] = 0; 3294eb8e494SKris Buschelman } 3304eb8e494SKris Buschelman 3314eb8e494SKris Buschelman lusol->luparm[1] = -1; 3324eb8e494SKris Buschelman lusol->luparm[2] = 5; 3334eb8e494SKris Buschelman lusol->luparm[7] = 1; 3344eb8e494SKris Buschelman 3354eb8e494SKris Buschelman lusol->parmlu[0] = 1 / Factorization_Tolerance; 3364eb8e494SKris Buschelman lusol->parmlu[1] = 1 / Factorization_Tolerance; 3374eb8e494SKris Buschelman lusol->parmlu[2] = Factorization_Small_Tolerance; 3384eb8e494SKris Buschelman lusol->parmlu[3] = Factorization_Pivot_Tolerance; 3394eb8e494SKris Buschelman lusol->parmlu[4] = Factorization_Pivot_Tolerance; 3404eb8e494SKris Buschelman lusol->parmlu[5] = 3.0; 3414eb8e494SKris Buschelman lusol->parmlu[6] = 0.3; 3424eb8e494SKris Buschelman lusol->parmlu[7] = 0.6; 3434eb8e494SKris Buschelman 3444eb8e494SKris Buschelman /* Allocate the workspace needed by LUSOL. */ 3454eb8e494SKris Buschelman lusol->elbowroom = PetscMax(lusol->elbowroom, info->fill); 3464eb8e494SKris Buschelman nnz = PetscMax((int)(lusol->elbowroom * nz), 5 * n); 3474eb8e494SKris Buschelman 3484eb8e494SKris Buschelman lusol->n = n; 3494eb8e494SKris Buschelman lusol->nz = nz; 3504eb8e494SKris Buschelman lusol->nnz = nnz; 3514eb8e494SKris Buschelman lusol->luroom = 1.75; 3524eb8e494SKris Buschelman 353d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->ip)); 354d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->iq)); 355d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->lenc)); 356d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->lenr)); 357d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->locc)); 358d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->locr)); 359d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->iploc)); 360d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->iqloc)); 361d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->ipinv)); 362d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->iqinv)); 363d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(double) * n, &lusol->mnsw)); 364d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(double) * n, &lusol->mnsv)); 3659566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(nnz, &lusol->data, nnz, &lusol->indc, nnz, &lusol->indr)); 3662205254eSKarl Rupp 3674eb8e494SKris Buschelman lusol->CleanUpLUSOL = PETSC_TRUE; 36835bd34faSBarry Smith F->ops->lufactornumeric = MatLUFactorNumeric_LUSOL; 3693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3704eb8e494SKris Buschelman } 3714eb8e494SKris Buschelman 37266976f2fSJacob Faibussowitsch static PetscErrorCode MatFactorGetSolverType_seqaij_lusol(Mat A, MatSolverType *type) 373d71ae5a4SJacob Faibussowitsch { 37435bd34faSBarry Smith PetscFunctionBegin; 3752692d6eeSBarry Smith *type = MATSOLVERLUSOL; 3763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37735bd34faSBarry Smith } 37835bd34faSBarry Smith 379d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_lusol(Mat A, MatFactorType ftype, Mat *F) 380d71ae5a4SJacob Faibussowitsch { 381b24902e0SBarry Smith Mat B; 382f0c56d0fSKris Buschelman Mat_LUSOL *lusol; 38335bd34faSBarry Smith int m, n; 3844eb8e494SKris Buschelman 3854eb8e494SKris Buschelman PetscFunctionBegin; 3869566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 3879566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 3889566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, PETSC_DECIDE, PETSC_DECIDE, m, n)); 3899566063dSJacob Faibussowitsch PetscCall(MatSetType(B, ((PetscObject)A)->type_name)); 3909566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(B, 0, NULL)); 3914eb8e494SKris Buschelman 3924dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&lusol)); 393b24902e0SBarry Smith B->spptr = lusol; 3942f71e704SKris Buschelman 39566e17bc3SBarry Smith B->trivialsymbolic = PETSC_TRUE; 396f0c56d0fSKris Buschelman B->ops->lufactorsymbolic = MatLUFactorSymbolic_LUSOL; 397f0c56d0fSKris Buschelman B->ops->destroy = MatDestroy_LUSOL; 3982205254eSKarl Rupp 3999566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatFactorGetSolverType_C", MatFactorGetSolverType_seqaij_lusol)); 4002205254eSKarl Rupp 401d5f3da31SBarry Smith B->factortype = MAT_FACTOR_LU; 4029566063dSJacob Faibussowitsch PetscCall(PetscFree(B->solvertype)); 4039566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERLUSOL, &B->solvertype)); 4043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 405f0c56d0fSKris Buschelman } 406f0c56d0fSKris Buschelman 407d1f0640dSPierre Jolivet PETSC_INTERN PetscErrorCode MatSolverTypeRegister_Lusol(void) 408d71ae5a4SJacob Faibussowitsch { 40942c9c57cSBarry Smith PetscFunctionBegin; 4109566063dSJacob Faibussowitsch PetscCall(MatSolverTypeRegister(MATSOLVERLUSOL, MATSEQAIJ, MAT_FACTOR_LU, MatGetFactor_seqaij_lusol)); 4113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 41242c9c57cSBarry Smith } 41342c9c57cSBarry Smith 4142f71e704SKris Buschelman /*MC 41511a5261eSBarry Smith MATSOLVERLUSOL - "lusol" - Provides direct solvers, LU, for sequential matrices 4162f71e704SKris Buschelman via the external package LUSOL. 4172f71e704SKris Buschelman 41811a5261eSBarry Smith Works with `MATSEQAIJ` matrices 4192f71e704SKris Buschelman 4202f71e704SKris Buschelman Level: beginner 4212f71e704SKris Buschelman 4221cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `PCLU`, `PCFactorSetMatSolverType()`, `MatSolverType` 4232f71e704SKris Buschelman M*/ 424