1be1d678aSKris Buschelman 24eb8e494SKris Buschelman /* 34eb8e494SKris Buschelman Provides an interface to the LUSOL package of .... 44eb8e494SKris Buschelman 54eb8e494SKris Buschelman */ 6c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h> 74eb8e494SKris Buschelman 84eb8e494SKris Buschelman #if defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 94eb8e494SKris Buschelman #define LU1FAC lu1fac_ 104eb8e494SKris Buschelman #define LU6SOL lu6sol_ 114eb8e494SKris Buschelman #define M1PAGE m1page_ 124eb8e494SKris Buschelman #define M5SETX m5setx_ 134eb8e494SKris Buschelman #define M6RDEL m6rdel_ 144eb8e494SKris Buschelman #elif !defined(PETSC_HAVE_FORTRAN_CAPS) 154eb8e494SKris Buschelman #define LU1FAC lu1fac 164eb8e494SKris Buschelman #define LU6SOL lu6sol 174eb8e494SKris Buschelman #define M1PAGE m1page 184eb8e494SKris Buschelman #define M5SETX m5setx 194eb8e494SKris Buschelman #define M6RDEL m6rdel 204eb8e494SKris Buschelman #endif 214eb8e494SKris Buschelman 224eb8e494SKris Buschelman /* 234eb8e494SKris Buschelman Dummy symbols that the MINOS files mi25bfac.f and mi15blas.f may require 244eb8e494SKris Buschelman */ 25d71ae5a4SJacob Faibussowitsch PETSC_EXTERN void M1PAGE() 26d71ae5a4SJacob Faibussowitsch { 274eb8e494SKris Buschelman ; 284eb8e494SKris Buschelman } 29d71ae5a4SJacob Faibussowitsch PETSC_EXTERN void M5SETX() 30d71ae5a4SJacob Faibussowitsch { 314eb8e494SKris Buschelman ; 324eb8e494SKris Buschelman } 334eb8e494SKris Buschelman 34d71ae5a4SJacob Faibussowitsch PETSC_EXTERN void M6RDEL() 35d71ae5a4SJacob Faibussowitsch { 364eb8e494SKris Buschelman ; 374eb8e494SKris Buschelman } 384eb8e494SKris Buschelman 399371c9d4SSatish 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); 404eb8e494SKris Buschelman 419371c9d4SSatish 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); 424eb8e494SKris Buschelman 4309573ac7SBarry Smith extern PetscErrorCode MatDuplicate_LUSOL(Mat, MatDuplicateOption, Mat *); 44f0c56d0fSKris Buschelman 45f0c56d0fSKris Buschelman typedef struct { 464eb8e494SKris Buschelman double *data; 474eb8e494SKris Buschelman int *indc; 484eb8e494SKris Buschelman int *indr; 494eb8e494SKris Buschelman 504eb8e494SKris Buschelman int *ip; 514eb8e494SKris Buschelman int *iq; 524eb8e494SKris Buschelman int *lenc; 534eb8e494SKris Buschelman int *lenr; 544eb8e494SKris Buschelman int *locc; 554eb8e494SKris Buschelman int *locr; 564eb8e494SKris Buschelman int *iploc; 574eb8e494SKris Buschelman int *iqloc; 584eb8e494SKris Buschelman int *ipinv; 594eb8e494SKris Buschelman int *iqinv; 604eb8e494SKris Buschelman double *mnsw; 614eb8e494SKris Buschelman double *mnsv; 624eb8e494SKris Buschelman 634eb8e494SKris Buschelman double elbowroom; 644eb8e494SKris Buschelman double luroom; /* Extra space allocated when factor fails */ 654eb8e494SKris Buschelman double parmlu[30]; /* Input/output to LUSOL */ 664eb8e494SKris Buschelman 674eb8e494SKris Buschelman int n; /* Number of rows/columns in matrix */ 684eb8e494SKris Buschelman int nz; /* Number of nonzeros */ 694eb8e494SKris Buschelman int nnz; /* Number of nonzeros allocated for factors */ 704eb8e494SKris Buschelman int luparm[30]; /* Input/output to LUSOL */ 714eb8e494SKris Buschelman 72ace3abfcSBarry Smith PetscBool CleanUpLUSOL; 734eb8e494SKris Buschelman 74f0c56d0fSKris Buschelman } Mat_LUSOL; 754eb8e494SKris Buschelman 764eb8e494SKris Buschelman /* LUSOL input/Output Parameters (Description uses C-style indexes 774eb8e494SKris Buschelman * 784eb8e494SKris Buschelman * Input parameters Typical value 794eb8e494SKris Buschelman * 804eb8e494SKris Buschelman * luparm(0) = nout File number for printed messages. 6 814eb8e494SKris Buschelman * luparm(1) = lprint Print level. 0 824eb8e494SKris Buschelman * < 0 suppresses output. 834eb8e494SKris Buschelman * = 0 gives error messages. 844eb8e494SKris Buschelman * = 1 gives debug output from some of the 854eb8e494SKris Buschelman * other routines in LUSOL. 864eb8e494SKris Buschelman * >= 2 gives the pivot row and column and the 874eb8e494SKris Buschelman * no. of rows and columns involved at 884eb8e494SKris Buschelman * each elimination step in lu1fac. 894eb8e494SKris Buschelman * luparm(2) = maxcol lu1fac: maximum number of columns 5 904eb8e494SKris Buschelman * searched allowed in a Markowitz-type 914eb8e494SKris Buschelman * search for the next pivot element. 924eb8e494SKris Buschelman * For some of the factorization, the 934eb8e494SKris Buschelman * number of rows searched is 944eb8e494SKris Buschelman * maxrow = maxcol - 1. 954eb8e494SKris Buschelman * 964eb8e494SKris Buschelman * 977a7aea1fSJed Brown * Output parameters: 984eb8e494SKris Buschelman * 994eb8e494SKris Buschelman * luparm(9) = inform Return code from last call to any LU routine. 1004eb8e494SKris Buschelman * luparm(10) = nsing No. of singularities marked in the 1014eb8e494SKris Buschelman * output array w(*). 1024eb8e494SKris Buschelman * luparm(11) = jsing Column index of last singularity. 1034eb8e494SKris Buschelman * luparm(12) = minlen Minimum recommended value for lena. 1044eb8e494SKris Buschelman * luparm(13) = maxlen ? 1054eb8e494SKris Buschelman * luparm(14) = nupdat No. of updates performed by the lu8 routines. 1064eb8e494SKris Buschelman * luparm(15) = nrank No. of nonempty rows of U. 1074eb8e494SKris Buschelman * luparm(16) = ndens1 No. of columns remaining when the density of 1084eb8e494SKris Buschelman * the matrix being factorized reached dens1. 1094eb8e494SKris Buschelman * luparm(17) = ndens2 No. of columns remaining when the density of 1104eb8e494SKris Buschelman * the matrix being factorized reached dens2. 1114eb8e494SKris Buschelman * luparm(18) = jumin The column index associated with dumin. 1124eb8e494SKris Buschelman * luparm(19) = numl0 No. of columns in initial L. 1134eb8e494SKris Buschelman * luparm(20) = lenl0 Size of initial L (no. of nonzeros). 1144eb8e494SKris Buschelman * luparm(21) = lenu0 Size of initial U. 1154eb8e494SKris Buschelman * luparm(22) = lenl Size of current L. 1164eb8e494SKris Buschelman * luparm(23) = lenu Size of current U. 1174eb8e494SKris Buschelman * luparm(24) = lrow Length of row file. 1184eb8e494SKris Buschelman * luparm(25) = ncp No. of compressions of LU data structures. 1194eb8e494SKris Buschelman * luparm(26) = mersum lu1fac: sum of Markowitz merit counts. 1204eb8e494SKris Buschelman * luparm(27) = nutri lu1fac: triangular rows in U. 1214eb8e494SKris Buschelman * luparm(28) = nltri lu1fac: triangular rows in L. 1224eb8e494SKris Buschelman * luparm(29) = 1234eb8e494SKris Buschelman * 1244eb8e494SKris Buschelman * 1254eb8e494SKris Buschelman * Input parameters Typical value 1264eb8e494SKris Buschelman * 1274eb8e494SKris Buschelman * parmlu(0) = elmax1 Max multiplier allowed in L 10.0 1284eb8e494SKris Buschelman * during factor. 1294eb8e494SKris Buschelman * parmlu(1) = elmax2 Max multiplier allowed in L 10.0 1304eb8e494SKris Buschelman * during updates. 1314eb8e494SKris Buschelman * parmlu(2) = small Absolute tolerance for eps**0.8 1324eb8e494SKris Buschelman * treating reals as zero. IBM double: 3.0d-13 1334eb8e494SKris Buschelman * parmlu(3) = utol1 Absolute tol for flagging eps**0.66667 1344eb8e494SKris Buschelman * small diagonals of U. IBM double: 3.7d-11 1354eb8e494SKris Buschelman * parmlu(4) = utol2 Relative tol for flagging eps**0.66667 1364eb8e494SKris Buschelman * small diagonals of U. IBM double: 3.7d-11 1374eb8e494SKris Buschelman * parmlu(5) = uspace Factor limiting waste space in U. 3.0 1384eb8e494SKris Buschelman * In lu1fac, the row or column lists 1394eb8e494SKris Buschelman * are compressed if their length 1404eb8e494SKris Buschelman * exceeds uspace times the length of 1414eb8e494SKris Buschelman * either file after the last compression. 1424eb8e494SKris Buschelman * parmlu(6) = dens1 The density at which the Markowitz 0.3 1434eb8e494SKris Buschelman * strategy should search maxcol columns 1444eb8e494SKris Buschelman * and no rows. 1454eb8e494SKris Buschelman * parmlu(7) = dens2 the density at which the Markowitz 0.6 1464eb8e494SKris Buschelman * strategy should search only 1 column 1474eb8e494SKris Buschelman * or (preferably) use a dense LU for 1484eb8e494SKris Buschelman * all the remaining rows and columns. 1494eb8e494SKris Buschelman * 1504eb8e494SKris Buschelman * 1517a7aea1fSJed Brown * Output parameters: 1524eb8e494SKris Buschelman * 1534eb8e494SKris Buschelman * parmlu(9) = amax Maximum element in A. 1544eb8e494SKris Buschelman * parmlu(10) = elmax Maximum multiplier in current L. 1554eb8e494SKris Buschelman * parmlu(11) = umax Maximum element in current U. 1564eb8e494SKris Buschelman * parmlu(12) = dumax Maximum diagonal in U. 1574eb8e494SKris Buschelman * parmlu(13) = dumin Minimum diagonal in U. 1584eb8e494SKris Buschelman * parmlu(14) = 1594eb8e494SKris Buschelman * parmlu(15) = 1604eb8e494SKris Buschelman * parmlu(16) = 1614eb8e494SKris Buschelman * parmlu(17) = 1624eb8e494SKris Buschelman * parmlu(18) = 1634eb8e494SKris Buschelman * parmlu(19) = resid lu6sol: residual after solve with U or U'. 1644eb8e494SKris Buschelman * ... 1654eb8e494SKris Buschelman * parmlu(29) = 1664eb8e494SKris Buschelman */ 1674eb8e494SKris Buschelman 1684eb8e494SKris Buschelman #define Factorization_Tolerance 1e-1 1694eb8e494SKris Buschelman #define Factorization_Pivot_Tolerance pow(2.2204460492503131E-16, 2.0 / 3.0) 1704eb8e494SKris Buschelman #define Factorization_Small_Tolerance 1e-15 /* pow(DBL_EPSILON, 0.8) */ 1714eb8e494SKris Buschelman 172d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_LUSOL(Mat A) 173d71ae5a4SJacob Faibussowitsch { 174f0c56d0fSKris Buschelman Mat_LUSOL *lusol = (Mat_LUSOL *)A->spptr; 1754eb8e494SKris Buschelman 1764eb8e494SKris Buschelman PetscFunctionBegin; 177bf0cc555SLisandro Dalcin if (lusol && lusol->CleanUpLUSOL) { 1789566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->ip)); 1799566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->iq)); 1809566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->lenc)); 1819566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->lenr)); 1829566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->locc)); 1839566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->locr)); 1849566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->iploc)); 1859566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->iqloc)); 1869566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->ipinv)); 1879566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->iqinv)); 1889566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->mnsw)); 1899566063dSJacob Faibussowitsch PetscCall(PetscFree(lusol->mnsv)); 1909566063dSJacob Faibussowitsch PetscCall(PetscFree3(lusol->data, lusol->indc, lusol->indr)); 1914eb8e494SKris Buschelman } 1929566063dSJacob Faibussowitsch PetscCall(PetscFree(A->spptr)); 1939566063dSJacob Faibussowitsch PetscCall(MatDestroy_SeqAIJ(A)); 1943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1954eb8e494SKris Buschelman } 1964eb8e494SKris Buschelman 197d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSolve_LUSOL(Mat A, Vec b, Vec x) 198d71ae5a4SJacob Faibussowitsch { 199f0c56d0fSKris Buschelman Mat_LUSOL *lusol = (Mat_LUSOL *)A->spptr; 200d9ca1df4SBarry Smith double *xx; 201d9ca1df4SBarry Smith const double *bb; 2024eb8e494SKris Buschelman int mode = 5; 2036849ba73SBarry Smith int i, m, n, nnz, status; 2044eb8e494SKris Buschelman 2054eb8e494SKris Buschelman PetscFunctionBegin; 2069566063dSJacob Faibussowitsch PetscCall(VecGetArray(x, &xx)); 2079566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(b, &bb)); 2084eb8e494SKris Buschelman 2094eb8e494SKris Buschelman m = n = lusol->n; 2104eb8e494SKris Buschelman nnz = lusol->nnz; 2114eb8e494SKris Buschelman 2122205254eSKarl Rupp for (i = 0; i < m; i++) lusol->mnsv[i] = bb[i]; 2134eb8e494SKris Buschelman 2149371c9d4SSatish 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); 2154eb8e494SKris Buschelman 21628b400f6SJacob Faibussowitsch PetscCheck(!status, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "solve failed, error code %d", status); 2174eb8e494SKris Buschelman 2189566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(x, &xx)); 2199566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(b, &bb)); 2203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2214eb8e494SKris Buschelman } 2224eb8e494SKris Buschelman 223d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactorNumeric_LUSOL(Mat F, Mat A, const MatFactorInfo *info) 224d71ae5a4SJacob Faibussowitsch { 2254eb8e494SKris Buschelman Mat_SeqAIJ *a; 226719d5645SBarry Smith Mat_LUSOL *lusol = (Mat_LUSOL *)F->spptr; 2274eb8e494SKris Buschelman int m, n, nz, nnz, status; 2286849ba73SBarry Smith int i, rs, re; 2294eb8e494SKris Buschelman int factorizations; 2304eb8e494SKris Buschelman 2314eb8e494SKris Buschelman PetscFunctionBegin; 2329566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 2334eb8e494SKris Buschelman a = (Mat_SeqAIJ *)A->data; 2344eb8e494SKris Buschelman 23508401ef6SPierre Jolivet PetscCheck(m == lusol->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "factorization struct inconsistent"); 2364eb8e494SKris Buschelman 2374eb8e494SKris Buschelman factorizations = 0; 2382205254eSKarl Rupp do { 2394eb8e494SKris Buschelman /*******************************************************************/ 2404eb8e494SKris Buschelman /* Check the workspace allocation. */ 2414eb8e494SKris Buschelman /*******************************************************************/ 2424eb8e494SKris Buschelman 2434eb8e494SKris Buschelman nz = a->nz; 2444eb8e494SKris Buschelman nnz = PetscMax(lusol->nnz, (int)(lusol->elbowroom * nz)); 2454eb8e494SKris Buschelman nnz = PetscMax(nnz, 5 * n); 2464eb8e494SKris Buschelman 2474eb8e494SKris Buschelman if (nnz < lusol->luparm[12]) { 2484eb8e494SKris Buschelman nnz = (int)(lusol->luroom * lusol->luparm[12]); 2494eb8e494SKris Buschelman } else if ((factorizations > 0) && (lusol->luroom < 6)) { 2504eb8e494SKris Buschelman lusol->luroom += 0.1; 2514eb8e494SKris Buschelman } 2524eb8e494SKris Buschelman 2534eb8e494SKris Buschelman nnz = PetscMax(nnz, (int)(lusol->luroom * (lusol->luparm[22] + lusol->luparm[23]))); 2544eb8e494SKris Buschelman 2554eb8e494SKris Buschelman if (nnz > lusol->nnz) { 2569566063dSJacob Faibussowitsch PetscCall(PetscFree3(lusol->data, lusol->indc, lusol->indr)); 2579566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(nnz, &lusol->data, nnz, &lusol->indc, nnz, &lusol->indr)); 2584eb8e494SKris Buschelman lusol->nnz = nnz; 2594eb8e494SKris Buschelman } 2604eb8e494SKris Buschelman 2614eb8e494SKris Buschelman /*******************************************************************/ 2624eb8e494SKris Buschelman /* Fill in the data for the problem. (1-based Fortran style) */ 2634eb8e494SKris Buschelman /*******************************************************************/ 2644eb8e494SKris Buschelman 2654eb8e494SKris Buschelman nz = 0; 2662205254eSKarl Rupp for (i = 0; i < n; i++) { 2674eb8e494SKris Buschelman rs = a->i[i]; 2684eb8e494SKris Buschelman re = a->i[i + 1]; 2694eb8e494SKris Buschelman 2702205254eSKarl Rupp while (rs < re) { 2712205254eSKarl Rupp if (a->a[rs] != 0.0) { 2724eb8e494SKris Buschelman lusol->indc[nz] = i + 1; 2734eb8e494SKris Buschelman lusol->indr[nz] = a->j[rs] + 1; 2744eb8e494SKris Buschelman lusol->data[nz] = a->a[rs]; 2754eb8e494SKris Buschelman nz++; 2764eb8e494SKris Buschelman } 2774eb8e494SKris Buschelman rs++; 2784eb8e494SKris Buschelman } 2794eb8e494SKris Buschelman } 2804eb8e494SKris Buschelman 2814eb8e494SKris Buschelman /*******************************************************************/ 2824eb8e494SKris Buschelman /* Do the factorization. */ 2834eb8e494SKris Buschelman /*******************************************************************/ 2844eb8e494SKris Buschelman 2859371c9d4SSatish 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); 2864eb8e494SKris Buschelman 2872205254eSKarl Rupp switch (status) { 288d71ae5a4SJacob Faibussowitsch case 0: /* factored */ 289d71ae5a4SJacob Faibussowitsch break; 2904eb8e494SKris Buschelman 291d71ae5a4SJacob Faibussowitsch case 7: /* insufficient memory */ 292d71ae5a4SJacob Faibussowitsch break; 2934eb8e494SKris Buschelman 2944eb8e494SKris Buschelman case 1: 295d71ae5a4SJacob Faibussowitsch case -1: /* singular */ 296d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Singular matrix"); 2974eb8e494SKris Buschelman 2984eb8e494SKris Buschelman case 3: 299d71ae5a4SJacob Faibussowitsch case 4: /* error conditions */ 300d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "matrix error"); 3014eb8e494SKris Buschelman 302d71ae5a4SJacob Faibussowitsch default: /* unknown condition */ 303d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "matrix unknown return code"); 3044eb8e494SKris Buschelman } 3054eb8e494SKris Buschelman 3064eb8e494SKris Buschelman factorizations++; 3074eb8e494SKris Buschelman } while (status == 7); 308719d5645SBarry Smith F->ops->solve = MatSolve_LUSOL; 309719d5645SBarry Smith F->assembled = PETSC_TRUE; 310719d5645SBarry Smith F->preallocated = PETSC_TRUE; 3113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3124eb8e494SKris Buschelman } 3134eb8e494SKris Buschelman 314d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactorSymbolic_LUSOL(Mat F, Mat A, IS r, IS c, const MatFactorInfo *info) 315d71ae5a4SJacob Faibussowitsch { 3164eb8e494SKris Buschelman /************************************************************************/ 3174eb8e494SKris Buschelman /* Input */ 3184eb8e494SKris Buschelman /* A - matrix to factor */ 3194eb8e494SKris Buschelman /* r - row permutation (ignored) */ 3204eb8e494SKris Buschelman /* c - column permutation (ignored) */ 3214eb8e494SKris Buschelman /* */ 3224eb8e494SKris Buschelman /* Output */ 3234eb8e494SKris Buschelman /* F - matrix storing the factorization; */ 3244eb8e494SKris Buschelman /************************************************************************/ 325f0c56d0fSKris Buschelman Mat_LUSOL *lusol; 326dfbe8321SBarry Smith int i, m, n, nz, nnz; 3274eb8e494SKris Buschelman 3284eb8e494SKris Buschelman PetscFunctionBegin; 3294eb8e494SKris Buschelman /************************************************************************/ 3304eb8e494SKris Buschelman /* Check the arguments. */ 3314eb8e494SKris Buschelman /************************************************************************/ 3324eb8e494SKris Buschelman 3339566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 3344eb8e494SKris Buschelman nz = ((Mat_SeqAIJ *)A->data)->nz; 3354eb8e494SKris Buschelman 3364eb8e494SKris Buschelman /************************************************************************/ 3374eb8e494SKris Buschelman /* Create the factorization. */ 3384eb8e494SKris Buschelman /************************************************************************/ 3394eb8e494SKris Buschelman 34035bd34faSBarry Smith F->ops->lufactornumeric = MatLUFactorNumeric_LUSOL; 34135bd34faSBarry Smith lusol = (Mat_LUSOL *)(F->spptr); 3424eb8e494SKris Buschelman 3434eb8e494SKris Buschelman /************************************************************************/ 3444eb8e494SKris Buschelman /* Initialize parameters */ 3454eb8e494SKris Buschelman /************************************************************************/ 3464eb8e494SKris Buschelman 3472205254eSKarl Rupp for (i = 0; i < 30; i++) { 3484eb8e494SKris Buschelman lusol->luparm[i] = 0; 3494eb8e494SKris Buschelman lusol->parmlu[i] = 0; 3504eb8e494SKris Buschelman } 3514eb8e494SKris Buschelman 3524eb8e494SKris Buschelman lusol->luparm[1] = -1; 3534eb8e494SKris Buschelman lusol->luparm[2] = 5; 3544eb8e494SKris Buschelman lusol->luparm[7] = 1; 3554eb8e494SKris Buschelman 3564eb8e494SKris Buschelman lusol->parmlu[0] = 1 / Factorization_Tolerance; 3574eb8e494SKris Buschelman lusol->parmlu[1] = 1 / Factorization_Tolerance; 3584eb8e494SKris Buschelman lusol->parmlu[2] = Factorization_Small_Tolerance; 3594eb8e494SKris Buschelman lusol->parmlu[3] = Factorization_Pivot_Tolerance; 3604eb8e494SKris Buschelman lusol->parmlu[4] = Factorization_Pivot_Tolerance; 3614eb8e494SKris Buschelman lusol->parmlu[5] = 3.0; 3624eb8e494SKris Buschelman lusol->parmlu[6] = 0.3; 3634eb8e494SKris Buschelman lusol->parmlu[7] = 0.6; 3644eb8e494SKris Buschelman 3654eb8e494SKris Buschelman /************************************************************************/ 3664eb8e494SKris Buschelman /* Allocate the workspace needed by LUSOL. */ 3674eb8e494SKris Buschelman /************************************************************************/ 3684eb8e494SKris Buschelman 3694eb8e494SKris Buschelman lusol->elbowroom = PetscMax(lusol->elbowroom, info->fill); 3704eb8e494SKris Buschelman nnz = PetscMax((int)(lusol->elbowroom * nz), 5 * n); 3714eb8e494SKris Buschelman 3724eb8e494SKris Buschelman lusol->n = n; 3734eb8e494SKris Buschelman lusol->nz = nz; 3744eb8e494SKris Buschelman lusol->nnz = nnz; 3754eb8e494SKris Buschelman lusol->luroom = 1.75; 3764eb8e494SKris Buschelman 377d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->ip)); 378d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->iq)); 379d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->lenc)); 380d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->lenr)); 381d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->locc)); 382d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->locr)); 383d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->iploc)); 384d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->iqloc)); 385d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->ipinv)); 386d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(int) * n, &lusol->iqinv)); 387d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(double) * n, &lusol->mnsw)); 388d0609cedSBarry Smith PetscCall(PetscMalloc(sizeof(double) * n, &lusol->mnsv)); 3899566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(nnz, &lusol->data, nnz, &lusol->indc, nnz, &lusol->indr)); 3902205254eSKarl Rupp 3914eb8e494SKris Buschelman lusol->CleanUpLUSOL = PETSC_TRUE; 39235bd34faSBarry Smith F->ops->lufactornumeric = MatLUFactorNumeric_LUSOL; 3933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3944eb8e494SKris Buschelman } 3954eb8e494SKris Buschelman 396d71ae5a4SJacob Faibussowitsch PetscErrorCode MatFactorGetSolverType_seqaij_lusol(Mat A, MatSolverType *type) 397d71ae5a4SJacob Faibussowitsch { 39835bd34faSBarry Smith PetscFunctionBegin; 3992692d6eeSBarry Smith *type = MATSOLVERLUSOL; 4003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40135bd34faSBarry Smith } 40235bd34faSBarry Smith 403d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_lusol(Mat A, MatFactorType ftype, Mat *F) 404d71ae5a4SJacob Faibussowitsch { 405b24902e0SBarry Smith Mat B; 406f0c56d0fSKris Buschelman Mat_LUSOL *lusol; 40735bd34faSBarry Smith int m, n; 4084eb8e494SKris Buschelman 4094eb8e494SKris Buschelman PetscFunctionBegin; 4109566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 4119566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 4129566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, PETSC_DECIDE, PETSC_DECIDE, m, n)); 4139566063dSJacob Faibussowitsch PetscCall(MatSetType(B, ((PetscObject)A)->type_name)); 4149566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(B, 0, NULL)); 4154eb8e494SKris Buschelman 4164dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&lusol)); 417b24902e0SBarry Smith B->spptr = lusol; 4182f71e704SKris Buschelman 41966e17bc3SBarry Smith B->trivialsymbolic = PETSC_TRUE; 420f0c56d0fSKris Buschelman B->ops->lufactorsymbolic = MatLUFactorSymbolic_LUSOL; 421f0c56d0fSKris Buschelman B->ops->destroy = MatDestroy_LUSOL; 4222205254eSKarl Rupp 4239566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatFactorGetSolverType_C", MatFactorGetSolverType_seqaij_lusol)); 4242205254eSKarl Rupp 425d5f3da31SBarry Smith B->factortype = MAT_FACTOR_LU; 4269566063dSJacob Faibussowitsch PetscCall(PetscFree(B->solvertype)); 4279566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERLUSOL, &B->solvertype)); 42800c67f3bSHong Zhang 4293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 430f0c56d0fSKris Buschelman } 431f0c56d0fSKris Buschelman 432d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatSolverTypeRegister_Lusol(void) 433d71ae5a4SJacob Faibussowitsch { 43442c9c57cSBarry Smith PetscFunctionBegin; 4359566063dSJacob Faibussowitsch PetscCall(MatSolverTypeRegister(MATSOLVERLUSOL, MATSEQAIJ, MAT_FACTOR_LU, MatGetFactor_seqaij_lusol)); 4363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 43742c9c57cSBarry Smith } 43842c9c57cSBarry Smith 4392f71e704SKris Buschelman /*MC 44011a5261eSBarry Smith MATSOLVERLUSOL - "lusol" - Provides direct solvers, LU, for sequential matrices 4412f71e704SKris Buschelman via the external package LUSOL. 4422f71e704SKris Buschelman 44311a5261eSBarry Smith Works with `MATSEQAIJ` matrices 4442f71e704SKris Buschelman 4452f71e704SKris Buschelman Level: beginner 4462f71e704SKris Buschelman 447*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `PCLU`, `PCFactorSetMatSolverType()`, `MatSolverType` 4482f71e704SKris Buschelman M*/ 449