14eb8e494SKris Buschelman /*$Id: lusol.c,v 1.11 2001/08/06 21:15:14 bsmith Exp $*/ 24eb8e494SKris Buschelman /* 34eb8e494SKris Buschelman Provides an interface to the LUSOL package of .... 44eb8e494SKris Buschelman 54eb8e494SKris Buschelman */ 64eb8e494SKris Buschelman #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 EXTERN_C_BEGIN 234eb8e494SKris Buschelman /* 244eb8e494SKris Buschelman Dummy symbols that the MINOS files mi25bfac.f and mi15blas.f may require 254eb8e494SKris Buschelman */ 264eb8e494SKris Buschelman void PETSC_STDCALL M1PAGE() { 274eb8e494SKris Buschelman ; 284eb8e494SKris Buschelman } 294eb8e494SKris Buschelman void PETSC_STDCALL M5SETX() { 304eb8e494SKris Buschelman ; 314eb8e494SKris Buschelman } 324eb8e494SKris Buschelman 334eb8e494SKris Buschelman void PETSC_STDCALL M6RDEL() { 344eb8e494SKris Buschelman ; 354eb8e494SKris Buschelman } 364eb8e494SKris Buschelman EXTERN_C_END 374eb8e494SKris Buschelman 384eb8e494SKris Buschelman EXTERN_C_BEGIN 394eb8e494SKris Buschelman extern void PETSC_STDCALL LU1FAC (int *m, int *n, int *nnz, int *size, int *luparm, 404eb8e494SKris Buschelman double *parmlu, double *data, int *indc, int *indr, 414eb8e494SKris Buschelman int *rowperm, int *colperm, int *collen, int *rowlen, 424eb8e494SKris Buschelman int *colstart, int *rowstart, int *rploc, int *cploc, 434eb8e494SKris Buschelman int *rpinv, int *cpinv, double *w, int *inform); 444eb8e494SKris Buschelman 454eb8e494SKris Buschelman extern void PETSC_STDCALL LU6SOL (int *mode, int *m, int *n, double *rhs, double *x, 464eb8e494SKris Buschelman int *size, int *luparm, double *parmlu, double *data, 474eb8e494SKris Buschelman int *indc, int *indr, int *rowperm, int *colperm, 484eb8e494SKris Buschelman int *collen, int *rowlen, int *colstart, int *rowstart, 494eb8e494SKris Buschelman int *inform); 504eb8e494SKris Buschelman 514eb8e494SKris Buschelman typedef struct 524eb8e494SKris Buschelman { 534eb8e494SKris Buschelman double *data; 544eb8e494SKris Buschelman int *indc; 554eb8e494SKris Buschelman int *indr; 564eb8e494SKris Buschelman 574eb8e494SKris Buschelman int *ip; 584eb8e494SKris Buschelman int *iq; 594eb8e494SKris Buschelman int *lenc; 604eb8e494SKris Buschelman int *lenr; 614eb8e494SKris Buschelman int *locc; 624eb8e494SKris Buschelman int *locr; 634eb8e494SKris Buschelman int *iploc; 644eb8e494SKris Buschelman int *iqloc; 654eb8e494SKris Buschelman int *ipinv; 664eb8e494SKris Buschelman int *iqinv; 674eb8e494SKris Buschelman double *mnsw; 684eb8e494SKris Buschelman double *mnsv; 694eb8e494SKris Buschelman 704eb8e494SKris Buschelman double elbowroom; 714eb8e494SKris Buschelman double luroom; /* Extra space allocated when factor fails */ 724eb8e494SKris Buschelman double parmlu[30]; /* Input/output to LUSOL */ 734eb8e494SKris Buschelman 744eb8e494SKris Buschelman int n; /* Number of rows/columns in matrix */ 754eb8e494SKris Buschelman int nz; /* Number of nonzeros */ 764eb8e494SKris Buschelman int nnz; /* Number of nonzeros allocated for factors */ 774eb8e494SKris Buschelman int luparm[30]; /* Input/output to LUSOL */ 784eb8e494SKris Buschelman 794eb8e494SKris Buschelman int (*MatDestroy)(Mat); 804eb8e494SKris Buschelman PetscTruth CleanUpLUSOL; 814eb8e494SKris Buschelman 824eb8e494SKris Buschelman } Mat_SeqAIJ_LUSOL; 834eb8e494SKris Buschelman 844eb8e494SKris Buschelman /* LUSOL input/Output Parameters (Description uses C-style indexes 854eb8e494SKris Buschelman * 864eb8e494SKris Buschelman * Input parameters Typical value 874eb8e494SKris Buschelman * 884eb8e494SKris Buschelman * luparm(0) = nout File number for printed messages. 6 894eb8e494SKris Buschelman * luparm(1) = lprint Print level. 0 904eb8e494SKris Buschelman * < 0 suppresses output. 914eb8e494SKris Buschelman * = 0 gives error messages. 924eb8e494SKris Buschelman * = 1 gives debug output from some of the 934eb8e494SKris Buschelman * other routines in LUSOL. 944eb8e494SKris Buschelman * >= 2 gives the pivot row and column and the 954eb8e494SKris Buschelman * no. of rows and columns involved at 964eb8e494SKris Buschelman * each elimination step in lu1fac. 974eb8e494SKris Buschelman * luparm(2) = maxcol lu1fac: maximum number of columns 5 984eb8e494SKris Buschelman * searched allowed in a Markowitz-type 994eb8e494SKris Buschelman * search for the next pivot element. 1004eb8e494SKris Buschelman * For some of the factorization, the 1014eb8e494SKris Buschelman * number of rows searched is 1024eb8e494SKris Buschelman * maxrow = maxcol - 1. 1034eb8e494SKris Buschelman * 1044eb8e494SKris Buschelman * 1054eb8e494SKris Buschelman * Output parameters 1064eb8e494SKris Buschelman * 1074eb8e494SKris Buschelman * luparm(9) = inform Return code from last call to any LU routine. 1084eb8e494SKris Buschelman * luparm(10) = nsing No. of singularities marked in the 1094eb8e494SKris Buschelman * output array w(*). 1104eb8e494SKris Buschelman * luparm(11) = jsing Column index of last singularity. 1114eb8e494SKris Buschelman * luparm(12) = minlen Minimum recommended value for lena. 1124eb8e494SKris Buschelman * luparm(13) = maxlen ? 1134eb8e494SKris Buschelman * luparm(14) = nupdat No. of updates performed by the lu8 routines. 1144eb8e494SKris Buschelman * luparm(15) = nrank No. of nonempty rows of U. 1154eb8e494SKris Buschelman * luparm(16) = ndens1 No. of columns remaining when the density of 1164eb8e494SKris Buschelman * the matrix being factorized reached dens1. 1174eb8e494SKris Buschelman * luparm(17) = ndens2 No. of columns remaining when the density of 1184eb8e494SKris Buschelman * the matrix being factorized reached dens2. 1194eb8e494SKris Buschelman * luparm(18) = jumin The column index associated with dumin. 1204eb8e494SKris Buschelman * luparm(19) = numl0 No. of columns in initial L. 1214eb8e494SKris Buschelman * luparm(20) = lenl0 Size of initial L (no. of nonzeros). 1224eb8e494SKris Buschelman * luparm(21) = lenu0 Size of initial U. 1234eb8e494SKris Buschelman * luparm(22) = lenl Size of current L. 1244eb8e494SKris Buschelman * luparm(23) = lenu Size of current U. 1254eb8e494SKris Buschelman * luparm(24) = lrow Length of row file. 1264eb8e494SKris Buschelman * luparm(25) = ncp No. of compressions of LU data structures. 1274eb8e494SKris Buschelman * luparm(26) = mersum lu1fac: sum of Markowitz merit counts. 1284eb8e494SKris Buschelman * luparm(27) = nutri lu1fac: triangular rows in U. 1294eb8e494SKris Buschelman * luparm(28) = nltri lu1fac: triangular rows in L. 1304eb8e494SKris Buschelman * luparm(29) = 1314eb8e494SKris Buschelman * 1324eb8e494SKris Buschelman * 1334eb8e494SKris Buschelman * Input parameters Typical value 1344eb8e494SKris Buschelman * 1354eb8e494SKris Buschelman * parmlu(0) = elmax1 Max multiplier allowed in L 10.0 1364eb8e494SKris Buschelman * during factor. 1374eb8e494SKris Buschelman * parmlu(1) = elmax2 Max multiplier allowed in L 10.0 1384eb8e494SKris Buschelman * during updates. 1394eb8e494SKris Buschelman * parmlu(2) = small Absolute tolerance for eps**0.8 1404eb8e494SKris Buschelman * treating reals as zero. IBM double: 3.0d-13 1414eb8e494SKris Buschelman * parmlu(3) = utol1 Absolute tol for flagging eps**0.66667 1424eb8e494SKris Buschelman * small diagonals of U. IBM double: 3.7d-11 1434eb8e494SKris Buschelman * parmlu(4) = utol2 Relative tol for flagging eps**0.66667 1444eb8e494SKris Buschelman * small diagonals of U. IBM double: 3.7d-11 1454eb8e494SKris Buschelman * parmlu(5) = uspace Factor limiting waste space in U. 3.0 1464eb8e494SKris Buschelman * In lu1fac, the row or column lists 1474eb8e494SKris Buschelman * are compressed if their length 1484eb8e494SKris Buschelman * exceeds uspace times the length of 1494eb8e494SKris Buschelman * either file after the last compression. 1504eb8e494SKris Buschelman * parmlu(6) = dens1 The density at which the Markowitz 0.3 1514eb8e494SKris Buschelman * strategy should search maxcol columns 1524eb8e494SKris Buschelman * and no rows. 1534eb8e494SKris Buschelman * parmlu(7) = dens2 the density at which the Markowitz 0.6 1544eb8e494SKris Buschelman * strategy should search only 1 column 1554eb8e494SKris Buschelman * or (preferably) use a dense LU for 1564eb8e494SKris Buschelman * all the remaining rows and columns. 1574eb8e494SKris Buschelman * 1584eb8e494SKris Buschelman * 1594eb8e494SKris Buschelman * Output parameters 1604eb8e494SKris Buschelman * 1614eb8e494SKris Buschelman * parmlu(9) = amax Maximum element in A. 1624eb8e494SKris Buschelman * parmlu(10) = elmax Maximum multiplier in current L. 1634eb8e494SKris Buschelman * parmlu(11) = umax Maximum element in current U. 1644eb8e494SKris Buschelman * parmlu(12) = dumax Maximum diagonal in U. 1654eb8e494SKris Buschelman * parmlu(13) = dumin Minimum diagonal in U. 1664eb8e494SKris Buschelman * parmlu(14) = 1674eb8e494SKris Buschelman * parmlu(15) = 1684eb8e494SKris Buschelman * parmlu(16) = 1694eb8e494SKris Buschelman * parmlu(17) = 1704eb8e494SKris Buschelman * parmlu(18) = 1714eb8e494SKris Buschelman * parmlu(19) = resid lu6sol: residual after solve with U or U'. 1724eb8e494SKris Buschelman * ... 1734eb8e494SKris Buschelman * parmlu(29) = 1744eb8e494SKris Buschelman */ 1754eb8e494SKris Buschelman 1764eb8e494SKris Buschelman #define Factorization_Tolerance 1e-1 1774eb8e494SKris Buschelman #define Factorization_Pivot_Tolerance pow(2.2204460492503131E-16, 2.0 / 3.0) 1784eb8e494SKris Buschelman #define Factorization_Small_Tolerance 1e-15 /* pow(DBL_EPSILON, 0.8) */ 1794eb8e494SKris Buschelman 1804eb8e494SKris Buschelman 1814eb8e494SKris Buschelman #undef __FUNCT__ 1824eb8e494SKris Buschelman #define __FUNCT__ "MatDestroy_SeqAIJ_LUSOL" 1834eb8e494SKris Buschelman int MatDestroy_SeqAIJ_LUSOL(Mat A) 1844eb8e494SKris Buschelman { 1854eb8e494SKris Buschelman Mat_SeqAIJ_LUSOL *lusol; 1864eb8e494SKris Buschelman int ierr,(*destroy)(Mat); 1874eb8e494SKris Buschelman 1884eb8e494SKris Buschelman PetscFunctionBegin; 1894eb8e494SKris Buschelman lusol = (Mat_SeqAIJ_LUSOL *)A->spptr; 1904eb8e494SKris Buschelman if (lusol->CleanUpLUSOL) { 1914eb8e494SKris Buschelman ierr = PetscFree(lusol->ip);CHKERRQ(ierr); 1924eb8e494SKris Buschelman ierr = PetscFree(lusol->iq);CHKERRQ(ierr); 1934eb8e494SKris Buschelman ierr = PetscFree(lusol->lenc);CHKERRQ(ierr); 1944eb8e494SKris Buschelman ierr = PetscFree(lusol->lenr);CHKERRQ(ierr); 1954eb8e494SKris Buschelman ierr = PetscFree(lusol->locc);CHKERRQ(ierr); 1964eb8e494SKris Buschelman ierr = PetscFree(lusol->locr);CHKERRQ(ierr); 1974eb8e494SKris Buschelman ierr = PetscFree(lusol->iploc);CHKERRQ(ierr); 1984eb8e494SKris Buschelman ierr = PetscFree(lusol->iqloc);CHKERRQ(ierr); 1994eb8e494SKris Buschelman ierr = PetscFree(lusol->ipinv);CHKERRQ(ierr); 2004eb8e494SKris Buschelman ierr = PetscFree(lusol->iqinv);CHKERRQ(ierr); 2014eb8e494SKris Buschelman ierr = PetscFree(lusol->mnsw);CHKERRQ(ierr); 2024eb8e494SKris Buschelman ierr = PetscFree(lusol->mnsv);CHKERRQ(ierr); 2034eb8e494SKris Buschelman 2044eb8e494SKris Buschelman ierr = PetscFree(lusol->indc);CHKERRQ(ierr); 2054eb8e494SKris Buschelman } 2064eb8e494SKris Buschelman 2074eb8e494SKris Buschelman destroy = lusol->MatDestroy; 2084eb8e494SKris Buschelman ierr = PetscFree(lusol);CHKERRQ(ierr); 2094eb8e494SKris Buschelman ierr = (*destroy)(A);CHKERRQ(ierr); 2104eb8e494SKris Buschelman PetscFunctionReturn(0); 2114eb8e494SKris Buschelman } 2124eb8e494SKris Buschelman 2134eb8e494SKris Buschelman #undef __FUNCT__ 2144eb8e494SKris Buschelman #define __FUNCT__ "MatSolve_SeqAIJ_LUSOL" 2154eb8e494SKris Buschelman int MatSolve_SeqAIJ_LUSOL(Mat A,Vec b,Vec x) 2164eb8e494SKris Buschelman { 2174eb8e494SKris Buschelman Mat_SeqAIJ_LUSOL *lusol = (Mat_SeqAIJ_LUSOL *)A->spptr; 2184eb8e494SKris Buschelman double *bb, *xx; 2194eb8e494SKris Buschelman int mode = 5; 2204eb8e494SKris Buschelman int i, m, n, nnz, status, ierr; 2214eb8e494SKris Buschelman 2224eb8e494SKris Buschelman PetscFunctionBegin; 2234eb8e494SKris Buschelman ierr = VecGetArray(x, &xx);CHKERRQ(ierr); 2244eb8e494SKris Buschelman ierr = VecGetArray(b, &bb);CHKERRQ(ierr); 2254eb8e494SKris Buschelman 2264eb8e494SKris Buschelman m = n = lusol->n; 2274eb8e494SKris Buschelman nnz = lusol->nnz; 2284eb8e494SKris Buschelman 2294eb8e494SKris Buschelman for (i = 0; i < m; i++) 2304eb8e494SKris Buschelman { 2314eb8e494SKris Buschelman lusol->mnsv[i] = bb[i]; 2324eb8e494SKris Buschelman } 2334eb8e494SKris Buschelman 2344eb8e494SKris Buschelman LU6SOL(&mode, &m, &n, lusol->mnsv, xx, &nnz, 2354eb8e494SKris Buschelman lusol->luparm, lusol->parmlu, lusol->data, 2364eb8e494SKris Buschelman lusol->indc, lusol->indr, lusol->ip, lusol->iq, 2374eb8e494SKris Buschelman lusol->lenc, lusol->lenr, lusol->locc, lusol->locr, &status); 2384eb8e494SKris Buschelman 2394eb8e494SKris Buschelman if (status != 0) 2404eb8e494SKris Buschelman { 2414eb8e494SKris Buschelman SETERRQ(PETSC_ERR_ARG_SIZ,"solve failed"); 2424eb8e494SKris Buschelman } 2434eb8e494SKris Buschelman 2444eb8e494SKris Buschelman ierr = VecRestoreArray(x, &xx);CHKERRQ(ierr); 2454eb8e494SKris Buschelman ierr = VecRestoreArray(b, &bb);CHKERRQ(ierr); 2464eb8e494SKris Buschelman PetscFunctionReturn(0); 2474eb8e494SKris Buschelman } 2484eb8e494SKris Buschelman 2494eb8e494SKris Buschelman #undef __FUNCT__ 2504eb8e494SKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_SeqAIJ_LUSOL" 2514eb8e494SKris Buschelman int MatLUFactorNumeric_SeqAIJ_LUSOL(Mat A, Mat *F) 2524eb8e494SKris Buschelman { 2534eb8e494SKris Buschelman Mat_SeqAIJ *a; 2544eb8e494SKris Buschelman Mat_SeqAIJ_LUSOL *lusol = (Mat_SeqAIJ_LUSOL *)(*F)->spptr; 2554eb8e494SKris Buschelman int m, n, nz, nnz, status; 2564eb8e494SKris Buschelman int i, rs, re,ierr; 2574eb8e494SKris Buschelman int factorizations; 2584eb8e494SKris Buschelman 2594eb8e494SKris Buschelman PetscFunctionBegin; 2604eb8e494SKris Buschelman ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);CHKERRQ(ierr); 2614eb8e494SKris Buschelman a = (Mat_SeqAIJ *)A->data; 2624eb8e494SKris Buschelman 2634eb8e494SKris Buschelman if (m != lusol->n) { 2644eb8e494SKris Buschelman SETERRQ(PETSC_ERR_ARG_SIZ,"factorization struct inconsistent"); 2654eb8e494SKris Buschelman } 2664eb8e494SKris Buschelman 2674eb8e494SKris Buschelman factorizations = 0; 2684eb8e494SKris Buschelman do 2694eb8e494SKris Buschelman { 2704eb8e494SKris Buschelman /*******************************************************************/ 2714eb8e494SKris Buschelman /* Check the workspace allocation. */ 2724eb8e494SKris Buschelman /*******************************************************************/ 2734eb8e494SKris Buschelman 2744eb8e494SKris Buschelman nz = a->nz; 2754eb8e494SKris Buschelman nnz = PetscMax(lusol->nnz, (int)(lusol->elbowroom*nz)); 2764eb8e494SKris Buschelman nnz = PetscMax(nnz, 5*n); 2774eb8e494SKris Buschelman 2784eb8e494SKris Buschelman if (nnz < lusol->luparm[12]){ 2794eb8e494SKris Buschelman nnz = (int)(lusol->luroom * lusol->luparm[12]); 2804eb8e494SKris Buschelman } else if ((factorizations > 0) && (lusol->luroom < 6)){ 2814eb8e494SKris Buschelman lusol->luroom += 0.1; 2824eb8e494SKris Buschelman } 2834eb8e494SKris Buschelman 2844eb8e494SKris Buschelman nnz = PetscMax(nnz, (int)(lusol->luroom*(lusol->luparm[22] + lusol->luparm[23]))); 2854eb8e494SKris Buschelman 2864eb8e494SKris Buschelman if (nnz > lusol->nnz){ 2874eb8e494SKris Buschelman ierr = PetscFree(lusol->indc);CHKERRQ(ierr); 2884eb8e494SKris Buschelman ierr = PetscMalloc((sizeof(double)+2*sizeof(int))*nnz,&lusol->indc);CHKERRQ(ierr); 2894eb8e494SKris Buschelman lusol->indr = lusol->indc + nnz; 2904eb8e494SKris Buschelman lusol->data = (double *)(lusol->indr + nnz); 2914eb8e494SKris Buschelman lusol->nnz = nnz; 2924eb8e494SKris Buschelman } 2934eb8e494SKris Buschelman 2944eb8e494SKris Buschelman /*******************************************************************/ 2954eb8e494SKris Buschelman /* Fill in the data for the problem. (1-based Fortran style) */ 2964eb8e494SKris Buschelman /*******************************************************************/ 2974eb8e494SKris Buschelman 2984eb8e494SKris Buschelman nz = 0; 2994eb8e494SKris Buschelman for (i = 0; i < n; i++) 3004eb8e494SKris Buschelman { 3014eb8e494SKris Buschelman rs = a->i[i]; 3024eb8e494SKris Buschelman re = a->i[i+1]; 3034eb8e494SKris Buschelman 3044eb8e494SKris Buschelman while (rs < re) 3054eb8e494SKris Buschelman { 3064eb8e494SKris Buschelman if (a->a[rs] != 0.0) 3074eb8e494SKris Buschelman { 3084eb8e494SKris Buschelman lusol->indc[nz] = i + 1; 3094eb8e494SKris Buschelman lusol->indr[nz] = a->j[rs] + 1; 3104eb8e494SKris Buschelman lusol->data[nz] = a->a[rs]; 3114eb8e494SKris Buschelman nz++; 3124eb8e494SKris Buschelman } 3134eb8e494SKris Buschelman rs++; 3144eb8e494SKris Buschelman } 3154eb8e494SKris Buschelman } 3164eb8e494SKris Buschelman 3174eb8e494SKris Buschelman /*******************************************************************/ 3184eb8e494SKris Buschelman /* Do the factorization. */ 3194eb8e494SKris Buschelman /*******************************************************************/ 3204eb8e494SKris Buschelman 3214eb8e494SKris Buschelman LU1FAC(&m, &n, &nz, &nnz, 3224eb8e494SKris Buschelman lusol->luparm, lusol->parmlu, lusol->data, 3234eb8e494SKris Buschelman lusol->indc, lusol->indr, lusol->ip, lusol->iq, 3244eb8e494SKris Buschelman lusol->lenc, lusol->lenr, lusol->locc, lusol->locr, 3254eb8e494SKris Buschelman lusol->iploc, lusol->iqloc, lusol->ipinv, 3264eb8e494SKris Buschelman lusol->iqinv, lusol->mnsw, &status); 3274eb8e494SKris Buschelman 3284eb8e494SKris Buschelman switch(status) 3294eb8e494SKris Buschelman { 3304eb8e494SKris Buschelman case 0: /* factored */ 3314eb8e494SKris Buschelman break; 3324eb8e494SKris Buschelman 3334eb8e494SKris Buschelman case 7: /* insufficient memory */ 3344eb8e494SKris Buschelman break; 3354eb8e494SKris Buschelman 3364eb8e494SKris Buschelman case 1: 3374eb8e494SKris Buschelman case -1: /* singular */ 3384eb8e494SKris Buschelman SETERRQ(1,"Singular matrix"); 3394eb8e494SKris Buschelman 3404eb8e494SKris Buschelman case 3: 3414eb8e494SKris Buschelman case 4: /* error conditions */ 3424eb8e494SKris Buschelman SETERRQ(1,"matrix error"); 3434eb8e494SKris Buschelman 3444eb8e494SKris Buschelman default: /* unknown condition */ 3454eb8e494SKris Buschelman SETERRQ(1,"matrix unknown return code"); 3464eb8e494SKris Buschelman } 3474eb8e494SKris Buschelman 3484eb8e494SKris Buschelman factorizations++; 3494eb8e494SKris Buschelman } while (status == 7); 350*a8883a68SKris Buschelman (*F)->assembled = PETSC_TRUE; 3514eb8e494SKris Buschelman PetscFunctionReturn(0); 3524eb8e494SKris Buschelman } 3534eb8e494SKris Buschelman 3544eb8e494SKris Buschelman #undef __FUNCT__ 3554eb8e494SKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_SeqAIJ_LUSOL" 3564eb8e494SKris Buschelman int MatLUFactorSymbolic_SeqAIJ_LUSOL(Mat A, IS r, IS c,MatFactorInfo *info, Mat *F) 3574eb8e494SKris Buschelman { 3584eb8e494SKris Buschelman /************************************************************************/ 3594eb8e494SKris Buschelman /* Input */ 3604eb8e494SKris Buschelman /* A - matrix to factor */ 3614eb8e494SKris Buschelman /* r - row permutation (ignored) */ 3624eb8e494SKris Buschelman /* c - column permutation (ignored) */ 3634eb8e494SKris Buschelman /* */ 3644eb8e494SKris Buschelman /* Output */ 3654eb8e494SKris Buschelman /* F - matrix storing the factorization; */ 3664eb8e494SKris Buschelman /************************************************************************/ 3674eb8e494SKris Buschelman Mat B; 3684eb8e494SKris Buschelman Mat_SeqAIJ_LUSOL *lusol; 3694eb8e494SKris Buschelman int ierr,i, m, n, nz, nnz; 3704eb8e494SKris Buschelman 3714eb8e494SKris Buschelman PetscFunctionBegin; 3724eb8e494SKris Buschelman 3734eb8e494SKris Buschelman /************************************************************************/ 3744eb8e494SKris Buschelman /* Check the arguments. */ 3754eb8e494SKris Buschelman /************************************************************************/ 3764eb8e494SKris Buschelman 3774eb8e494SKris Buschelman ierr = MatGetSize(A, &m, &n);CHKERRQ(ierr); 3784eb8e494SKris Buschelman nz = ((Mat_SeqAIJ *)A->data)->nz; 3794eb8e494SKris Buschelman 3804eb8e494SKris Buschelman /************************************************************************/ 3814eb8e494SKris Buschelman /* Create the factorization. */ 3824eb8e494SKris Buschelman /************************************************************************/ 3834eb8e494SKris Buschelman 3844eb8e494SKris Buschelman ierr = MatCreate(A->comm,PETSC_DECIDE,PETSC_DECIDE,m,n,&B);CHKERRQ(ierr); 3854eb8e494SKris Buschelman ierr = MatSetType(B,MATLUSOL);CHKERRQ(ierr); 3864eb8e494SKris Buschelman ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr); 3874eb8e494SKris Buschelman 3884eb8e494SKris Buschelman B->ops->lufactornumeric = MatLUFactorNumeric_SeqAIJ_LUSOL; 3894eb8e494SKris Buschelman B->ops->solve = MatSolve_SeqAIJ_LUSOL; 3904eb8e494SKris Buschelman B->factor = FACTOR_LU; 3914eb8e494SKris Buschelman lusol = (Mat_SeqAIJ_LUSOL*)(B->spptr); 3924eb8e494SKris Buschelman 3934eb8e494SKris Buschelman /************************************************************************/ 3944eb8e494SKris Buschelman /* Initialize parameters */ 3954eb8e494SKris Buschelman /************************************************************************/ 3964eb8e494SKris Buschelman 3974eb8e494SKris Buschelman for (i = 0; i < 30; i++) 3984eb8e494SKris Buschelman { 3994eb8e494SKris Buschelman lusol->luparm[i] = 0; 4004eb8e494SKris Buschelman lusol->parmlu[i] = 0; 4014eb8e494SKris Buschelman } 4024eb8e494SKris Buschelman 4034eb8e494SKris Buschelman lusol->luparm[1] = -1; 4044eb8e494SKris Buschelman lusol->luparm[2] = 5; 4054eb8e494SKris Buschelman lusol->luparm[7] = 1; 4064eb8e494SKris Buschelman 4074eb8e494SKris Buschelman lusol->parmlu[0] = 1 / Factorization_Tolerance; 4084eb8e494SKris Buschelman lusol->parmlu[1] = 1 / Factorization_Tolerance; 4094eb8e494SKris Buschelman lusol->parmlu[2] = Factorization_Small_Tolerance; 4104eb8e494SKris Buschelman lusol->parmlu[3] = Factorization_Pivot_Tolerance; 4114eb8e494SKris Buschelman lusol->parmlu[4] = Factorization_Pivot_Tolerance; 4124eb8e494SKris Buschelman lusol->parmlu[5] = 3.0; 4134eb8e494SKris Buschelman lusol->parmlu[6] = 0.3; 4144eb8e494SKris Buschelman lusol->parmlu[7] = 0.6; 4154eb8e494SKris Buschelman 4164eb8e494SKris Buschelman /************************************************************************/ 4174eb8e494SKris Buschelman /* Allocate the workspace needed by LUSOL. */ 4184eb8e494SKris Buschelman /************************************************************************/ 4194eb8e494SKris Buschelman 4204eb8e494SKris Buschelman lusol->elbowroom = PetscMax(lusol->elbowroom, info->fill); 4214eb8e494SKris Buschelman nnz = PetscMax((int)(lusol->elbowroom*nz), 5*n); 4224eb8e494SKris Buschelman 4234eb8e494SKris Buschelman lusol->n = n; 4244eb8e494SKris Buschelman lusol->nz = nz; 4254eb8e494SKris Buschelman lusol->nnz = nnz; 4264eb8e494SKris Buschelman lusol->luroom = 1.75; 4274eb8e494SKris Buschelman 4284eb8e494SKris Buschelman ierr = PetscMalloc(sizeof(int)*n,&lusol->ip); 4294eb8e494SKris Buschelman ierr = PetscMalloc(sizeof(int)*n,&lusol->iq); 4304eb8e494SKris Buschelman ierr = PetscMalloc(sizeof(int)*n,&lusol->lenc); 4314eb8e494SKris Buschelman ierr = PetscMalloc(sizeof(int)*n,&lusol->lenr); 4324eb8e494SKris Buschelman ierr = PetscMalloc(sizeof(int)*n,&lusol->locc); 4334eb8e494SKris Buschelman ierr = PetscMalloc(sizeof(int)*n,&lusol->locr); 4344eb8e494SKris Buschelman ierr = PetscMalloc(sizeof(int)*n,&lusol->iploc); 4354eb8e494SKris Buschelman ierr = PetscMalloc(sizeof(int)*n,&lusol->iqloc); 4364eb8e494SKris Buschelman ierr = PetscMalloc(sizeof(int)*n,&lusol->ipinv); 4374eb8e494SKris Buschelman ierr = PetscMalloc(sizeof(int)*n,&lusol->iqinv); 4384eb8e494SKris Buschelman ierr = PetscMalloc(sizeof(double)*n,&lusol->mnsw); 4394eb8e494SKris Buschelman ierr = PetscMalloc(sizeof(double)*n,&lusol->mnsv); 4404eb8e494SKris Buschelman 4414eb8e494SKris Buschelman ierr = PetscMalloc((sizeof(double)+2*sizeof(int))*nnz,&lusol->indc); 4424eb8e494SKris Buschelman lusol->indr = lusol->indc + nnz; 4434eb8e494SKris Buschelman lusol->data = (double *)(lusol->indr + nnz); 4444eb8e494SKris Buschelman lusol->CleanUpLUSOL = PETSC_TRUE; 4454eb8e494SKris Buschelman *F = B; 4464eb8e494SKris Buschelman PetscFunctionReturn(0); 4474eb8e494SKris Buschelman } 4484eb8e494SKris Buschelman EXTERN_C_END 4494eb8e494SKris Buschelman 4504eb8e494SKris Buschelman #undef __FUNCT__ 4514eb8e494SKris Buschelman #define __FUNCT__ "MatUseLUSOL_SeqAIJ" 4524eb8e494SKris Buschelman int MatUseLUSOL_SeqAIJ(Mat A) 4534eb8e494SKris Buschelman { 4544eb8e494SKris Buschelman int ierr, m, n; 4554eb8e494SKris Buschelman PetscTruth match; 4564eb8e494SKris Buschelman 4574eb8e494SKris Buschelman PetscFunctionBegin; 4584eb8e494SKris Buschelman ierr = MatGetSize(A, &m, &n);CHKERRQ(ierr); 4594eb8e494SKris Buschelman if (m != n) { 4604eb8e494SKris Buschelman SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square"); 4614eb8e494SKris Buschelman } 4624eb8e494SKris Buschelman 4634eb8e494SKris Buschelman A->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqAIJ_LUSOL; 4644eb8e494SKris Buschelman PetscLogInfo(0,"Using LUSOL for SeqAIJ LU factorization and solves."); 4654eb8e494SKris Buschelman PetscFunctionReturn(0); 4664eb8e494SKris Buschelman } 4674eb8e494SKris Buschelman 4684eb8e494SKris Buschelman EXTERN_C_BEGIN 4694eb8e494SKris Buschelman #undef __FUNCT__ 4704eb8e494SKris Buschelman #define __FUNCT__ "MatCreate_SeqAIJ_LUSOL" 4714eb8e494SKris Buschelman int MatCreate_SeqAIJ_LUSOL(Mat A) 4724eb8e494SKris Buschelman { 4734eb8e494SKris Buschelman int ierr; 4744eb8e494SKris Buschelman Mat_SeqAIJ_LUSOL *lusol; 4754eb8e494SKris Buschelman 4764eb8e494SKris Buschelman PetscFunctionBegin; 4774eb8e494SKris Buschelman ierr = MatSetType(A,MATSEQAIJ);CHKERRQ(ierr); 4784eb8e494SKris Buschelman ierr = MatUseLUSOL_SeqAIJ(A);CHKERRQ(ierr); 4794eb8e494SKris Buschelman 4804eb8e494SKris Buschelman ierr = PetscNew(Mat_SeqAIJ_LUSOL,&lusol);CHKERRQ(ierr); 4814eb8e494SKris Buschelman lusol->CleanUpLUSOL = PETSC_FALSE; 4824eb8e494SKris Buschelman lusol->MatDestroy = A->ops->destroy; 4834eb8e494SKris Buschelman A->ops->destroy = MatDestroy_SeqAIJ_LUSOL; 4844eb8e494SKris Buschelman A->spptr = (void *)lusol; 4854eb8e494SKris Buschelman PetscFunctionReturn(0); 4864eb8e494SKris Buschelman } 4874eb8e494SKris Buschelman EXTERN_C_END 488