1*289bc588SBarry Smith 2*289bc588SBarry Smith 3*289bc588SBarry Smith #include "aij.h" 4*289bc588SBarry Smith 5*289bc588SBarry Smith /* 6*289bc588SBarry Smith Factorization code for AIJ format. 7*289bc588SBarry Smith */ 8*289bc588SBarry Smith 9*289bc588SBarry Smith int MatiAIJLUFactorSymbolic(Mat mat,IS isrow,IS iscol,Mat *fact) 10*289bc588SBarry Smith { 11*289bc588SBarry Smith Matiaij *aij = (Matiaij *) mat->data, *aijnew; 12*289bc588SBarry Smith IS isicol; 13*289bc588SBarry Smith int *r,*ic, ierr, i, j, n = aij->m, *ai = aij->i, *aj = aij->j; 14*289bc588SBarry Smith int prow, *ainew,*ajnew, jmax,*fill, *ajtmp, nz , *ii; 15*289bc588SBarry Smith int *idnew, idx, pivot_row,row,m,fm, nnz, nzi,len; 16*289bc588SBarry Smith 17*289bc588SBarry Smith if (n != aij->n) SETERR(1,"Mat must be square"); 18*289bc588SBarry Smith if (!isrow) {SETERR(1,"Must have row permutation");} 19*289bc588SBarry Smith if (!iscol) {SETERR(1,"Must have column permutation");} 20*289bc588SBarry Smith 21*289bc588SBarry Smith if (ierr = ISInvertPermutation(iscol,&isicol)) SETERR(ierr,0); 22*289bc588SBarry Smith ISGetIndices(isrow,&r); ISGetIndices(isicol,&ic); 23*289bc588SBarry Smith 24*289bc588SBarry Smith /* get new row pointers */ 25*289bc588SBarry Smith ainew = (int *) MALLOC( (n+1)*sizeof(int) ); CHKPTR(ainew); 26*289bc588SBarry Smith ainew[0] = 1; 27*289bc588SBarry Smith /* don't know how many column pointers are needed so estimate */ 28*289bc588SBarry Smith jmax = 2*ai[n]; 29*289bc588SBarry Smith ajnew = (int *) MALLOC( (jmax)*sizeof(int) ); CHKPTR(ajnew); 30*289bc588SBarry Smith /* fill is a linked list of nonzeros in active row */ 31*289bc588SBarry Smith fill = (int *) MALLOC( (n+1)*sizeof(int)); CHKPTR(fill); 32*289bc588SBarry Smith /* idnew is location of diagonal in factor */ 33*289bc588SBarry Smith idnew = (int *) MALLOC( (n+1)*sizeof(int)); CHKPTR(idnew); 34*289bc588SBarry Smith idnew[0] = 1; 35*289bc588SBarry Smith 36*289bc588SBarry Smith for ( i=0; i<n; i++ ) { 37*289bc588SBarry Smith /* first copy previous fill into linked list */ 38*289bc588SBarry Smith nnz = nz = ai[r[i]+1] - ai[r[i]]; 39*289bc588SBarry Smith ajtmp = aj + ai[r[i]] - 1; 40*289bc588SBarry Smith fill[n] = n; 41*289bc588SBarry Smith while (nz--) { 42*289bc588SBarry Smith fm = n; 43*289bc588SBarry Smith idx = ic[*ajtmp++ - 1]; 44*289bc588SBarry Smith do { 45*289bc588SBarry Smith m = fm; 46*289bc588SBarry Smith fm = fill[m]; 47*289bc588SBarry Smith } while (fm < idx); 48*289bc588SBarry Smith fill[m] = idx; 49*289bc588SBarry Smith fill[idx] = fm; 50*289bc588SBarry Smith } 51*289bc588SBarry Smith row = fill[n]; 52*289bc588SBarry Smith while ( row < i ) { 53*289bc588SBarry Smith ajtmp = ajnew + idnew[row] - 1; 54*289bc588SBarry Smith nz = ainew[row+1] - idnew[row]; 55*289bc588SBarry Smith fm = row; 56*289bc588SBarry Smith while (nz--) { 57*289bc588SBarry Smith fm = n; 58*289bc588SBarry Smith idx = *ajtmp++ - 1; 59*289bc588SBarry Smith do { 60*289bc588SBarry Smith m = fm; 61*289bc588SBarry Smith fm = fill[m]; 62*289bc588SBarry Smith } while (fm < idx); 63*289bc588SBarry Smith if (fm != idx) { 64*289bc588SBarry Smith fill[m] = idx; 65*289bc588SBarry Smith fill[idx] = fm; 66*289bc588SBarry Smith fm = idx; 67*289bc588SBarry Smith nnz++; 68*289bc588SBarry Smith } 69*289bc588SBarry Smith } 70*289bc588SBarry Smith row = fill[row]; 71*289bc588SBarry Smith } 72*289bc588SBarry Smith /* copy new filled row into permanent storage */ 73*289bc588SBarry Smith ainew[i+1] = ainew[i] + nnz; 74*289bc588SBarry Smith if (ainew[i+1] > jmax+1) { 75*289bc588SBarry Smith /* allocate a longer ajnew */ 76*289bc588SBarry Smith jmax += nnz*(n-i); 77*289bc588SBarry Smith ajtmp = (int *) MALLOC( jmax*sizeof(int) );CHKPTR(ajtmp); 78*289bc588SBarry Smith MEMCPY(ajtmp,ajnew,(ainew[i]-1)*sizeof(int)); 79*289bc588SBarry Smith FREE(ajnew); 80*289bc588SBarry Smith ajnew = ajtmp; 81*289bc588SBarry Smith } 82*289bc588SBarry Smith ajtmp = ajnew + ainew[i] - 1; 83*289bc588SBarry Smith fm = fill[n]; 84*289bc588SBarry Smith nzi = 0; 85*289bc588SBarry Smith while (nnz--) { 86*289bc588SBarry Smith if (fm < i) nzi++; 87*289bc588SBarry Smith *ajtmp++ = fm + 1; 88*289bc588SBarry Smith fm = fill[fm]; 89*289bc588SBarry Smith } 90*289bc588SBarry Smith idnew[i] = ainew[i] + nzi; 91*289bc588SBarry Smith } 92*289bc588SBarry Smith 93*289bc588SBarry Smith ISDestroy(isicol); FREE(fill); 94*289bc588SBarry Smith 95*289bc588SBarry Smith /* put together the new matrix */ 96*289bc588SBarry Smith ierr = MatCreateSequentialAIJ(n, n, 0, fact); CHKERR(ierr); 97*289bc588SBarry Smith aijnew = (Matiaij *) (*fact)->data; 98*289bc588SBarry Smith FREE(aijnew->imax); 99*289bc588SBarry Smith aijnew->singlemalloc = 0; 100*289bc588SBarry Smith len = ainew[n] - 1; 101*289bc588SBarry Smith aijnew->a = (Scalar *) MALLOC( len ); CHKPTR(aijnew->a); 102*289bc588SBarry Smith aijnew->j = ajnew; 103*289bc588SBarry Smith aijnew->i = ainew; 104*289bc588SBarry Smith aij->diag = idnew; 105*289bc588SBarry Smith (*fact)->row = isrow; 106*289bc588SBarry Smith (*fact)->col = iscol; 107*289bc588SBarry Smith (*fact)->factor = FACTOR_LU; 108*289bc588SBarry Smith return 0; 109*289bc588SBarry Smith } 110*289bc588SBarry Smith 111*289bc588SBarry Smith int MatiAIJLUFactorNumeric(Mat mat,Mat fact) 112*289bc588SBarry Smith { 113*289bc588SBarry Smith Matiaij *aij = (Matiaij *) mat->data, *aijnew = (Matiaij *)fact->data; 114*289bc588SBarry Smith IS iscol = fact->col, isrow = fact->row, isicol; 115*289bc588SBarry Smith int *r,*ic, ierr, i, j, n = aij->m, *ai = aijnew->i, *aj = aijnew->j; 116*289bc588SBarry Smith int prow, *ainew,*ajnew, jmax,*fill, *ajtmpold, *ajtmp, nz , *ii; 117*289bc588SBarry Smith int *idnew, idx, pivot_row,row,m,fm, nnz, nzi,len; 118*289bc588SBarry Smith Scalar *rtmp,*vnew,*v; 119*289bc588SBarry Smith 120*289bc588SBarry Smith if (ierr = ISInvertPermutation(iscol,&isicol)) SETERR(ierr,0); 121*289bc588SBarry Smith ISGetIndices(isrow,&r); ISGetIndices(isicol,&ic); 122*289bc588SBarry Smith rtmp = (Scalar *) MALLOC( (n+1)*sizeof(Scalar) ); CHKPTR(rtmp); 123*289bc588SBarry Smith 124*289bc588SBarry Smith for ( i=0; i<n; i++ ) { 125*289bc588SBarry Smith nz = ai[i+1] - ai[i]; 126*289bc588SBarry Smith ajtmp = aj + ai[i] - 1; 127*289bc588SBarry Smith vnew = aij->a + ai[i] - 1; 128*289bc588SBarry Smith for ( j=0; j<nz; j++ ) rtmp[ajtmp[j]-1] = 0.0; 129*289bc588SBarry Smith 130*289bc588SBarry Smith /* load in initial (unfactored row) */ 131*289bc588SBarry Smith nz = aij->i[i+1] - aij->i[i]; 132*289bc588SBarry Smith ajtmpold = aij->j + aij->i[i] - 1; 133*289bc588SBarry Smith v = aij->a + aij->i[i] - 1; 134*289bc588SBarry Smith for ( j=0; j<nz; j++ ) rtmp[ic[ajtmpold[j]-1]] = v[i]; 135*289bc588SBarry Smith 136*289bc588SBarry Smith row = *ajtmp++: 137*289bc588SBarry Smith while (row < i) { 138*289bc588SBarry Smith pc = rm 139*289bc588SBarry Smith } 140*289bc588SBarry Smith } 141*289bc588SBarry Smith ISDestroy(isicol); 142*289bc588SBarry Smith 143*289bc588SBarry Smith return 0; 144*289bc588SBarry Smith } 145