16d84be18SBarry Smith 26945ee14SBarry Smith 317ab2063SBarry Smith #ifndef lint 4*026e39d0SSatish Balay static char vcid[] = "$Id: aij.c,v 1.199 1996/12/02 20:20:36 balay Exp balay $"; 517ab2063SBarry Smith #endif 617ab2063SBarry Smith 7d5d45c9bSBarry Smith /* 85a838052SSatish Balay B Defines the basic matrix operations for the AIJ (compressed row) 9d5d45c9bSBarry Smith matrix storage format. 10d5d45c9bSBarry Smith */ 1170f55243SBarry Smith #include "src/mat/impls/aij/seq/aij.h" 12f5eb4b81SSatish Balay #include "src/vec/vecimpl.h" 13f5eb4b81SSatish Balay #include "src/inline/spops.h" 14e4d965acSSatish Balay #include "petsc.h" 15f5eb4b81SSatish Balay #include "src/inline/bitarray.h" 1617ab2063SBarry Smith 17a2ce50c7SBarry Smith /* 18a2ce50c7SBarry Smith Basic AIJ format ILU based on drop tolerance 19a2ce50c7SBarry Smith */ 20*026e39d0SSatish Balay #undef __FUNCTION__ 21*026e39d0SSatish Balay #define __FUNCTION__ "MatILUDTFactor_SeqAIJ" 22a2ce50c7SBarry Smith int MatILUDTFactor_SeqAIJ(Mat A,double dt,int maxnz,IS row,IS col,Mat *fact) 23a2ce50c7SBarry Smith { 24a2ce50c7SBarry Smith /* Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; */ 25a2ce50c7SBarry Smith int ierr = 1; 26a2ce50c7SBarry Smith 27a2ce50c7SBarry Smith SETERRQ(ierr,"MatILUDTFactor_SeqAIJ:Not implemented"); 28a2ce50c7SBarry Smith } 29a2ce50c7SBarry Smith 30bcd2baecSBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**); 3117ab2063SBarry Smith 32*026e39d0SSatish Balay #undef __FUNCTION__ 33*026e39d0SSatish Balay #define __FUNCTION__ "MatGetRowIJ_SeqAIJ" 3431625ec5SSatish Balay static int MatGetRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *m,int **ia,int **ja, 356945ee14SBarry Smith PetscTruth *done) 3617ab2063SBarry Smith { 37416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 386945ee14SBarry Smith int ierr,i,ishift; 3917ab2063SBarry Smith 4031625ec5SSatish Balay *m = A->m; 416945ee14SBarry Smith if (!ia) return 0; 426945ee14SBarry Smith ishift = a->indexshift; 436945ee14SBarry Smith if (symmetric) { 4431625ec5SSatish Balay ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,ishift,oshift,ia,ja); CHKERRQ(ierr); 456945ee14SBarry Smith } else if (oshift == 0 && ishift == -1) { 4631625ec5SSatish Balay int nz = a->i[a->m]; 473b2fbd54SBarry Smith /* malloc space and subtract 1 from i and j indices */ 4831625ec5SSatish Balay *ia = (int *) PetscMalloc( (a->m+1)*sizeof(int) ); CHKPTRQ(*ia); 493b2fbd54SBarry Smith *ja = (int *) PetscMalloc( (nz+1)*sizeof(int) ); CHKPTRQ(*ja); 503b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) (*ja)[i] = a->j[i] - 1; 5131625ec5SSatish Balay for ( i=0; i<a->m+1; i++ ) (*ia)[i] = a->i[i] - 1; 526945ee14SBarry Smith } else if (oshift == 1 && ishift == 0) { 5331625ec5SSatish Balay int nz = a->i[a->m] + 1; 543b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 5531625ec5SSatish Balay *ia = (int *) PetscMalloc( (a->m+1)*sizeof(int) ); CHKPTRQ(*ia); 563b2fbd54SBarry Smith *ja = (int *) PetscMalloc( (nz+1)*sizeof(int) ); CHKPTRQ(*ja); 573b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) (*ja)[i] = a->j[i] + 1; 5831625ec5SSatish Balay for ( i=0; i<a->m+1; i++ ) (*ia)[i] = a->i[i] + 1; 596945ee14SBarry Smith } else { 606945ee14SBarry Smith *ia = a->i; *ja = a->j; 61a2ce50c7SBarry Smith } 62a2ce50c7SBarry Smith 63a2744918SBarry Smith return 0; 64a2744918SBarry Smith } 65a2744918SBarry Smith 66*026e39d0SSatish Balay #undef __FUNCTION__ 67*026e39d0SSatish Balay #define __FUNCTION__ "MatRestoreRowIJ_SeqAIJ" 683b2fbd54SBarry Smith static int MatRestoreRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja, 696945ee14SBarry Smith PetscTruth *done) 706945ee14SBarry Smith { 716945ee14SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 723b2fbd54SBarry Smith int ishift = a->indexshift; 736945ee14SBarry Smith 746945ee14SBarry Smith if (!ia) return 0; 753b2fbd54SBarry Smith if (symmetric || (oshift == 0 && ishift == -1) || (oshift == 1 && ishift == 0)) { 766945ee14SBarry Smith PetscFree(*ia); 776945ee14SBarry Smith PetscFree(*ja); 78bcd2baecSBarry Smith } 7917ab2063SBarry Smith return 0; 8017ab2063SBarry Smith } 8117ab2063SBarry Smith 82*026e39d0SSatish Balay #undef __FUNCTION__ 83*026e39d0SSatish Balay #define __FUNCTION__ "MatGetColumnIJ_SeqAIJ" 8443a90d84SBarry Smith int MatGetColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja, 853b2fbd54SBarry Smith PetscTruth *done) 863b2fbd54SBarry Smith { 873b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 88a93ec695SBarry Smith int ierr,i,ishift = a->indexshift,*collengths,*cia,*cja,n = A->n,m = A->m; 89a93ec695SBarry Smith int nz = a->i[m]+ishift,row,*jj,mr,col; 903b2fbd54SBarry Smith 913b2fbd54SBarry Smith *nn = A->n; 923b2fbd54SBarry Smith if (!ia) return 0; 933b2fbd54SBarry Smith if (symmetric) { 94179192dfSSatish Balay ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,ishift,oshift,ia,ja); CHKERRQ(ierr); 953b2fbd54SBarry Smith } else { 9661d2ded1SBarry Smith collengths = (int *) PetscMalloc( (n+1)*sizeof(int) ); CHKPTRQ(collengths); 973b2fbd54SBarry Smith PetscMemzero(collengths,n*sizeof(int)); 983b2fbd54SBarry Smith cia = (int *) PetscMalloc( (n+1)*sizeof(int) ); CHKPTRQ(cia); 99a93ec695SBarry Smith cja = (int *) PetscMalloc( (nz+1)*sizeof(int) ); CHKPTRQ(cja); 1003b2fbd54SBarry Smith jj = a->j; 1013b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) { 1023b2fbd54SBarry Smith collengths[jj[i] + ishift]++; 1033b2fbd54SBarry Smith } 1043b2fbd54SBarry Smith cia[0] = oshift; 1053b2fbd54SBarry Smith for ( i=0; i<n; i++) { 1063b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 1073b2fbd54SBarry Smith } 1083b2fbd54SBarry Smith PetscMemzero(collengths,n*sizeof(int)); 1093b2fbd54SBarry Smith jj = a->j; 110a93ec695SBarry Smith for ( row=0; row<m; row++ ) { 111a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 112a93ec695SBarry Smith for ( i=0; i<mr; i++ ) { 1133b2fbd54SBarry Smith col = *jj++ + ishift; 1143b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 1153b2fbd54SBarry Smith } 1163b2fbd54SBarry Smith } 1173b2fbd54SBarry Smith PetscFree(collengths); 1183b2fbd54SBarry Smith *ia = cia; *ja = cja; 1193b2fbd54SBarry Smith } 1203b2fbd54SBarry Smith 1213b2fbd54SBarry Smith return 0; 1223b2fbd54SBarry Smith } 1233b2fbd54SBarry Smith 124*026e39d0SSatish Balay #undef __FUNCTION__ 125*026e39d0SSatish Balay #define __FUNCTION__ "MatRestoreColumnIJ_SeqAIJ" 12643a90d84SBarry Smith int MatRestoreColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia, 1273b2fbd54SBarry Smith int **ja,PetscTruth *done) 1283b2fbd54SBarry Smith { 1293b2fbd54SBarry Smith if (!ia) return 0; 1303b2fbd54SBarry Smith 1313b2fbd54SBarry Smith PetscFree(*ia); 1323b2fbd54SBarry Smith PetscFree(*ja); 1333b2fbd54SBarry Smith 1343b2fbd54SBarry Smith return 0; 1353b2fbd54SBarry Smith } 1363b2fbd54SBarry Smith 137227d817aSBarry Smith #define CHUNKSIZE 15 13817ab2063SBarry Smith 139*026e39d0SSatish Balay #undef __FUNCTION__ 140*026e39d0SSatish Balay #define __FUNCTION__ "MatSetValues_SeqAIJ" 14161d2ded1SBarry Smith int MatSetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 14217ab2063SBarry Smith { 143416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 144416022c9SBarry Smith int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax, N, sorted = a->sorted; 1454b0e389bSBarry Smith int *imax = a->imax, *ai = a->i, *ailen = a->ilen,roworiented = a->roworiented; 146d5d45c9bSBarry Smith int *aj = a->j, nonew = a->nonew,shift = a->indexshift; 147416022c9SBarry Smith Scalar *ap,value, *aa = a->a; 14817ab2063SBarry Smith 14917ab2063SBarry Smith for ( k=0; k<m; k++ ) { /* loop over added rows */ 150416022c9SBarry Smith row = im[k]; 1513b2fbd54SBarry Smith #if defined(PETSC_BOPT_g) 15217ab2063SBarry Smith if (row < 0) SETERRQ(1,"MatSetValues_SeqAIJ:Negative row"); 153416022c9SBarry Smith if (row >= a->m) SETERRQ(1,"MatSetValues_SeqAIJ:Row too large"); 1543b2fbd54SBarry Smith #endif 15517ab2063SBarry Smith rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 15617ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 157416022c9SBarry Smith low = 0; 15817ab2063SBarry Smith for ( l=0; l<n; l++ ) { /* loop over added columns */ 1593b2fbd54SBarry Smith #if defined(PETSC_BOPT_g) 160416022c9SBarry Smith if (in[l] < 0) SETERRQ(1,"MatSetValues_SeqAIJ:Negative column"); 161416022c9SBarry Smith if (in[l] >= a->n) SETERRQ(1,"MatSetValues_SeqAIJ:Column too large"); 1623b2fbd54SBarry Smith #endif 1634b0e389bSBarry Smith col = in[l] - shift; 1644b0e389bSBarry Smith if (roworiented) { 1654b0e389bSBarry Smith value = *v++; 1664b0e389bSBarry Smith } 1674b0e389bSBarry Smith else { 1684b0e389bSBarry Smith value = v[k + l*m]; 1694b0e389bSBarry Smith } 170416022c9SBarry Smith if (!sorted) low = 0; high = nrow; 171416022c9SBarry Smith while (high-low > 5) { 172416022c9SBarry Smith t = (low+high)/2; 173416022c9SBarry Smith if (rp[t] > col) high = t; 174416022c9SBarry Smith else low = t; 17517ab2063SBarry Smith } 176416022c9SBarry Smith for ( i=low; i<high; i++ ) { 17717ab2063SBarry Smith if (rp[i] > col) break; 17817ab2063SBarry Smith if (rp[i] == col) { 179416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 18017ab2063SBarry Smith else ap[i] = value; 18117ab2063SBarry Smith goto noinsert; 18217ab2063SBarry Smith } 18317ab2063SBarry Smith } 18417ab2063SBarry Smith if (nonew) goto noinsert; 18517ab2063SBarry Smith if (nrow >= rmax) { 18617ab2063SBarry Smith /* there is no extra room in row, therefore enlarge */ 187416022c9SBarry Smith int new_nz = ai[a->m] + CHUNKSIZE,len,*new_i,*new_j; 18817ab2063SBarry Smith Scalar *new_a; 18917ab2063SBarry Smith 19017ab2063SBarry Smith /* malloc new storage space */ 191416022c9SBarry Smith len = new_nz*(sizeof(int)+sizeof(Scalar))+(a->m+1)*sizeof(int); 1920452661fSBarry Smith new_a = (Scalar *) PetscMalloc( len ); CHKPTRQ(new_a); 19317ab2063SBarry Smith new_j = (int *) (new_a + new_nz); 19417ab2063SBarry Smith new_i = new_j + new_nz; 19517ab2063SBarry Smith 19617ab2063SBarry Smith /* copy over old data into new slots */ 19717ab2063SBarry Smith for ( ii=0; ii<row+1; ii++ ) {new_i[ii] = ai[ii];} 198416022c9SBarry Smith for ( ii=row+1; ii<a->m+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;} 199416022c9SBarry Smith PetscMemcpy(new_j,aj,(ai[row]+nrow+shift)*sizeof(int)); 200416022c9SBarry Smith len = (new_nz - CHUNKSIZE - ai[row] - nrow - shift); 201416022c9SBarry Smith PetscMemcpy(new_j+ai[row]+shift+nrow+CHUNKSIZE,aj+ai[row]+shift+nrow, 20217ab2063SBarry Smith len*sizeof(int)); 203416022c9SBarry Smith PetscMemcpy(new_a,aa,(ai[row]+nrow+shift)*sizeof(Scalar)); 204416022c9SBarry Smith PetscMemcpy(new_a+ai[row]+shift+nrow+CHUNKSIZE,aa+ai[row]+shift+nrow, 20517ab2063SBarry Smith len*sizeof(Scalar)); 20617ab2063SBarry Smith /* free up old matrix storage */ 2070452661fSBarry Smith PetscFree(a->a); 2080452661fSBarry Smith if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);} 209416022c9SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 210416022c9SBarry Smith a->singlemalloc = 1; 21117ab2063SBarry Smith 21217ab2063SBarry Smith rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 213416022c9SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 214416022c9SBarry Smith PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + sizeof(Scalar))); 215416022c9SBarry Smith a->maxnz += CHUNKSIZE; 216b810aeb4SBarry Smith a->reallocs++; 21717ab2063SBarry Smith } 218416022c9SBarry Smith N = nrow++ - 1; a->nz++; 219416022c9SBarry Smith /* shift up all the later entries in this row */ 220416022c9SBarry Smith for ( ii=N; ii>=i; ii-- ) { 22117ab2063SBarry Smith rp[ii+1] = rp[ii]; 22217ab2063SBarry Smith ap[ii+1] = ap[ii]; 22317ab2063SBarry Smith } 22417ab2063SBarry Smith rp[i] = col; 22517ab2063SBarry Smith ap[i] = value; 22617ab2063SBarry Smith noinsert:; 227416022c9SBarry Smith low = i + 1; 22817ab2063SBarry Smith } 22917ab2063SBarry Smith ailen[row] = nrow; 23017ab2063SBarry Smith } 23117ab2063SBarry Smith return 0; 23217ab2063SBarry Smith } 23317ab2063SBarry Smith 234*026e39d0SSatish Balay #undef __FUNCTION__ 235*026e39d0SSatish Balay #define __FUNCTION__ "MatGetValues_SeqAIJ" 2367eb43aa7SLois Curfman McInnes static int MatGetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v) 2377eb43aa7SLois Curfman McInnes { 2387eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 239b49de8d1SLois Curfman McInnes int *rp, k, low, high, t, row, nrow, i, col, l, *aj = a->j; 2407eb43aa7SLois Curfman McInnes int *ai = a->i, *ailen = a->ilen, shift = a->indexshift; 2417eb43aa7SLois Curfman McInnes Scalar *ap, *aa = a->a, zero = 0.0; 2427eb43aa7SLois Curfman McInnes 2437eb43aa7SLois Curfman McInnes for ( k=0; k<m; k++ ) { /* loop over rows */ 2447eb43aa7SLois Curfman McInnes row = im[k]; 2457eb43aa7SLois Curfman McInnes if (row < 0) SETERRQ(1,"MatGetValues_SeqAIJ:Negative row"); 2467eb43aa7SLois Curfman McInnes if (row >= a->m) SETERRQ(1,"MatGetValues_SeqAIJ:Row too large"); 2477eb43aa7SLois Curfman McInnes rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 2487eb43aa7SLois Curfman McInnes nrow = ailen[row]; 2497eb43aa7SLois Curfman McInnes for ( l=0; l<n; l++ ) { /* loop over columns */ 2507eb43aa7SLois Curfman McInnes if (in[l] < 0) SETERRQ(1,"MatGetValues_SeqAIJ:Negative column"); 2517eb43aa7SLois Curfman McInnes if (in[l] >= a->n) SETERRQ(1,"MatGetValues_SeqAIJ:Column too large"); 2527eb43aa7SLois Curfman McInnes col = in[l] - shift; 2537eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 2547eb43aa7SLois Curfman McInnes while (high-low > 5) { 2557eb43aa7SLois Curfman McInnes t = (low+high)/2; 2567eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 2577eb43aa7SLois Curfman McInnes else low = t; 2587eb43aa7SLois Curfman McInnes } 2597eb43aa7SLois Curfman McInnes for ( i=low; i<high; i++ ) { 2607eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 2617eb43aa7SLois Curfman McInnes if (rp[i] == col) { 262b49de8d1SLois Curfman McInnes *v++ = ap[i]; 2637eb43aa7SLois Curfman McInnes goto finished; 2647eb43aa7SLois Curfman McInnes } 2657eb43aa7SLois Curfman McInnes } 266b49de8d1SLois Curfman McInnes *v++ = zero; 2677eb43aa7SLois Curfman McInnes finished:; 2687eb43aa7SLois Curfman McInnes } 2697eb43aa7SLois Curfman McInnes } 2707eb43aa7SLois Curfman McInnes return 0; 2717eb43aa7SLois Curfman McInnes } 2727eb43aa7SLois Curfman McInnes 27317ab2063SBarry Smith #include "draw.h" 27417ab2063SBarry Smith #include "pinclude/pviewer.h" 27577c4ece6SBarry Smith #include "sys.h" 27617ab2063SBarry Smith 277*026e39d0SSatish Balay #undef __FUNCTION__ 278*026e39d0SSatish Balay #define __FUNCTION__ "MatView_SeqAIJ_Binary" 279416022c9SBarry Smith static int MatView_SeqAIJ_Binary(Mat A,Viewer viewer) 28017ab2063SBarry Smith { 281416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 282416022c9SBarry Smith int i, fd, *col_lens, ierr; 28317ab2063SBarry Smith 28490ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 2850452661fSBarry Smith col_lens = (int *) PetscMalloc( (4+a->m)*sizeof(int) ); CHKPTRQ(col_lens); 286416022c9SBarry Smith col_lens[0] = MAT_COOKIE; 287416022c9SBarry Smith col_lens[1] = a->m; 288416022c9SBarry Smith col_lens[2] = a->n; 289416022c9SBarry Smith col_lens[3] = a->nz; 290416022c9SBarry Smith 291416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 292416022c9SBarry Smith for ( i=0; i<a->m; i++ ) { 293416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 29417ab2063SBarry Smith } 29577c4ece6SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+a->m,BINARY_INT,1); CHKERRQ(ierr); 2960452661fSBarry Smith PetscFree(col_lens); 297416022c9SBarry Smith 298416022c9SBarry Smith /* store column indices (zero start index) */ 299416022c9SBarry Smith if (a->indexshift) { 300416022c9SBarry Smith for ( i=0; i<a->nz; i++ ) a->j[i]--; 30117ab2063SBarry Smith } 30277c4ece6SBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,BINARY_INT,0); CHKERRQ(ierr); 303416022c9SBarry Smith if (a->indexshift) { 304416022c9SBarry Smith for ( i=0; i<a->nz; i++ ) a->j[i]++; 30517ab2063SBarry Smith } 306416022c9SBarry Smith 307416022c9SBarry Smith /* store nonzero values */ 30877c4ece6SBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,BINARY_SCALAR,0); CHKERRQ(ierr); 30917ab2063SBarry Smith return 0; 31017ab2063SBarry Smith } 311416022c9SBarry Smith 312*026e39d0SSatish Balay #undef __FUNCTION__ 313*026e39d0SSatish Balay #define __FUNCTION__ "MatView_SeqAIJ_ASCII" 314416022c9SBarry Smith static int MatView_SeqAIJ_ASCII(Mat A,Viewer viewer) 315416022c9SBarry Smith { 316416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 317496e697eSBarry Smith int ierr, i,j, m = a->m, shift = a->indexshift, format, flg1,flg2; 31817ab2063SBarry Smith FILE *fd; 31917ab2063SBarry Smith char *outputname; 32017ab2063SBarry Smith 32190ace30eSBarry Smith ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr); 322416022c9SBarry Smith ierr = ViewerFileGetOutputname_Private(viewer,&outputname); CHKERRQ(ierr); 32390ace30eSBarry Smith ierr = ViewerGetFormat(viewer,&format); 324a93ec695SBarry Smith if (format == VIEWER_FORMAT_ASCII_INFO) { 32595e01e2fSLois Curfman McInnes return 0; 32695e01e2fSLois Curfman McInnes } 327a93ec695SBarry Smith else if (format == VIEWER_FORMAT_ASCII_INFO_LONG) { 328496e697eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_aij_no_inode",&flg1); CHKERRQ(ierr); 329496e697eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg2); CHKERRQ(ierr); 330496e697eSBarry Smith if (flg1 || flg2) fprintf(fd," not using I-node routines\n"); 33195e01e2fSLois Curfman McInnes else fprintf(fd," using I-node routines: found %d nodes, limit used is %d\n", 33295e01e2fSLois Curfman McInnes a->inode.node_count,a->inode.limit); 33317ab2063SBarry Smith } 334a93ec695SBarry Smith else if (format == VIEWER_FORMAT_ASCII_MATLAB) { 335416022c9SBarry Smith fprintf(fd,"%% Size = %d %d \n",m,a->n); 3364e220ebcSLois Curfman McInnes fprintf(fd,"%% Nonzeros = %d \n",a->nz); 3374e220ebcSLois Curfman McInnes fprintf(fd,"zzz = zeros(%d,3);\n",a->nz); 33817ab2063SBarry Smith fprintf(fd,"zzz = [\n"); 33917ab2063SBarry Smith 34017ab2063SBarry Smith for (i=0; i<m; i++) { 341416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 34217ab2063SBarry Smith #if defined(PETSC_COMPLEX) 3436945ee14SBarry Smith fprintf(fd,"%d %d %18.16e + %18.16e i \n",i+1,a->j[j]+!shift,real(a->a[j]), 344416022c9SBarry Smith imag(a->a[j])); 34517ab2063SBarry Smith #else 3467a743949SBarry Smith fprintf(fd,"%d %d %18.16e\n", i+1, a->j[j]+!shift, a->a[j]); 34717ab2063SBarry Smith #endif 34817ab2063SBarry Smith } 34917ab2063SBarry Smith } 35017ab2063SBarry Smith fprintf(fd,"];\n %s = spconvert(zzz);\n",outputname); 35117ab2063SBarry Smith } 352a93ec695SBarry Smith else if (format == VIEWER_FORMAT_ASCII_COMMON) { 35344cd7ae7SLois Curfman McInnes for ( i=0; i<m; i++ ) { 35444cd7ae7SLois Curfman McInnes fprintf(fd,"row %d:",i); 35544cd7ae7SLois Curfman McInnes for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 35644cd7ae7SLois Curfman McInnes #if defined(PETSC_COMPLEX) 35744cd7ae7SLois Curfman McInnes if (imag(a->a[j]) != 0.0 && real(a->a[j]) != 0.0) 35844cd7ae7SLois Curfman McInnes fprintf(fd," %d %g + %g i",a->j[j]+shift,real(a->a[j]),imag(a->a[j])); 35944cd7ae7SLois Curfman McInnes else if (real(a->a[j]) != 0.0) 36044cd7ae7SLois Curfman McInnes fprintf(fd," %d %g ",a->j[j]+shift,real(a->a[j])); 36144cd7ae7SLois Curfman McInnes #else 36244cd7ae7SLois Curfman McInnes if (a->a[j] != 0.0) fprintf(fd," %d %g ",a->j[j]+shift,a->a[j]); 36344cd7ae7SLois Curfman McInnes #endif 36444cd7ae7SLois Curfman McInnes } 36544cd7ae7SLois Curfman McInnes fprintf(fd,"\n"); 36644cd7ae7SLois Curfman McInnes } 36744cd7ae7SLois Curfman McInnes } 36817ab2063SBarry Smith else { 36917ab2063SBarry Smith for ( i=0; i<m; i++ ) { 37017ab2063SBarry Smith fprintf(fd,"row %d:",i); 371416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 37217ab2063SBarry Smith #if defined(PETSC_COMPLEX) 373416022c9SBarry Smith if (imag(a->a[j]) != 0.0) { 374416022c9SBarry Smith fprintf(fd," %d %g + %g i",a->j[j]+shift,real(a->a[j]),imag(a->a[j])); 37517ab2063SBarry Smith } 37617ab2063SBarry Smith else { 377416022c9SBarry Smith fprintf(fd," %d %g ",a->j[j]+shift,real(a->a[j])); 37817ab2063SBarry Smith } 37917ab2063SBarry Smith #else 380416022c9SBarry Smith fprintf(fd," %d %g ",a->j[j]+shift,a->a[j]); 38117ab2063SBarry Smith #endif 38217ab2063SBarry Smith } 38317ab2063SBarry Smith fprintf(fd,"\n"); 38417ab2063SBarry Smith } 38517ab2063SBarry Smith } 38617ab2063SBarry Smith fflush(fd); 387416022c9SBarry Smith return 0; 388416022c9SBarry Smith } 389416022c9SBarry Smith 390*026e39d0SSatish Balay #undef __FUNCTION__ 391*026e39d0SSatish Balay #define __FUNCTION__ "MatView_SeqAIJ_Draw" 392416022c9SBarry Smith static int MatView_SeqAIJ_Draw(Mat A,Viewer viewer) 393416022c9SBarry Smith { 394416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 395cddf8d76SBarry Smith int ierr, i,j, m = a->m, shift = a->indexshift,pause,color; 396cddf8d76SBarry Smith double xl,yl,xr,yr,w,h,xc,yc,scale = 1.0,x_l,x_r,y_l,y_r; 397bcd2baecSBarry Smith Draw draw; 398cddf8d76SBarry Smith DrawButton button; 39919bcc07fSBarry Smith PetscTruth isnull; 400cddf8d76SBarry Smith 401bcd2baecSBarry Smith ViewerDrawGetDraw(viewer,&draw); 40219bcc07fSBarry Smith ierr = DrawIsNull(draw,&isnull); CHKERRQ(ierr); if (isnull) return 0; 40319bcc07fSBarry Smith 404416022c9SBarry Smith xr = a->n; yr = a->m; h = yr/10.0; w = xr/10.0; 405416022c9SBarry Smith xr += w; yr += h; xl = -w; yl = -h; 406416022c9SBarry Smith ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr); 407416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 408cddf8d76SBarry Smith color = DRAW_BLUE; 409416022c9SBarry Smith for ( i=0; i<m; i++ ) { 410cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 411416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 412cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 413cddf8d76SBarry Smith #if defined(PETSC_COMPLEX) 414cddf8d76SBarry Smith if (real(a->a[j]) >= 0.) continue; 415cddf8d76SBarry Smith #else 416cddf8d76SBarry Smith if (a->a[j] >= 0.) continue; 417cddf8d76SBarry Smith #endif 418cddf8d76SBarry Smith DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color); 419cddf8d76SBarry Smith } 420cddf8d76SBarry Smith } 421cddf8d76SBarry Smith color = DRAW_CYAN; 422cddf8d76SBarry Smith for ( i=0; i<m; i++ ) { 423cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 424cddf8d76SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 425cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 426cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 427cddf8d76SBarry Smith DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color); 428cddf8d76SBarry Smith } 429cddf8d76SBarry Smith } 430cddf8d76SBarry Smith color = DRAW_RED; 431cddf8d76SBarry Smith for ( i=0; i<m; i++ ) { 432cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 433cddf8d76SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 434cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 435cddf8d76SBarry Smith #if defined(PETSC_COMPLEX) 436cddf8d76SBarry Smith if (real(a->a[j]) <= 0.) continue; 437cddf8d76SBarry Smith #else 438cddf8d76SBarry Smith if (a->a[j] <= 0.) continue; 439cddf8d76SBarry Smith #endif 440cddf8d76SBarry Smith DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color); 441416022c9SBarry Smith } 442416022c9SBarry Smith } 443416022c9SBarry Smith DrawFlush(draw); 444cddf8d76SBarry Smith DrawGetPause(draw,&pause); 445cddf8d76SBarry Smith if (pause >= 0) { PetscSleep(pause); return 0;} 446cddf8d76SBarry Smith 447cddf8d76SBarry Smith /* allow the matrix to zoom or shrink */ 4486945ee14SBarry Smith ierr = DrawCheckResizedWindow(draw); 449cddf8d76SBarry Smith ierr = DrawGetMouseButton(draw,&button,&xc,&yc,0,0); 450cddf8d76SBarry Smith while (button != BUTTON_RIGHT) { 451cddf8d76SBarry Smith DrawClear(draw); 452cddf8d76SBarry Smith if (button == BUTTON_LEFT) scale = .5; 453cddf8d76SBarry Smith else if (button == BUTTON_CENTER) scale = 2.; 454cddf8d76SBarry Smith xl = scale*(xl + w - xc) + xc - w*scale; 455cddf8d76SBarry Smith xr = scale*(xr - w - xc) + xc + w*scale; 456cddf8d76SBarry Smith yl = scale*(yl + h - yc) + yc - h*scale; 457cddf8d76SBarry Smith yr = scale*(yr - h - yc) + yc + h*scale; 458cddf8d76SBarry Smith w *= scale; h *= scale; 459cddf8d76SBarry Smith ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr); 460cddf8d76SBarry Smith color = DRAW_BLUE; 461cddf8d76SBarry Smith for ( i=0; i<m; i++ ) { 462cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 463cddf8d76SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 464cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 465cddf8d76SBarry Smith #if defined(PETSC_COMPLEX) 466cddf8d76SBarry Smith if (real(a->a[j]) >= 0.) continue; 467cddf8d76SBarry Smith #else 468cddf8d76SBarry Smith if (a->a[j] >= 0.) continue; 469cddf8d76SBarry Smith #endif 470cddf8d76SBarry Smith DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color); 471cddf8d76SBarry Smith } 472cddf8d76SBarry Smith } 473cddf8d76SBarry Smith color = DRAW_CYAN; 474cddf8d76SBarry Smith for ( i=0; i<m; i++ ) { 475cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 476cddf8d76SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 477cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 478cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 479cddf8d76SBarry Smith DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color); 480cddf8d76SBarry Smith } 481cddf8d76SBarry Smith } 482cddf8d76SBarry Smith color = DRAW_RED; 483cddf8d76SBarry Smith for ( i=0; i<m; i++ ) { 484cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 485cddf8d76SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 486cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 487cddf8d76SBarry Smith #if defined(PETSC_COMPLEX) 488cddf8d76SBarry Smith if (real(a->a[j]) <= 0.) continue; 489cddf8d76SBarry Smith #else 490cddf8d76SBarry Smith if (a->a[j] <= 0.) continue; 491cddf8d76SBarry Smith #endif 492cddf8d76SBarry Smith DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color); 493cddf8d76SBarry Smith } 494cddf8d76SBarry Smith } 4956945ee14SBarry Smith ierr = DrawCheckResizedWindow(draw); 496cddf8d76SBarry Smith ierr = DrawGetMouseButton(draw,&button,&xc,&yc,0,0); 497cddf8d76SBarry Smith } 498416022c9SBarry Smith return 0; 499416022c9SBarry Smith } 500416022c9SBarry Smith 501*026e39d0SSatish Balay #undef __FUNCTION__ 502*026e39d0SSatish Balay #define __FUNCTION__ "MatView_SeqAIJ" 503416022c9SBarry Smith static int MatView_SeqAIJ(PetscObject obj,Viewer viewer) 504416022c9SBarry Smith { 505416022c9SBarry Smith Mat A = (Mat) obj; 506416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 507bcd2baecSBarry Smith ViewerType vtype; 508bcd2baecSBarry Smith int ierr; 509416022c9SBarry Smith 510bcd2baecSBarry Smith ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 511bcd2baecSBarry Smith if (vtype == MATLAB_VIEWER) { 512416022c9SBarry Smith return ViewerMatlabPutSparse_Private(viewer,a->m,a->n,a->nz,a->a,a->i,a->j); 513416022c9SBarry Smith } 514bcd2baecSBarry Smith else if (vtype == ASCII_FILE_VIEWER || vtype == ASCII_FILES_VIEWER){ 515416022c9SBarry Smith return MatView_SeqAIJ_ASCII(A,viewer); 516416022c9SBarry Smith } 517bcd2baecSBarry Smith else if (vtype == BINARY_FILE_VIEWER) { 518416022c9SBarry Smith return MatView_SeqAIJ_Binary(A,viewer); 519416022c9SBarry Smith } 520bcd2baecSBarry Smith else if (vtype == DRAW_VIEWER) { 521bcd2baecSBarry Smith return MatView_SeqAIJ_Draw(A,viewer); 52217ab2063SBarry Smith } 52317ab2063SBarry Smith return 0; 52417ab2063SBarry Smith } 52519bcc07fSBarry Smith 526c456f294SBarry Smith extern int Mat_AIJ_CheckInode(Mat); 527*026e39d0SSatish Balay #undef __FUNCTION__ 528*026e39d0SSatish Balay #define __FUNCTION__ "MatAssemblyEnd_SeqAIJ" 529416022c9SBarry Smith static int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 53017ab2063SBarry Smith { 531416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 53241c01911SSatish Balay int fshift = 0,i,j,*ai = a->i, *aj = a->j, *imax = a->imax,ierr; 533416022c9SBarry Smith int m = a->m, *ip, N, *ailen = a->ilen,shift = a->indexshift; 534416022c9SBarry Smith Scalar *aa = a->a, *ap; 53517ab2063SBarry Smith 5366d4a8577SBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) return 0; 53717ab2063SBarry Smith 53817ab2063SBarry Smith for ( i=1; i<m; i++ ) { 539416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 54017ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 54117ab2063SBarry Smith if (fshift) { 542416022c9SBarry Smith ip = aj + ai[i] + shift; ap = aa + ai[i] + shift; 54317ab2063SBarry Smith N = ailen[i]; 54417ab2063SBarry Smith for ( j=0; j<N; j++ ) { 54517ab2063SBarry Smith ip[j-fshift] = ip[j]; 54617ab2063SBarry Smith ap[j-fshift] = ap[j]; 54717ab2063SBarry Smith } 54817ab2063SBarry Smith } 54917ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 55017ab2063SBarry Smith } 55117ab2063SBarry Smith if (m) { 55217ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 55317ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 55417ab2063SBarry Smith } 55517ab2063SBarry Smith /* reset ilen and imax for each row */ 55617ab2063SBarry Smith for ( i=0; i<m; i++ ) { 55717ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 55817ab2063SBarry Smith } 559416022c9SBarry Smith a->nz = ai[m] + shift; 56017ab2063SBarry Smith 56117ab2063SBarry Smith /* diagonals may have moved, so kill the diagonal pointers */ 562416022c9SBarry Smith if (fshift && a->diag) { 5630452661fSBarry Smith PetscFree(a->diag); 564416022c9SBarry Smith PLogObjectMemory(A,-(m+1)*sizeof(int)); 565416022c9SBarry Smith a->diag = 0; 56617ab2063SBarry Smith } 5674e220ebcSLois Curfman McInnes PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded, %d used\n", 5684e220ebcSLois Curfman McInnes m,a->n,fshift,a->nz); 5694e220ebcSLois Curfman McInnes PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues is %d\n", 570b810aeb4SBarry Smith a->reallocs); 571dd5f02e7SSatish Balay a->reallocs = 0; 5724e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift; 5734e220ebcSLois Curfman McInnes 57476dd722bSSatish Balay /* check out for identical nodes. If found, use inode functions */ 57541c01911SSatish Balay ierr = Mat_AIJ_CheckInode(A); CHKERRQ(ierr); 57617ab2063SBarry Smith return 0; 57717ab2063SBarry Smith } 57817ab2063SBarry Smith 579*026e39d0SSatish Balay #undef __FUNCTION__ 580*026e39d0SSatish Balay #define __FUNCTION__ "MatZeroEntries_SeqAIJ" 581416022c9SBarry Smith static int MatZeroEntries_SeqAIJ(Mat A) 58217ab2063SBarry Smith { 583416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 584cddf8d76SBarry Smith PetscMemzero(a->a,(a->i[a->m]+a->indexshift)*sizeof(Scalar)); 58517ab2063SBarry Smith return 0; 58617ab2063SBarry Smith } 587416022c9SBarry Smith 588*026e39d0SSatish Balay #undef __FUNCTION__ 589*026e39d0SSatish Balay #define __FUNCTION__ "MatDestroy_SeqAIJ" 59017ab2063SBarry Smith int MatDestroy_SeqAIJ(PetscObject obj) 59117ab2063SBarry Smith { 592416022c9SBarry Smith Mat A = (Mat) obj; 593416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 59490f02eecSBarry Smith int ierr; 595d5d45c9bSBarry Smith 59617ab2063SBarry Smith #if defined(PETSC_LOG) 597416022c9SBarry Smith PLogObjectState(obj,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz); 59817ab2063SBarry Smith #endif 5990452661fSBarry Smith PetscFree(a->a); 6000452661fSBarry Smith if (!a->singlemalloc) { PetscFree(a->i); PetscFree(a->j);} 6010452661fSBarry Smith if (a->diag) PetscFree(a->diag); 6020452661fSBarry Smith if (a->ilen) PetscFree(a->ilen); 6030452661fSBarry Smith if (a->imax) PetscFree(a->imax); 6040452661fSBarry Smith if (a->solve_work) PetscFree(a->solve_work); 60576dd722bSSatish Balay if (a->inode.size) PetscFree(a->inode.size); 6060452661fSBarry Smith PetscFree(a); 60790f02eecSBarry Smith if (A->mapping) { 60890f02eecSBarry Smith ierr = ISLocalToGlobalMappingDestroy(A->mapping); CHKERRQ(ierr); 60990f02eecSBarry Smith } 610f2655603SLois Curfman McInnes PLogObjectDestroy(A); 611f2655603SLois Curfman McInnes PetscHeaderDestroy(A); 61217ab2063SBarry Smith return 0; 61317ab2063SBarry Smith } 61417ab2063SBarry Smith 615*026e39d0SSatish Balay #undef __FUNCTION__ 616*026e39d0SSatish Balay #define __FUNCTION__ "MatCompress_SeqAIJ" 617416022c9SBarry Smith static int MatCompress_SeqAIJ(Mat A) 61817ab2063SBarry Smith { 61917ab2063SBarry Smith return 0; 62017ab2063SBarry Smith } 62117ab2063SBarry Smith 622*026e39d0SSatish Balay #undef __FUNCTION__ 623*026e39d0SSatish Balay #define __FUNCTION__ "MatSetOption_SeqAIJ" 624416022c9SBarry Smith static int MatSetOption_SeqAIJ(Mat A,MatOption op) 62517ab2063SBarry Smith { 626416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 6276d4a8577SBarry Smith if (op == MAT_ROW_ORIENTED) a->roworiented = 1; 6286d4a8577SBarry Smith else if (op == MAT_COLUMN_ORIENTED) a->roworiented = 0; 6296d4a8577SBarry Smith else if (op == MAT_COLUMNS_SORTED) a->sorted = 1; 630219d9a1aSLois Curfman McInnes else if (op == MAT_COLUMNS_UNSORTED) a->sorted = 0; 6316d4a8577SBarry Smith else if (op == MAT_NO_NEW_NONZERO_LOCATIONS) a->nonew = 1; 6326d4a8577SBarry Smith else if (op == MAT_YES_NEW_NONZERO_LOCATIONS) a->nonew = 0; 6336d4a8577SBarry Smith else if (op == MAT_ROWS_SORTED || 634219d9a1aSLois Curfman McInnes op == MAT_ROWS_UNSORTED || 6356d4a8577SBarry Smith op == MAT_SYMMETRIC || 6366d4a8577SBarry Smith op == MAT_STRUCTURALLY_SYMMETRIC || 63790f02eecSBarry Smith op == MAT_YES_NEW_DIAGONALS || 63890f02eecSBarry Smith op == MAT_IGNORE_OFF_PROCESSOR_ENTRIES) 63994a424c1SBarry Smith PLogInfo(A,"Info:MatSetOption_SeqAIJ:Option ignored\n"); 6406d4a8577SBarry Smith else if (op == MAT_NO_NEW_DIAGONALS) 6416d4a8577SBarry Smith {SETERRQ(PETSC_ERR_SUP,"MatSetOption_SeqAIJ:MAT_NO_NEW_DIAGONALS");} 6426d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_1) a->inode.limit = 1; 6436d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_2) a->inode.limit = 2; 6446d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_3) a->inode.limit = 3; 6456d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_4) a->inode.limit = 4; 6466d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_5) a->inode.limit = 5; 647e2f28af5SBarry Smith else 6484d39ef84SLois Curfman McInnes {SETERRQ(PETSC_ERR_SUP,"MatSetOption_SeqAIJ:unknown option");} 64917ab2063SBarry Smith return 0; 65017ab2063SBarry Smith } 65117ab2063SBarry Smith 652*026e39d0SSatish Balay #undef __FUNCTION__ 653*026e39d0SSatish Balay #define __FUNCTION__ "MatGetDiagonal_SeqAIJ" 654416022c9SBarry Smith static int MatGetDiagonal_SeqAIJ(Mat A,Vec v) 65517ab2063SBarry Smith { 656416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 657416022c9SBarry Smith int i,j, n,shift = a->indexshift; 65817ab2063SBarry Smith Scalar *x, zero = 0.0; 65917ab2063SBarry Smith 66017ab2063SBarry Smith VecSet(&zero,v); 66190f02eecSBarry Smith VecGetArray_Fast(v,x); VecGetLocalSize(v,&n); 662416022c9SBarry Smith if (n != a->m) SETERRQ(1,"MatGetDiagonal_SeqAIJ:Nonconforming matrix and vector"); 663416022c9SBarry Smith for ( i=0; i<a->m; i++ ) { 664416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 665416022c9SBarry Smith if (a->j[j]+shift == i) { 666416022c9SBarry Smith x[i] = a->a[j]; 66717ab2063SBarry Smith break; 66817ab2063SBarry Smith } 66917ab2063SBarry Smith } 67017ab2063SBarry Smith } 67117ab2063SBarry Smith return 0; 67217ab2063SBarry Smith } 67317ab2063SBarry Smith 67417ab2063SBarry Smith /* -------------------------------------------------------*/ 67517ab2063SBarry Smith /* Should check that shapes of vectors and matrices match */ 67617ab2063SBarry Smith /* -------------------------------------------------------*/ 677*026e39d0SSatish Balay #undef __FUNCTION__ 678*026e39d0SSatish Balay #define __FUNCTION__ "MatMultTrans_SeqAIJ" 67944cd7ae7SLois Curfman McInnes int MatMultTrans_SeqAIJ(Mat A,Vec xx,Vec yy) 68017ab2063SBarry Smith { 681416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 68217ab2063SBarry Smith Scalar *x, *y, *v, alpha; 683416022c9SBarry Smith int m = a->m, n, i, *idx, shift = a->indexshift; 68417ab2063SBarry Smith 68590f02eecSBarry Smith VecGetArray_Fast(xx,x); VecGetArray_Fast(yy,y); 686cddf8d76SBarry Smith PetscMemzero(y,a->n*sizeof(Scalar)); 68717ab2063SBarry Smith y = y + shift; /* shift for Fortran start by 1 indexing */ 68817ab2063SBarry Smith for ( i=0; i<m; i++ ) { 689416022c9SBarry Smith idx = a->j + a->i[i] + shift; 690416022c9SBarry Smith v = a->a + a->i[i] + shift; 691416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 69217ab2063SBarry Smith alpha = x[i]; 69317ab2063SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 69417ab2063SBarry Smith } 695416022c9SBarry Smith PLogFlops(2*a->nz - a->n); 69617ab2063SBarry Smith return 0; 69717ab2063SBarry Smith } 698d5d45c9bSBarry Smith 699*026e39d0SSatish Balay #undef __FUNCTION__ 700*026e39d0SSatish Balay #define __FUNCTION__ "MatMultTransAdd_SeqAIJ" 70144cd7ae7SLois Curfman McInnes int MatMultTransAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 70217ab2063SBarry Smith { 703416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 70417ab2063SBarry Smith Scalar *x, *y, *v, alpha; 705416022c9SBarry Smith int m = a->m, n, i, *idx,shift = a->indexshift; 70617ab2063SBarry Smith 70790f02eecSBarry Smith VecGetArray_Fast(xx,x); VecGetArray_Fast(yy,y); 70817ab2063SBarry Smith if (zz != yy) VecCopy(zz,yy); 70917ab2063SBarry Smith y = y + shift; /* shift for Fortran start by 1 indexing */ 71017ab2063SBarry Smith for ( i=0; i<m; i++ ) { 711416022c9SBarry Smith idx = a->j + a->i[i] + shift; 712416022c9SBarry Smith v = a->a + a->i[i] + shift; 713416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 71417ab2063SBarry Smith alpha = x[i]; 71517ab2063SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 71617ab2063SBarry Smith } 71790f02eecSBarry Smith PLogFlops(2*a->nz); 71817ab2063SBarry Smith return 0; 71917ab2063SBarry Smith } 72017ab2063SBarry Smith 721*026e39d0SSatish Balay #undef __FUNCTION__ 722*026e39d0SSatish Balay #define __FUNCTION__ "MatMult_SeqAIJ" 72344cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 72417ab2063SBarry Smith { 725416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 72617ab2063SBarry Smith Scalar *x, *y, *v, sum; 727416022c9SBarry Smith int m = a->m, n, i, *idx, shift = a->indexshift,*ii; 72817ab2063SBarry Smith 72990f02eecSBarry Smith VecGetArray_Fast(xx,x); VecGetArray_Fast(yy,y); 73017ab2063SBarry Smith x = x + shift; /* shift for Fortran start by 1 indexing */ 731416022c9SBarry Smith idx = a->j; 732416022c9SBarry Smith v = a->a; 733416022c9SBarry Smith ii = a->i; 73417ab2063SBarry Smith for ( i=0; i<m; i++ ) { 735416022c9SBarry Smith n = ii[1] - ii[0]; ii++; 73617ab2063SBarry Smith sum = 0.0; 73717ab2063SBarry Smith /* SPARSEDENSEDOT(sum,x,v,idx,n); */ 73817ab2063SBarry Smith /* for ( j=n-1; j>-1; j--) sum += v[j]*x[idx[j]]; */ 739416022c9SBarry Smith while (n--) sum += *v++ * x[*idx++]; 74017ab2063SBarry Smith y[i] = sum; 74117ab2063SBarry Smith } 742416022c9SBarry Smith PLogFlops(2*a->nz - m); 74317ab2063SBarry Smith return 0; 74417ab2063SBarry Smith } 74517ab2063SBarry Smith 746*026e39d0SSatish Balay #undef __FUNCTION__ 747*026e39d0SSatish Balay #define __FUNCTION__ "MatMultAdd_SeqAIJ" 74844cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 74917ab2063SBarry Smith { 750416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 75117ab2063SBarry Smith Scalar *x, *y, *z, *v, sum; 752cddf8d76SBarry Smith int m = a->m, n, i, *idx, shift = a->indexshift,*ii; 75317ab2063SBarry Smith 75490f02eecSBarry Smith VecGetArray_Fast(xx,x); VecGetArray_Fast(yy,y); VecGetArray_Fast(zz,z); 75517ab2063SBarry Smith x = x + shift; /* shift for Fortran start by 1 indexing */ 756cddf8d76SBarry Smith idx = a->j; 757cddf8d76SBarry Smith v = a->a; 758cddf8d76SBarry Smith ii = a->i; 75917ab2063SBarry Smith for ( i=0; i<m; i++ ) { 760cddf8d76SBarry Smith n = ii[1] - ii[0]; ii++; 76117ab2063SBarry Smith sum = y[i]; 762cddf8d76SBarry Smith /* SPARSEDENSEDOT(sum,x,v,idx,n); */ 763cddf8d76SBarry Smith while (n--) sum += *v++ * x[*idx++]; 76417ab2063SBarry Smith z[i] = sum; 76517ab2063SBarry Smith } 766416022c9SBarry Smith PLogFlops(2*a->nz); 76717ab2063SBarry Smith return 0; 76817ab2063SBarry Smith } 76917ab2063SBarry Smith 77017ab2063SBarry Smith /* 77117ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 77217ab2063SBarry Smith */ 77317ab2063SBarry Smith 774*026e39d0SSatish Balay #undef __FUNCTION__ 775*026e39d0SSatish Balay #define __FUNCTION__ "MatMarkDiag_SeqAIJ" 776416022c9SBarry Smith int MatMarkDiag_SeqAIJ(Mat A) 77717ab2063SBarry Smith { 778416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 779416022c9SBarry Smith int i,j, *diag, m = a->m,shift = a->indexshift; 78017ab2063SBarry Smith 7810452661fSBarry Smith diag = (int *) PetscMalloc( (m+1)*sizeof(int)); CHKPTRQ(diag); 782416022c9SBarry Smith PLogObjectMemory(A,(m+1)*sizeof(int)); 783416022c9SBarry Smith for ( i=0; i<a->m; i++ ) { 784416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 785416022c9SBarry Smith if (a->j[j]+shift == i) { 78617ab2063SBarry Smith diag[i] = j - shift; 78717ab2063SBarry Smith break; 78817ab2063SBarry Smith } 78917ab2063SBarry Smith } 79017ab2063SBarry Smith } 791416022c9SBarry Smith a->diag = diag; 79217ab2063SBarry Smith return 0; 79317ab2063SBarry Smith } 79417ab2063SBarry Smith 795*026e39d0SSatish Balay #undef __FUNCTION__ 796*026e39d0SSatish Balay #define __FUNCTION__ "MatRelax_SeqAIJ" 79744cd7ae7SLois Curfman McInnes int MatRelax_SeqAIJ(Mat A,Vec bb,double omega,MatSORType flag, 79817ab2063SBarry Smith double fshift,int its,Vec xx) 79917ab2063SBarry Smith { 800416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 801416022c9SBarry Smith Scalar *x, *b, *bs, d, *xs, sum, *v = a->a,*t,scale,*ts, *xb; 802d5d45c9bSBarry Smith int ierr, *idx, *diag,n = a->n, m = a->m, i, shift = a->indexshift; 80317ab2063SBarry Smith 80490f02eecSBarry Smith VecGetArray_Fast(xx,x); VecGetArray_Fast(bb,b); 805416022c9SBarry Smith if (!a->diag) {if ((ierr = MatMarkDiag_SeqAIJ(A))) return ierr;} 806416022c9SBarry Smith diag = a->diag; 807416022c9SBarry Smith xs = x + shift; /* shifted by one for index start of a or a->j*/ 80817ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 80917ab2063SBarry Smith /* apply ( U + D/omega) to the vector */ 81017ab2063SBarry Smith bs = b + shift; 81117ab2063SBarry Smith for ( i=0; i<m; i++ ) { 812416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 813416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 814416022c9SBarry Smith idx = a->j + diag[i] + (!shift); 815416022c9SBarry Smith v = a->a + diag[i] + (!shift); 81617ab2063SBarry Smith sum = b[i]*d/omega; 81717ab2063SBarry Smith SPARSEDENSEDOT(sum,bs,v,idx,n); 81817ab2063SBarry Smith x[i] = sum; 81917ab2063SBarry Smith } 82017ab2063SBarry Smith return 0; 82117ab2063SBarry Smith } 82217ab2063SBarry Smith if (flag == SOR_APPLY_LOWER) { 82317ab2063SBarry Smith SETERRQ(1,"MatRelax_SeqAIJ:SOR_APPLY_LOWER is not done"); 82417ab2063SBarry Smith } 825416022c9SBarry Smith else if (flag & SOR_EISENSTAT) { 82617ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 82717ab2063SBarry Smith U is upper triangular, E is diagonal; This routine applies 82817ab2063SBarry Smith 82917ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 83017ab2063SBarry Smith 83117ab2063SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 83217ab2063SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 83317ab2063SBarry Smith is the relaxation factor. 83417ab2063SBarry Smith */ 8350452661fSBarry Smith t = (Scalar *) PetscMalloc( m*sizeof(Scalar) ); CHKPTRQ(t); 83617ab2063SBarry Smith scale = (2.0/omega) - 1.0; 83717ab2063SBarry Smith 83817ab2063SBarry Smith /* x = (E + U)^{-1} b */ 83917ab2063SBarry Smith for ( i=m-1; i>=0; i-- ) { 840416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 841416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 842416022c9SBarry Smith idx = a->j + diag[i] + (!shift); 843416022c9SBarry Smith v = a->a + diag[i] + (!shift); 84417ab2063SBarry Smith sum = b[i]; 84517ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 84617ab2063SBarry Smith x[i] = omega*(sum/d); 84717ab2063SBarry Smith } 84817ab2063SBarry Smith 84917ab2063SBarry Smith /* t = b - (2*E - D)x */ 850416022c9SBarry Smith v = a->a; 85117ab2063SBarry Smith for ( i=0; i<m; i++ ) { t[i] = b[i] - scale*(v[*diag++ + shift])*x[i]; } 85217ab2063SBarry Smith 85317ab2063SBarry Smith /* t = (E + L)^{-1}t */ 854416022c9SBarry Smith ts = t + shift; /* shifted by one for index start of a or a->j*/ 855416022c9SBarry Smith diag = a->diag; 85617ab2063SBarry Smith for ( i=0; i<m; i++ ) { 857416022c9SBarry Smith d = fshift + a->a[diag[i]+shift]; 858416022c9SBarry Smith n = diag[i] - a->i[i]; 859416022c9SBarry Smith idx = a->j + a->i[i] + shift; 860416022c9SBarry Smith v = a->a + a->i[i] + shift; 86117ab2063SBarry Smith sum = t[i]; 86217ab2063SBarry Smith SPARSEDENSEMDOT(sum,ts,v,idx,n); 86317ab2063SBarry Smith t[i] = omega*(sum/d); 86417ab2063SBarry Smith } 86517ab2063SBarry Smith 86617ab2063SBarry Smith /* x = x + t */ 86717ab2063SBarry Smith for ( i=0; i<m; i++ ) { x[i] += t[i]; } 8680452661fSBarry Smith PetscFree(t); 86917ab2063SBarry Smith return 0; 87017ab2063SBarry Smith } 87117ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 87217ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 87317ab2063SBarry Smith for ( i=0; i<m; i++ ) { 874416022c9SBarry Smith d = fshift + a->a[diag[i]+shift]; 875416022c9SBarry Smith n = diag[i] - a->i[i]; 876416022c9SBarry Smith idx = a->j + a->i[i] + shift; 877416022c9SBarry Smith v = a->a + a->i[i] + shift; 87817ab2063SBarry Smith sum = b[i]; 87917ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 88017ab2063SBarry Smith x[i] = omega*(sum/d); 88117ab2063SBarry Smith } 88217ab2063SBarry Smith xb = x; 88317ab2063SBarry Smith } 88417ab2063SBarry Smith else xb = b; 88517ab2063SBarry Smith if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) && 88617ab2063SBarry Smith (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) { 88717ab2063SBarry Smith for ( i=0; i<m; i++ ) { 888416022c9SBarry Smith x[i] *= a->a[diag[i]+shift]; 88917ab2063SBarry Smith } 89017ab2063SBarry Smith } 89117ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 89217ab2063SBarry Smith for ( i=m-1; i>=0; i-- ) { 893416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 894416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 895416022c9SBarry Smith idx = a->j + diag[i] + (!shift); 896416022c9SBarry Smith v = a->a + diag[i] + (!shift); 89717ab2063SBarry Smith sum = xb[i]; 89817ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 89917ab2063SBarry Smith x[i] = omega*(sum/d); 90017ab2063SBarry Smith } 90117ab2063SBarry Smith } 90217ab2063SBarry Smith its--; 90317ab2063SBarry Smith } 90417ab2063SBarry Smith while (its--) { 90517ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 90617ab2063SBarry Smith for ( i=0; i<m; i++ ) { 907416022c9SBarry Smith d = fshift + a->a[diag[i]+shift]; 908416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 909416022c9SBarry Smith idx = a->j + a->i[i] + shift; 910416022c9SBarry Smith v = a->a + a->i[i] + shift; 91117ab2063SBarry Smith sum = b[i]; 91217ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 9137e33a6baSBarry Smith x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d; 91417ab2063SBarry Smith } 91517ab2063SBarry Smith } 91617ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 91717ab2063SBarry Smith for ( i=m-1; i>=0; i-- ) { 918416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 919416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 920416022c9SBarry Smith idx = a->j + a->i[i] + shift; 921416022c9SBarry Smith v = a->a + a->i[i] + shift; 92217ab2063SBarry Smith sum = b[i]; 92317ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 9247e33a6baSBarry Smith x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d; 92517ab2063SBarry Smith } 92617ab2063SBarry Smith } 92717ab2063SBarry Smith } 92817ab2063SBarry Smith return 0; 92917ab2063SBarry Smith } 93017ab2063SBarry Smith 931*026e39d0SSatish Balay #undef __FUNCTION__ 932*026e39d0SSatish Balay #define __FUNCTION__ "MatGetInfo_SeqAIJ" 9334e220ebcSLois Curfman McInnes static int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 93417ab2063SBarry Smith { 935416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 9364e220ebcSLois Curfman McInnes 9374e220ebcSLois Curfman McInnes info->rows_global = (double)a->m; 9384e220ebcSLois Curfman McInnes info->columns_global = (double)a->n; 9394e220ebcSLois Curfman McInnes info->rows_local = (double)a->m; 9404e220ebcSLois Curfman McInnes info->columns_local = (double)a->n; 9414e220ebcSLois Curfman McInnes info->block_size = 1.0; 9424e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 9434e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 9444e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 9454e220ebcSLois Curfman McInnes /* if (info->nz_unneeded != A->info.nz_unneeded) 9464e220ebcSLois Curfman McInnes printf("space descrepancy: maxnz-nz = %d, nz_unneeded = %d\n",(int)info->nz_unneeded,(int)A->info.nz_unneeded); */ 9474e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 9484e220ebcSLois Curfman McInnes info->mallocs = (double)a->reallocs; 9494e220ebcSLois Curfman McInnes info->memory = A->mem; 9504e220ebcSLois Curfman McInnes if (A->factor) { 9514e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 9524e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 9534e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 9544e220ebcSLois Curfman McInnes } else { 9554e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 9564e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 9574e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 9584e220ebcSLois Curfman McInnes } 95917ab2063SBarry Smith return 0; 96017ab2063SBarry Smith } 96117ab2063SBarry Smith 96217ab2063SBarry Smith extern int MatLUFactorSymbolic_SeqAIJ(Mat,IS,IS,double,Mat*); 96317ab2063SBarry Smith extern int MatLUFactorNumeric_SeqAIJ(Mat,Mat*); 96417ab2063SBarry Smith extern int MatLUFactor_SeqAIJ(Mat,IS,IS,double); 96517ab2063SBarry Smith extern int MatSolve_SeqAIJ(Mat,Vec,Vec); 96617ab2063SBarry Smith extern int MatSolveAdd_SeqAIJ(Mat,Vec,Vec,Vec); 96717ab2063SBarry Smith extern int MatSolveTrans_SeqAIJ(Mat,Vec,Vec); 96817ab2063SBarry Smith extern int MatSolveTransAdd_SeqAIJ(Mat,Vec,Vec,Vec); 96917ab2063SBarry Smith 970*026e39d0SSatish Balay #undef __FUNCTION__ 971*026e39d0SSatish Balay #define __FUNCTION__ "MatZeroRows_SeqAIJ" 97217ab2063SBarry Smith static int MatZeroRows_SeqAIJ(Mat A,IS is,Scalar *diag) 97317ab2063SBarry Smith { 974416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 975416022c9SBarry Smith int i,ierr,N, *rows,m = a->m - 1,shift = a->indexshift; 97617ab2063SBarry Smith 97777c4ece6SBarry Smith ierr = ISGetSize(is,&N); CHKERRQ(ierr); 97817ab2063SBarry Smith ierr = ISGetIndices(is,&rows); CHKERRQ(ierr); 97917ab2063SBarry Smith if (diag) { 98017ab2063SBarry Smith for ( i=0; i<N; i++ ) { 981416022c9SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(1,"MatZeroRows_SeqAIJ:row out of range"); 982416022c9SBarry Smith if (a->ilen[rows[i]] > 0) { /* in case row was completely empty */ 983416022c9SBarry Smith a->ilen[rows[i]] = 1; 984416022c9SBarry Smith a->a[a->i[rows[i]]+shift] = *diag; 985416022c9SBarry Smith a->j[a->i[rows[i]]+shift] = rows[i]+shift; 98617ab2063SBarry Smith } 98717ab2063SBarry Smith else { 98817ab2063SBarry Smith ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES); 98917ab2063SBarry Smith CHKERRQ(ierr); 99017ab2063SBarry Smith } 99117ab2063SBarry Smith } 99217ab2063SBarry Smith } 99317ab2063SBarry Smith else { 99417ab2063SBarry Smith for ( i=0; i<N; i++ ) { 995416022c9SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(1,"MatZeroRows_SeqAIJ:row out of range"); 996416022c9SBarry Smith a->ilen[rows[i]] = 0; 99717ab2063SBarry Smith } 99817ab2063SBarry Smith } 99917ab2063SBarry Smith ISRestoreIndices(is,&rows); 100043a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 100117ab2063SBarry Smith return 0; 100217ab2063SBarry Smith } 100317ab2063SBarry Smith 1004*026e39d0SSatish Balay #undef __FUNCTION__ 1005*026e39d0SSatish Balay #define __FUNCTION__ "MatGetSize_SeqAIJ" 1006416022c9SBarry Smith static int MatGetSize_SeqAIJ(Mat A,int *m,int *n) 100717ab2063SBarry Smith { 1008416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1009416022c9SBarry Smith *m = a->m; *n = a->n; 101017ab2063SBarry Smith return 0; 101117ab2063SBarry Smith } 101217ab2063SBarry Smith 1013*026e39d0SSatish Balay #undef __FUNCTION__ 1014*026e39d0SSatish Balay #define __FUNCTION__ "MatGetOwnershipRange_SeqAIJ" 1015416022c9SBarry Smith static int MatGetOwnershipRange_SeqAIJ(Mat A,int *m,int *n) 101617ab2063SBarry Smith { 1017416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1018416022c9SBarry Smith *m = 0; *n = a->m; 101917ab2063SBarry Smith return 0; 102017ab2063SBarry Smith } 1021*026e39d0SSatish Balay 1022*026e39d0SSatish Balay #undef __FUNCTION__ 1023*026e39d0SSatish Balay #define __FUNCTION__ "MatGetRow_SeqAIJ" 10244e093b46SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 102517ab2063SBarry Smith { 1026416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1027c456f294SBarry Smith int *itmp,i,shift = a->indexshift; 102817ab2063SBarry Smith 1029416022c9SBarry Smith if (row < 0 || row >= a->m) SETERRQ(1,"MatGetRow_SeqAIJ:Row out of range"); 103017ab2063SBarry Smith 1031416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1032416022c9SBarry Smith if (v) *v = a->a + a->i[row] + shift; 103317ab2063SBarry Smith if (idx) { 1034416022c9SBarry Smith itmp = a->j + a->i[row] + shift; 10354e093b46SBarry Smith if (*nz && shift) { 10360452661fSBarry Smith *idx = (int *) PetscMalloc( (*nz)*sizeof(int) ); CHKPTRQ(*idx); 103717ab2063SBarry Smith for ( i=0; i<(*nz); i++ ) {(*idx)[i] = itmp[i] + shift;} 10384e093b46SBarry Smith } else if (*nz) { 10394e093b46SBarry Smith *idx = itmp; 104017ab2063SBarry Smith } 104117ab2063SBarry Smith else *idx = 0; 104217ab2063SBarry Smith } 104317ab2063SBarry Smith return 0; 104417ab2063SBarry Smith } 104517ab2063SBarry Smith 1046*026e39d0SSatish Balay #undef __FUNCTION__ 1047*026e39d0SSatish Balay #define __FUNCTION__ "MatRestoreRow_SeqAIJ" 10484e093b46SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 104917ab2063SBarry Smith { 10504e093b46SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 10514e093b46SBarry Smith if (idx) {if (*idx && a->indexshift) PetscFree(*idx);} 105217ab2063SBarry Smith return 0; 105317ab2063SBarry Smith } 105417ab2063SBarry Smith 1055*026e39d0SSatish Balay #undef __FUNCTION__ 1056*026e39d0SSatish Balay #define __FUNCTION__ "MatNorm_SeqAIJ" 1057cddf8d76SBarry Smith static int MatNorm_SeqAIJ(Mat A,NormType type,double *norm) 105817ab2063SBarry Smith { 1059416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1060416022c9SBarry Smith Scalar *v = a->a; 106117ab2063SBarry Smith double sum = 0.0; 1062416022c9SBarry Smith int i, j,shift = a->indexshift; 106317ab2063SBarry Smith 106417ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1065416022c9SBarry Smith for (i=0; i<a->nz; i++ ) { 106617ab2063SBarry Smith #if defined(PETSC_COMPLEX) 106717ab2063SBarry Smith sum += real(conj(*v)*(*v)); v++; 106817ab2063SBarry Smith #else 106917ab2063SBarry Smith sum += (*v)*(*v); v++; 107017ab2063SBarry Smith #endif 107117ab2063SBarry Smith } 107217ab2063SBarry Smith *norm = sqrt(sum); 107317ab2063SBarry Smith } 107417ab2063SBarry Smith else if (type == NORM_1) { 107517ab2063SBarry Smith double *tmp; 1076416022c9SBarry Smith int *jj = a->j; 10770452661fSBarry Smith tmp = (double *) PetscMalloc( a->n*sizeof(double) ); CHKPTRQ(tmp); 1078cddf8d76SBarry Smith PetscMemzero(tmp,a->n*sizeof(double)); 107917ab2063SBarry Smith *norm = 0.0; 1080416022c9SBarry Smith for ( j=0; j<a->nz; j++ ) { 1081a2744918SBarry Smith tmp[*jj++ + shift] += PetscAbsScalar(*v); v++; 108217ab2063SBarry Smith } 1083416022c9SBarry Smith for ( j=0; j<a->n; j++ ) { 108417ab2063SBarry Smith if (tmp[j] > *norm) *norm = tmp[j]; 108517ab2063SBarry Smith } 10860452661fSBarry Smith PetscFree(tmp); 108717ab2063SBarry Smith } 108817ab2063SBarry Smith else if (type == NORM_INFINITY) { 108917ab2063SBarry Smith *norm = 0.0; 1090416022c9SBarry Smith for ( j=0; j<a->m; j++ ) { 1091416022c9SBarry Smith v = a->a + a->i[j] + shift; 109217ab2063SBarry Smith sum = 0.0; 1093416022c9SBarry Smith for ( i=0; i<a->i[j+1]-a->i[j]; i++ ) { 1094cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 109517ab2063SBarry Smith } 109617ab2063SBarry Smith if (sum > *norm) *norm = sum; 109717ab2063SBarry Smith } 109817ab2063SBarry Smith } 109917ab2063SBarry Smith else { 110048d91487SBarry Smith SETERRQ(1,"MatNorm_SeqAIJ:No support for two norm yet"); 110117ab2063SBarry Smith } 110217ab2063SBarry Smith return 0; 110317ab2063SBarry Smith } 110417ab2063SBarry Smith 1105*026e39d0SSatish Balay #undef __FUNCTION__ 1106*026e39d0SSatish Balay #define __FUNCTION__ "MatTranspose_SeqAIJ" 1107416022c9SBarry Smith static int MatTranspose_SeqAIJ(Mat A,Mat *B) 110817ab2063SBarry Smith { 1109416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1110416022c9SBarry Smith Mat C; 1111416022c9SBarry Smith int i, ierr, *aj = a->j, *ai = a->i, m = a->m, len, *col; 1112416022c9SBarry Smith int shift = a->indexshift; 1113d5d45c9bSBarry Smith Scalar *array = a->a; 111417ab2063SBarry Smith 11153638b69dSLois Curfman McInnes if (B == PETSC_NULL && m != a->n) 1116dfa27b74SSatish Balay SETERRQ(1,"MatTranspose_SeqAIJ:Square matrix only for in-place"); 11170452661fSBarry Smith col = (int *) PetscMalloc((1+a->n)*sizeof(int)); CHKPTRQ(col); 1118cddf8d76SBarry Smith PetscMemzero(col,(1+a->n)*sizeof(int)); 111917ab2063SBarry Smith if (shift) { 112017ab2063SBarry Smith for ( i=0; i<ai[m]-1; i++ ) aj[i] -= 1; 112117ab2063SBarry Smith } 112217ab2063SBarry Smith for ( i=0; i<ai[m]+shift; i++ ) col[aj[i]] += 1; 1123416022c9SBarry Smith ierr = MatCreateSeqAIJ(A->comm,a->n,m,0,col,&C); CHKERRQ(ierr); 11240452661fSBarry Smith PetscFree(col); 112517ab2063SBarry Smith for ( i=0; i<m; i++ ) { 112617ab2063SBarry Smith len = ai[i+1]-ai[i]; 1127416022c9SBarry Smith ierr = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES); CHKERRQ(ierr); 112817ab2063SBarry Smith array += len; aj += len; 112917ab2063SBarry Smith } 113017ab2063SBarry Smith if (shift) { 113117ab2063SBarry Smith for ( i=0; i<ai[m]-1; i++ ) aj[i] += 1; 113217ab2063SBarry Smith } 113317ab2063SBarry Smith 11346d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 11356d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 113617ab2063SBarry Smith 11373638b69dSLois Curfman McInnes if (B != PETSC_NULL) { 1138416022c9SBarry Smith *B = C; 113917ab2063SBarry Smith } else { 1140416022c9SBarry Smith /* This isn't really an in-place transpose */ 11410452661fSBarry Smith PetscFree(a->a); 11420452661fSBarry Smith if (!a->singlemalloc) {PetscFree(a->i); PetscFree(a->j);} 11430452661fSBarry Smith if (a->diag) PetscFree(a->diag); 11440452661fSBarry Smith if (a->ilen) PetscFree(a->ilen); 11450452661fSBarry Smith if (a->imax) PetscFree(a->imax); 11460452661fSBarry Smith if (a->solve_work) PetscFree(a->solve_work); 11471073c447SSatish Balay if (a->inode.size) PetscFree(a->inode.size); 11480452661fSBarry Smith PetscFree(a); 1149416022c9SBarry Smith PetscMemcpy(A,C,sizeof(struct _Mat)); 11500452661fSBarry Smith PetscHeaderDestroy(C); 115117ab2063SBarry Smith } 115217ab2063SBarry Smith return 0; 115317ab2063SBarry Smith } 115417ab2063SBarry Smith 1155*026e39d0SSatish Balay #undef __FUNCTION__ 1156*026e39d0SSatish Balay #define __FUNCTION__ "MatDiagonalScale_SeqAIJ" 1157f0b747eeSBarry Smith static int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 115817ab2063SBarry Smith { 1159416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 116017ab2063SBarry Smith Scalar *l,*r,x,*v; 1161d5d45c9bSBarry Smith int i,j,m = a->m, n = a->n, M, nz = a->nz, *jj,shift = a->indexshift; 116217ab2063SBarry Smith 116317ab2063SBarry Smith if (ll) { 11643ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 11653ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 11669b1297e1SSatish Balay VecGetLocalSize_Fast(ll,m); 1167f0b747eeSBarry Smith if (m != a->m) SETERRQ(1,"MatDiagonalScale_SeqAIJ:Left scaling vector wrong length"); 116890f02eecSBarry Smith VecGetArray_Fast(ll,l); 1169416022c9SBarry Smith v = a->a; 117017ab2063SBarry Smith for ( i=0; i<m; i++ ) { 117117ab2063SBarry Smith x = l[i]; 1172416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 117317ab2063SBarry Smith for ( j=0; j<M; j++ ) { (*v++) *= x;} 117417ab2063SBarry Smith } 117544cd7ae7SLois Curfman McInnes PLogFlops(nz); 117617ab2063SBarry Smith } 117717ab2063SBarry Smith if (rr) { 11789b1297e1SSatish Balay VecGetLocalSize_Fast(rr,n); 1179f0b747eeSBarry Smith if (n != a->n) SETERRQ(1,"MatDiagonalScale_SeqAIJ:Right scaling vector wrong length"); 118090f02eecSBarry Smith VecGetArray_Fast(rr,r); 1181416022c9SBarry Smith v = a->a; jj = a->j; 118217ab2063SBarry Smith for ( i=0; i<nz; i++ ) { 118317ab2063SBarry Smith (*v++) *= r[*jj++ + shift]; 118417ab2063SBarry Smith } 118544cd7ae7SLois Curfman McInnes PLogFlops(nz); 118617ab2063SBarry Smith } 118717ab2063SBarry Smith return 0; 118817ab2063SBarry Smith } 118917ab2063SBarry Smith 1190*026e39d0SSatish Balay #undef __FUNCTION__ 1191*026e39d0SSatish Balay #define __FUNCTION__ "MatGetSubMatrix_SeqAIJ" 1192cddf8d76SBarry Smith static int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,MatGetSubMatrixCall scall,Mat *B) 119317ab2063SBarry Smith { 1194db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data,*c; 119502834360SBarry Smith int nznew, *smap, i, k, kstart, kend, ierr, oldcols = a->n,*lens; 119699141d43SSatish Balay int row,mat_i,*mat_j,tcol,first,step,*mat_ilen; 1197a2744918SBarry Smith register int sum,lensi; 119899141d43SSatish Balay int *irow, *icol, nrows, ncols, shift = a->indexshift,*ssmap; 119999141d43SSatish Balay int *starts,*j_new,*i_new,*aj = a->j, *ai = a->i,ii,*ailen = a->ilen; 120099141d43SSatish Balay Scalar *a_new,*mat_a; 1201416022c9SBarry Smith Mat C; 120217ab2063SBarry Smith 1203b48a1e75SSatish Balay ierr = ISSorted(isrow,(PetscTruth*)&i); 1204b48a1e75SSatish Balay if (!i) SETERRQ(1,"MatGetSubmatrices_SeqAIJ:ISrow is not sorted"); 120599141d43SSatish Balay ierr = ISSorted(iscol,(PetscTruth*)&i); 1206b48a1e75SSatish Balay if (!i) SETERRQ(1,"MatGetSubmatrices_SeqAIJ:IScol is not sorted"); 120799141d43SSatish Balay 120817ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow); CHKERRQ(ierr); 120917ab2063SBarry Smith ierr = ISGetSize(isrow,&nrows); CHKERRQ(ierr); 121017ab2063SBarry Smith ierr = ISGetSize(iscol,&ncols); CHKERRQ(ierr); 121117ab2063SBarry Smith 12127264ac53SSatish Balay if (ISStrideGetInfo(iscol,&first,&step) && step == 1) { /* no need to sort */ 121302834360SBarry Smith /* special case of contiguous rows */ 121457faeb66SBarry Smith lens = (int *) PetscMalloc((ncols+nrows+1)*sizeof(int)); CHKPTRQ(lens); 121502834360SBarry Smith starts = lens + ncols; 121602834360SBarry Smith /* loop over new rows determining lens and starting points */ 121702834360SBarry Smith for (i=0; i<nrows; i++) { 1218a2744918SBarry Smith kstart = ai[irow[i]]+shift; 1219a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 122002834360SBarry Smith for ( k=kstart; k<kend; k++ ) { 1221d8ced48eSBarry Smith if (aj[k]+shift >= first) { 122202834360SBarry Smith starts[i] = k; 122302834360SBarry Smith break; 122402834360SBarry Smith } 122502834360SBarry Smith } 1226a2744918SBarry Smith sum = 0; 122702834360SBarry Smith while (k < kend) { 1228d8ced48eSBarry Smith if (aj[k++]+shift >= first+ncols) break; 1229a2744918SBarry Smith sum++; 123002834360SBarry Smith } 1231a2744918SBarry Smith lens[i] = sum; 123202834360SBarry Smith } 123302834360SBarry Smith /* create submatrix */ 1234cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 123508480c60SBarry Smith int n_cols,n_rows; 123608480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols); CHKERRQ(ierr); 123708480c60SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(1,"MatGetSubMatrix_SeqAIJ:"); 1238d8ced48eSBarry Smith ierr = MatZeroEntries(*B); CHKERRQ(ierr); 123908480c60SBarry Smith C = *B; 124008480c60SBarry Smith } 124108480c60SBarry Smith else { 124202834360SBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 124308480c60SBarry Smith } 1244db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*) C->data; 1245db02288aSLois Curfman McInnes 124602834360SBarry Smith /* loop over rows inserting into submatrix */ 1247db02288aSLois Curfman McInnes a_new = c->a; 1248db02288aSLois Curfman McInnes j_new = c->j; 1249db02288aSLois Curfman McInnes i_new = c->i; 1250db02288aSLois Curfman McInnes i_new[0] = -shift; 125102834360SBarry Smith for (i=0; i<nrows; i++) { 1252a2744918SBarry Smith ii = starts[i]; 1253a2744918SBarry Smith lensi = lens[i]; 1254a2744918SBarry Smith for ( k=0; k<lensi; k++ ) { 1255a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 125602834360SBarry Smith } 1257a2744918SBarry Smith PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(Scalar)); 1258a2744918SBarry Smith a_new += lensi; 1259a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 1260a2744918SBarry Smith c->ilen[i] = lensi; 126102834360SBarry Smith } 12620452661fSBarry Smith PetscFree(lens); 126302834360SBarry Smith } 126402834360SBarry Smith else { 126502834360SBarry Smith ierr = ISGetIndices(iscol,&icol); CHKERRQ(ierr); 12660452661fSBarry Smith smap = (int *) PetscMalloc((1+oldcols)*sizeof(int)); CHKPTRQ(smap); 126702834360SBarry Smith ssmap = smap + shift; 126899141d43SSatish Balay lens = (int *) PetscMalloc((1+nrows)*sizeof(int)); CHKPTRQ(lens); 1269cddf8d76SBarry Smith PetscMemzero(smap,oldcols*sizeof(int)); 127017ab2063SBarry Smith for ( i=0; i<ncols; i++ ) smap[icol[i]] = i+1; 127102834360SBarry Smith /* determine lens of each row */ 127202834360SBarry Smith for (i=0; i<nrows; i++) { 1273d8ced48eSBarry Smith kstart = ai[irow[i]]+shift; 127402834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 127502834360SBarry Smith lens[i] = 0; 127602834360SBarry Smith for ( k=kstart; k<kend; k++ ) { 1277d8ced48eSBarry Smith if (ssmap[aj[k]]) { 127802834360SBarry Smith lens[i]++; 127902834360SBarry Smith } 128002834360SBarry Smith } 128102834360SBarry Smith } 128217ab2063SBarry Smith /* Create and fill new matrix */ 1283a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 128499141d43SSatish Balay c = (Mat_SeqAIJ *)((*B)->data); 128599141d43SSatish Balay 128699141d43SSatish Balay if (c->m != nrows || c->n != ncols) SETERRQ(1,"MatGetSubMatrix_SeqAIJ:"); 128799141d43SSatish Balay if (PetscMemcmp(c->ilen,lens, c->m *sizeof(int))) { 128899141d43SSatish Balay SETERRQ(1,"MatGetSubmatrices_SeqAIJ:Cannot reuse matrix. wrong no of nonzeros"); 128999141d43SSatish Balay } 129099141d43SSatish Balay PetscMemzero(c->ilen,c->m*sizeof(int)); 129108480c60SBarry Smith C = *B; 129208480c60SBarry Smith } 129308480c60SBarry Smith else { 129402834360SBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 129508480c60SBarry Smith } 129699141d43SSatish Balay c = (Mat_SeqAIJ *)(C->data); 129717ab2063SBarry Smith for (i=0; i<nrows; i++) { 129899141d43SSatish Balay row = irow[i]; 129917ab2063SBarry Smith nznew = 0; 130099141d43SSatish Balay kstart = ai[row]+shift; 130199141d43SSatish Balay kend = kstart + a->ilen[row]; 130299141d43SSatish Balay mat_i = c->i[i]+shift; 130399141d43SSatish Balay mat_j = c->j + mat_i; 130499141d43SSatish Balay mat_a = c->a + mat_i; 130599141d43SSatish Balay mat_ilen = c->ilen + i; 130617ab2063SBarry Smith for ( k=kstart; k<kend; k++ ) { 130799141d43SSatish Balay if ((tcol=ssmap[a->j[k]])) { 130899141d43SSatish Balay *mat_j++ = tcol - (!shift); 130999141d43SSatish Balay *mat_a++ = a->a[k]; 131099141d43SSatish Balay (*mat_ilen)++; 131199141d43SSatish Balay 131217ab2063SBarry Smith } 131317ab2063SBarry Smith } 131417ab2063SBarry Smith } 131502834360SBarry Smith /* Free work space */ 131602834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol); CHKERRQ(ierr); 131799141d43SSatish Balay PetscFree(smap); PetscFree(lens); 131802834360SBarry Smith } 13196d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 13206d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 132117ab2063SBarry Smith 132217ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow); CHKERRQ(ierr); 1323416022c9SBarry Smith *B = C; 132417ab2063SBarry Smith return 0; 132517ab2063SBarry Smith } 132617ab2063SBarry Smith 1327a871dcd8SBarry Smith /* 132863b91edcSBarry Smith note: This can only work for identity for row and col. It would 132963b91edcSBarry Smith be good to check this and otherwise generate an error. 1330a871dcd8SBarry Smith */ 1331*026e39d0SSatish Balay #undef __FUNCTION__ 1332*026e39d0SSatish Balay #define __FUNCTION__ "MatILUFactor_SeqAIJ" 133363b91edcSBarry Smith static int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,double efill,int fill) 1334a871dcd8SBarry Smith { 133563b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) inA->data; 133608480c60SBarry Smith int ierr; 133763b91edcSBarry Smith Mat outA; 133863b91edcSBarry Smith 1339a871dcd8SBarry Smith if (fill != 0) SETERRQ(1,"MatILUFactor_SeqAIJ:Only fill=0 supported"); 1340a871dcd8SBarry Smith 134163b91edcSBarry Smith outA = inA; 134263b91edcSBarry Smith inA->factor = FACTOR_LU; 134363b91edcSBarry Smith a->row = row; 134463b91edcSBarry Smith a->col = col; 134563b91edcSBarry Smith 13460452661fSBarry Smith a->solve_work = (Scalar *) PetscMalloc( (a->m+1)*sizeof(Scalar)); CHKPTRQ(a->solve_work); 134763b91edcSBarry Smith 134808480c60SBarry Smith if (!a->diag) { 134908480c60SBarry Smith ierr = MatMarkDiag_SeqAIJ(inA); CHKERRQ(ierr); 135063b91edcSBarry Smith } 135163b91edcSBarry Smith ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA); CHKERRQ(ierr); 1352a871dcd8SBarry Smith return 0; 1353a871dcd8SBarry Smith } 1354a871dcd8SBarry Smith 1355f0b747eeSBarry Smith #include "pinclude/plapack.h" 1356*026e39d0SSatish Balay #undef __FUNCTION__ 1357*026e39d0SSatish Balay #define __FUNCTION__ "MatScale_SeqAIJ" 1358f0b747eeSBarry Smith static int MatScale_SeqAIJ(Scalar *alpha,Mat inA) 1359f0b747eeSBarry Smith { 1360f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) inA->data; 1361f0b747eeSBarry Smith int one = 1; 1362f0b747eeSBarry Smith BLscal_( &a->nz, alpha, a->a, &one ); 1363f0b747eeSBarry Smith PLogFlops(a->nz); 1364f0b747eeSBarry Smith return 0; 1365f0b747eeSBarry Smith } 1366f0b747eeSBarry Smith 1367*026e39d0SSatish Balay #undef __FUNCTION__ 1368*026e39d0SSatish Balay #define __FUNCTION__ "MatGetSubMatrices_SeqAIJ" 1369cddf8d76SBarry Smith static int MatGetSubMatrices_SeqAIJ(Mat A,int n, IS *irow,IS *icol,MatGetSubMatrixCall scall, 1370cddf8d76SBarry Smith Mat **B) 1371cddf8d76SBarry Smith { 1372cddf8d76SBarry Smith int ierr,i; 1373cddf8d76SBarry Smith 1374cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 13750452661fSBarry Smith *B = (Mat *) PetscMalloc( (n+1)*sizeof(Mat) ); CHKPTRQ(*B); 1376cddf8d76SBarry Smith } 1377cddf8d76SBarry Smith 1378cddf8d76SBarry Smith for ( i=0; i<n; i++ ) { 1379905e6a2fSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],scall,&(*B)[i]);CHKERRQ(ierr); 1380cddf8d76SBarry Smith } 1381cddf8d76SBarry Smith return 0; 1382cddf8d76SBarry Smith } 1383cddf8d76SBarry Smith 1384*026e39d0SSatish Balay #undef __FUNCTION__ 1385*026e39d0SSatish Balay #define __FUNCTION__ "MatGetBlockSize_SeqAIJ" 13865a838052SSatish Balay static int MatGetBlockSize_SeqAIJ(Mat A, int *bs) 13875a838052SSatish Balay { 13885a838052SSatish Balay *bs = 1; 13895a838052SSatish Balay return 0; 13905a838052SSatish Balay } 13915a838052SSatish Balay 1392*026e39d0SSatish Balay #undef __FUNCTION__ 1393*026e39d0SSatish Balay #define __FUNCTION__ "MatIncreaseOverlap_SeqAIJ" 1394e4d965acSSatish Balay static int MatIncreaseOverlap_SeqAIJ(Mat A, int is_max, IS *is, int ov) 13954dcbc457SBarry Smith { 1396e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 139706763907SSatish Balay int shift, row, i,j,k,l,m,n, *idx,ierr, *nidx, isz, val; 13988a047759SSatish Balay int start, end, *ai, *aj; 139906763907SSatish Balay char *table; 14008a047759SSatish Balay shift = a->indexshift; 1401e4d965acSSatish Balay m = a->m; 1402e4d965acSSatish Balay ai = a->i; 14038a047759SSatish Balay aj = a->j+shift; 14048a047759SSatish Balay 1405e4d965acSSatish Balay if (ov < 0) SETERRQ(1,"MatIncreaseOverlap_SeqAIJ: illegal overlap value used"); 140606763907SSatish Balay 140706763907SSatish Balay table = (char *) PetscMalloc((m/BITSPERBYTE +1)*sizeof(char)); CHKPTRQ(table); 140806763907SSatish Balay nidx = (int *) PetscMalloc((m+1)*sizeof(int)); CHKPTRQ(nidx); 140906763907SSatish Balay 1410e4d965acSSatish Balay for ( i=0; i<is_max; i++ ) { 1411e4d965acSSatish Balay /* Initialise the two local arrays */ 1412e4d965acSSatish Balay isz = 0; 141306763907SSatish Balay PetscMemzero(table,(m/BITSPERBYTE +1)*sizeof(char)); 1414e4d965acSSatish Balay 1415e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 14164dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx); CHKERRQ(ierr); 141777c4ece6SBarry Smith ierr = ISGetSize(is[i],&n); CHKERRQ(ierr); 1418e4d965acSSatish Balay 1419e4d965acSSatish Balay /* Enter these into the temp arrays i.e mark table[row], enter row into new index */ 1420e4d965acSSatish Balay for ( j=0; j<n ; ++j){ 142106763907SSatish Balay if(!BT_LOOKUP(table, idx[j])) { nidx[isz++] = idx[j];} 14224dcbc457SBarry Smith } 142306763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx); CHKERRQ(ierr); 142406763907SSatish Balay ierr = ISDestroy(is[i]); CHKERRQ(ierr); 1425e4d965acSSatish Balay 142604a348a9SBarry Smith k = 0; 142704a348a9SBarry Smith for ( j=0; j<ov; j++){ /* for each overlap*/ 142804a348a9SBarry Smith n = isz; 142906763907SSatish Balay for ( ; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */ 1430e4d965acSSatish Balay row = nidx[k]; 1431e4d965acSSatish Balay start = ai[row]; 1432e4d965acSSatish Balay end = ai[row+1]; 143304a348a9SBarry Smith for ( l = start; l<end ; l++){ 14348a047759SSatish Balay val = aj[l] + shift; 143506763907SSatish Balay if (!BT_LOOKUP(table,val)) {nidx[isz++] = val;} 1436e4d965acSSatish Balay } 1437e4d965acSSatish Balay } 1438e4d965acSSatish Balay } 1439537820f0SBarry Smith ierr = ISCreateGeneral(MPI_COMM_SELF, isz, nidx, (is+i)); CHKERRQ(ierr); 1440e4d965acSSatish Balay } 144104a348a9SBarry Smith PetscFree(table); 144206763907SSatish Balay PetscFree(nidx); 1443e4d965acSSatish Balay return 0; 14444dcbc457SBarry Smith } 144517ab2063SBarry Smith 1446*026e39d0SSatish Balay #undef __FUNCTION__ 1447*026e39d0SSatish Balay #define __FUNCTION__ "MatPrintHelp_SeqAIJ" 1448682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A) 1449682d7d0cSBarry Smith { 1450682d7d0cSBarry Smith static int called = 0; 1451682d7d0cSBarry Smith MPI_Comm comm = A->comm; 1452682d7d0cSBarry Smith 1453682d7d0cSBarry Smith if (called) return 0; else called = 1; 145477c4ece6SBarry Smith PetscPrintf(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n"); 145577c4ece6SBarry Smith PetscPrintf(comm," -mat_lu_pivotthreshold <threshold>\n"); 145677c4ece6SBarry Smith PetscPrintf(comm," -mat_aij_oneindex - internal indices begin at 1 instead of the default 0.\n"); 145777c4ece6SBarry Smith PetscPrintf(comm," -mat_aij_no_inode - Do not use inodes\n"); 145877c4ece6SBarry Smith PetscPrintf(comm," -mat_aij_inode_limit <limit> - Set inode limit (max limit=5)\n"); 1459682d7d0cSBarry Smith #if defined(HAVE_ESSL) 146077c4ece6SBarry Smith PetscPrintf(comm," -mat_aij_essl - Use IBM sparse LU factorization and solve.\n"); 1461682d7d0cSBarry Smith #endif 1462682d7d0cSBarry Smith return 0; 1463682d7d0cSBarry Smith } 1464205e38a3SBarry Smith static int MatEqual_SeqAIJ(Mat A,Mat B, PetscTruth* flg); 1465a93ec695SBarry Smith extern int MatFDColoringCreate_SeqAIJ(Mat,ISColoring,MatFDColoring); 1466a93ec695SBarry Smith extern int MatColoringPatch_SeqAIJ(Mat,int,int *,ISColoring *); 1467a93ec695SBarry Smith 1468682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 146917ab2063SBarry Smith static struct _MatOps MatOps = {MatSetValues_SeqAIJ, 147017ab2063SBarry Smith MatGetRow_SeqAIJ,MatRestoreRow_SeqAIJ, 1471416022c9SBarry Smith MatMult_SeqAIJ,MatMultAdd_SeqAIJ, 1472416022c9SBarry Smith MatMultTrans_SeqAIJ,MatMultTransAdd_SeqAIJ, 147317ab2063SBarry Smith MatSolve_SeqAIJ,MatSolveAdd_SeqAIJ, 147417ab2063SBarry Smith MatSolveTrans_SeqAIJ,MatSolveTransAdd_SeqAIJ, 147517ab2063SBarry Smith MatLUFactor_SeqAIJ,0, 147617ab2063SBarry Smith MatRelax_SeqAIJ, 147717ab2063SBarry Smith MatTranspose_SeqAIJ, 14787264ac53SSatish Balay MatGetInfo_SeqAIJ,MatEqual_SeqAIJ, 1479f0b747eeSBarry Smith MatGetDiagonal_SeqAIJ,MatDiagonalScale_SeqAIJ,MatNorm_SeqAIJ, 148017ab2063SBarry Smith 0,MatAssemblyEnd_SeqAIJ, 148117ab2063SBarry Smith MatCompress_SeqAIJ, 148217ab2063SBarry Smith MatSetOption_SeqAIJ,MatZeroEntries_SeqAIJ,MatZeroRows_SeqAIJ, 148317ab2063SBarry Smith MatLUFactorSymbolic_SeqAIJ,MatLUFactorNumeric_SeqAIJ,0,0, 148417ab2063SBarry Smith MatGetSize_SeqAIJ,MatGetSize_SeqAIJ,MatGetOwnershipRange_SeqAIJ, 148517ab2063SBarry Smith MatILUFactorSymbolic_SeqAIJ,0, 148617ab2063SBarry Smith 0,0,MatConvert_SeqAIJ, 14873d1612f7SBarry Smith MatConvertSameType_SeqAIJ,0,0, 1488cddf8d76SBarry Smith MatILUFactor_SeqAIJ,0,0, 14897eb43aa7SLois Curfman McInnes MatGetSubMatrices_SeqAIJ,MatIncreaseOverlap_SeqAIJ, 1490682d7d0cSBarry Smith MatGetValues_SeqAIJ,0, 1491f0b747eeSBarry Smith MatPrintHelp_SeqAIJ, 14925a838052SSatish Balay MatScale_SeqAIJ,0,0, 14936945ee14SBarry Smith MatILUDTFactor_SeqAIJ, 14946945ee14SBarry Smith MatGetBlockSize_SeqAIJ, 14953b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 14963b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 14973b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 1498a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 1499a93ec695SBarry Smith MatFDColoringCreate_SeqAIJ, 1500a93ec695SBarry Smith MatColoringPatch_SeqAIJ}; 150117ab2063SBarry Smith 150217ab2063SBarry Smith extern int MatUseSuperLU_SeqAIJ(Mat); 150317ab2063SBarry Smith extern int MatUseEssl_SeqAIJ(Mat); 150417ab2063SBarry Smith extern int MatUseDXML_SeqAIJ(Mat); 150517ab2063SBarry Smith 1506*026e39d0SSatish Balay #undef __FUNCTION__ 1507*026e39d0SSatish Balay #define __FUNCTION__ "MatCreateSeqAIJ" 150817ab2063SBarry Smith /*@C 1509682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 15100d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 15116e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 15122bd5e0b2SLois Curfman McInnes (or the array nzz). By setting these parameters accurately, performance 15132bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 151417ab2063SBarry Smith 151517ab2063SBarry Smith Input Parameters: 151617ab2063SBarry Smith . comm - MPI communicator, set to MPI_COMM_SELF 151717ab2063SBarry Smith . m - number of rows 151817ab2063SBarry Smith . n - number of columns 151917ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 15202bd5e0b2SLois Curfman McInnes . nzz - array containing the number of nonzeros in the various rows 15212bd5e0b2SLois Curfman McInnes (possibly different for each row) or PETSC_NULL 152217ab2063SBarry Smith 152317ab2063SBarry Smith Output Parameter: 1524416022c9SBarry Smith . A - the matrix 152517ab2063SBarry Smith 152617ab2063SBarry Smith Notes: 152717ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 152817ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 15290002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 153044cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 153117ab2063SBarry Smith 153217ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 1533a40aa06bSLois Curfman McInnes Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 15343d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 15356da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 153617ab2063SBarry Smith 1537682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 1538682d7d0cSBarry Smith improve numerical efficiency of Matrix vector products and solves. We 1539682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 15406c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 15416c7ebb05SLois Curfman McInnes 15426c7ebb05SLois Curfman McInnes Options Database Keys: 15436c7ebb05SLois Curfman McInnes $ -mat_aij_no_inode - Do not use inodes 15446e62573dSLois Curfman McInnes $ -mat_aij_inode_limit <limit> - Set inode limit. 15456e62573dSLois Curfman McInnes $ (max limit=5) 15466e62573dSLois Curfman McInnes $ -mat_aij_oneindex - Internally use indexing starting at 1 15476e62573dSLois Curfman McInnes $ rather than 0. Note: When calling MatSetValues(), 15486e62573dSLois Curfman McInnes $ the user still MUST index entries starting at 0! 154917ab2063SBarry Smith 155017ab2063SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues() 155117ab2063SBarry Smith @*/ 1552416022c9SBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,int *nnz, Mat *A) 155317ab2063SBarry Smith { 1554416022c9SBarry Smith Mat B; 1555416022c9SBarry Smith Mat_SeqAIJ *b; 15566945ee14SBarry Smith int i, len, ierr, flg,size; 15576945ee14SBarry Smith 15586945ee14SBarry Smith MPI_Comm_size(comm,&size); 15596945ee14SBarry Smith if (size > 1) SETERRQ(1,"MatCreateSeqAIJ:Comm must be of size 1"); 1560d5d45c9bSBarry Smith 1561416022c9SBarry Smith *A = 0; 15620452661fSBarry Smith PetscHeaderCreate(B,_Mat,MAT_COOKIE,MATSEQAIJ,comm); 1563416022c9SBarry Smith PLogObjectCreate(B); 15640452661fSBarry Smith B->data = (void *) (b = PetscNew(Mat_SeqAIJ)); CHKPTRQ(b); 156544cd7ae7SLois Curfman McInnes PetscMemzero(b,sizeof(Mat_SeqAIJ)); 1566416022c9SBarry Smith PetscMemcpy(&B->ops,&MatOps,sizeof(struct _MatOps)); 1567416022c9SBarry Smith B->destroy = MatDestroy_SeqAIJ; 1568416022c9SBarry Smith B->view = MatView_SeqAIJ; 1569416022c9SBarry Smith B->factor = 0; 1570416022c9SBarry Smith B->lupivotthreshold = 1.0; 157190f02eecSBarry Smith B->mapping = 0; 15727a743949SBarry Smith ierr = OptionsGetDouble(PETSC_NULL,"-mat_lu_pivotthreshold",&B->lupivotthreshold, 157369957df2SSatish Balay &flg); CHKERRQ(ierr); 15747a743949SBarry Smith b->ilu_preserve_row_sums = PETSC_FALSE; 15757a743949SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-pc_ilu_preserve_row_sums", 15767a743949SBarry Smith (int*) &b->ilu_preserve_row_sums); CHKERRQ(ierr); 1577416022c9SBarry Smith b->row = 0; 1578416022c9SBarry Smith b->col = 0; 1579416022c9SBarry Smith b->indexshift = 0; 1580b810aeb4SBarry Smith b->reallocs = 0; 158169957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_oneindex", &flg); CHKERRQ(ierr); 158269957df2SSatish Balay if (flg) b->indexshift = -1; 158317ab2063SBarry Smith 158444cd7ae7SLois Curfman McInnes b->m = m; B->m = m; B->M = m; 158544cd7ae7SLois Curfman McInnes b->n = n; B->n = n; B->N = n; 15860452661fSBarry Smith b->imax = (int *) PetscMalloc( (m+1)*sizeof(int) ); CHKPTRQ(b->imax); 1587b4fd4287SBarry Smith if (nnz == PETSC_NULL) { 15887b8455f0SLois Curfman McInnes if (nz == PETSC_DEFAULT) nz = 10; 15897b8455f0SLois Curfman McInnes else if (nz <= 0) nz = 1; 1590416022c9SBarry Smith for ( i=0; i<m; i++ ) b->imax[i] = nz; 159117ab2063SBarry Smith nz = nz*m; 159217ab2063SBarry Smith } 159317ab2063SBarry Smith else { 159417ab2063SBarry Smith nz = 0; 1595416022c9SBarry Smith for ( i=0; i<m; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];} 159617ab2063SBarry Smith } 159717ab2063SBarry Smith 159817ab2063SBarry Smith /* allocate the matrix space */ 1599416022c9SBarry Smith len = nz*(sizeof(int) + sizeof(Scalar)) + (b->m+1)*sizeof(int); 16000452661fSBarry Smith b->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(b->a); 1601416022c9SBarry Smith b->j = (int *) (b->a + nz); 1602cddf8d76SBarry Smith PetscMemzero(b->j,nz*sizeof(int)); 1603416022c9SBarry Smith b->i = b->j + nz; 1604416022c9SBarry Smith b->singlemalloc = 1; 160517ab2063SBarry Smith 1606416022c9SBarry Smith b->i[0] = -b->indexshift; 160717ab2063SBarry Smith for (i=1; i<m+1; i++) { 1608416022c9SBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 160917ab2063SBarry Smith } 161017ab2063SBarry Smith 1611416022c9SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 16120452661fSBarry Smith b->ilen = (int *) PetscMalloc((m+1)*sizeof(int)); 1613416022c9SBarry Smith PLogObjectMemory(B,len+2*(m+1)*sizeof(int)+sizeof(struct _Mat)+sizeof(Mat_SeqAIJ)); 1614416022c9SBarry Smith for ( i=0; i<b->m; i++ ) { b->ilen[i] = 0;} 161517ab2063SBarry Smith 1616416022c9SBarry Smith b->nz = 0; 1617416022c9SBarry Smith b->maxnz = nz; 1618416022c9SBarry Smith b->sorted = 0; 1619416022c9SBarry Smith b->roworiented = 1; 1620416022c9SBarry Smith b->nonew = 0; 1621416022c9SBarry Smith b->diag = 0; 1622416022c9SBarry Smith b->solve_work = 0; 162371bd300dSLois Curfman McInnes b->spptr = 0; 1624754ec7b1SSatish Balay b->inode.node_count = 0; 1625754ec7b1SSatish Balay b->inode.size = 0; 16266c7ebb05SLois Curfman McInnes b->inode.limit = 5; 16276c7ebb05SLois Curfman McInnes b->inode.max_limit = 5; 16284e220ebcSLois Curfman McInnes B->info.nz_unneeded = (double)b->maxnz; 162917ab2063SBarry Smith 1630416022c9SBarry Smith *A = B; 16314e220ebcSLois Curfman McInnes 16324b14c69eSBarry Smith /* SuperLU is not currently supported through PETSc */ 16334b14c69eSBarry Smith #if defined(HAVE_SUPERLU) 163469957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_superlu", &flg); CHKERRQ(ierr); 163569957df2SSatish Balay if (flg) { ierr = MatUseSuperLU_SeqAIJ(B); CHKERRQ(ierr); } 16364b14c69eSBarry Smith #endif 163769957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_essl", &flg); CHKERRQ(ierr); 163869957df2SSatish Balay if (flg) { ierr = MatUseEssl_SeqAIJ(B); CHKERRQ(ierr); } 163969957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_dxml", &flg); CHKERRQ(ierr); 164069957df2SSatish Balay if (flg) { 1641416022c9SBarry Smith if (!b->indexshift) SETERRQ(1,"MatCreateSeqAIJ:need -mat_aij_oneindex with -mat_aij_dxml"); 1642416022c9SBarry Smith ierr = MatUseDXML_SeqAIJ(B); CHKERRQ(ierr); 164317ab2063SBarry Smith } 164469957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr); 164569957df2SSatish Balay if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); } 164617ab2063SBarry Smith return 0; 164717ab2063SBarry Smith } 164817ab2063SBarry Smith 1649*026e39d0SSatish Balay #undef __FUNCTION__ 1650*026e39d0SSatish Balay #define __FUNCTION__ "MatConvertSameType_SeqAIJ" 16513d1612f7SBarry Smith int MatConvertSameType_SeqAIJ(Mat A,Mat *B,int cpvalues) 165217ab2063SBarry Smith { 1653416022c9SBarry Smith Mat C; 1654416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ *) A->data; 165508480c60SBarry Smith int i,len, m = a->m,shift = a->indexshift; 165617ab2063SBarry Smith 16574043dd9cSLois Curfman McInnes *B = 0; 16580452661fSBarry Smith PetscHeaderCreate(C,_Mat,MAT_COOKIE,MATSEQAIJ,A->comm); 1659416022c9SBarry Smith PLogObjectCreate(C); 16600452661fSBarry Smith C->data = (void *) (c = PetscNew(Mat_SeqAIJ)); CHKPTRQ(c); 166141c01911SSatish Balay PetscMemcpy(&C->ops,&A->ops,sizeof(struct _MatOps)); 1662416022c9SBarry Smith C->destroy = MatDestroy_SeqAIJ; 1663416022c9SBarry Smith C->view = MatView_SeqAIJ; 1664416022c9SBarry Smith C->factor = A->factor; 1665416022c9SBarry Smith c->row = 0; 1666416022c9SBarry Smith c->col = 0; 1667416022c9SBarry Smith c->indexshift = shift; 1668c456f294SBarry Smith C->assembled = PETSC_TRUE; 166917ab2063SBarry Smith 167044cd7ae7SLois Curfman McInnes c->m = C->m = a->m; 167144cd7ae7SLois Curfman McInnes c->n = C->n = a->n; 167244cd7ae7SLois Curfman McInnes C->M = a->m; 167344cd7ae7SLois Curfman McInnes C->N = a->n; 167417ab2063SBarry Smith 16750452661fSBarry Smith c->imax = (int *) PetscMalloc((m+1)*sizeof(int)); CHKPTRQ(c->imax); 16760452661fSBarry Smith c->ilen = (int *) PetscMalloc((m+1)*sizeof(int)); CHKPTRQ(c->ilen); 167717ab2063SBarry Smith for ( i=0; i<m; i++ ) { 1678416022c9SBarry Smith c->imax[i] = a->imax[i]; 1679416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 168017ab2063SBarry Smith } 168117ab2063SBarry Smith 168217ab2063SBarry Smith /* allocate the matrix space */ 1683416022c9SBarry Smith c->singlemalloc = 1; 1684416022c9SBarry Smith len = (m+1)*sizeof(int)+(a->i[m])*(sizeof(Scalar)+sizeof(int)); 16850452661fSBarry Smith c->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(c->a); 1686416022c9SBarry Smith c->j = (int *) (c->a + a->i[m] + shift); 1687416022c9SBarry Smith c->i = c->j + a->i[m] + shift; 1688416022c9SBarry Smith PetscMemcpy(c->i,a->i,(m+1)*sizeof(int)); 168917ab2063SBarry Smith if (m > 0) { 1690416022c9SBarry Smith PetscMemcpy(c->j,a->j,(a->i[m]+shift)*sizeof(int)); 169108480c60SBarry Smith if (cpvalues == COPY_VALUES) { 1692416022c9SBarry Smith PetscMemcpy(c->a,a->a,(a->i[m]+shift)*sizeof(Scalar)); 169317ab2063SBarry Smith } 169408480c60SBarry Smith } 169517ab2063SBarry Smith 1696416022c9SBarry Smith PLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _Mat)+sizeof(Mat_SeqAIJ)); 1697416022c9SBarry Smith c->sorted = a->sorted; 1698416022c9SBarry Smith c->roworiented = a->roworiented; 1699416022c9SBarry Smith c->nonew = a->nonew; 17007a743949SBarry Smith c->ilu_preserve_row_sums = a->ilu_preserve_row_sums; 170117ab2063SBarry Smith 1702416022c9SBarry Smith if (a->diag) { 17030452661fSBarry Smith c->diag = (int *) PetscMalloc( (m+1)*sizeof(int) ); CHKPTRQ(c->diag); 1704416022c9SBarry Smith PLogObjectMemory(C,(m+1)*sizeof(int)); 170517ab2063SBarry Smith for ( i=0; i<m; i++ ) { 1706416022c9SBarry Smith c->diag[i] = a->diag[i]; 170717ab2063SBarry Smith } 170817ab2063SBarry Smith } 1709416022c9SBarry Smith else c->diag = 0; 17106c7ebb05SLois Curfman McInnes c->inode.limit = a->inode.limit; 17116c7ebb05SLois Curfman McInnes c->inode.max_limit = a->inode.max_limit; 1712754ec7b1SSatish Balay if (a->inode.size){ 1713daed632aSSatish Balay c->inode.size = (int *) PetscMalloc( (m+1)*sizeof(int) ); CHKPTRQ(c->inode.size); 1714754ec7b1SSatish Balay c->inode.node_count = a->inode.node_count; 1715daed632aSSatish Balay PetscMemcpy( c->inode.size, a->inode.size, (m+1)*sizeof(int)); 1716754ec7b1SSatish Balay } else { 1717754ec7b1SSatish Balay c->inode.size = 0; 1718754ec7b1SSatish Balay c->inode.node_count = 0; 1719754ec7b1SSatish Balay } 1720416022c9SBarry Smith c->nz = a->nz; 1721416022c9SBarry Smith c->maxnz = a->maxnz; 1722416022c9SBarry Smith c->solve_work = 0; 172376dd722bSSatish Balay c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 1724754ec7b1SSatish Balay 1725416022c9SBarry Smith *B = C; 172617ab2063SBarry Smith return 0; 172717ab2063SBarry Smith } 172817ab2063SBarry Smith 1729*026e39d0SSatish Balay #undef __FUNCTION__ 1730*026e39d0SSatish Balay #define __FUNCTION__ "MatLoad_SeqAIJ" 173119bcc07fSBarry Smith int MatLoad_SeqAIJ(Viewer viewer,MatType type,Mat *A) 173217ab2063SBarry Smith { 1733416022c9SBarry Smith Mat_SeqAIJ *a; 1734416022c9SBarry Smith Mat B; 173517699dbbSLois Curfman McInnes int i, nz, ierr, fd, header[4],size,*rowlengths = 0,M,N,shift; 1736bcd2baecSBarry Smith MPI_Comm comm; 173717ab2063SBarry Smith 173819bcc07fSBarry Smith PetscObjectGetComm((PetscObject) viewer,&comm); 173917699dbbSLois Curfman McInnes MPI_Comm_size(comm,&size); 174017699dbbSLois Curfman McInnes if (size > 1) SETERRQ(1,"MatLoad_SeqAIJ:view must have one processor"); 174190ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 174277c4ece6SBarry Smith ierr = PetscBinaryRead(fd,header,4,BINARY_INT); CHKERRQ(ierr); 174348d91487SBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(1,"MatLoad_SeqAIJ:not matrix object in file"); 174417ab2063SBarry Smith M = header[1]; N = header[2]; nz = header[3]; 174517ab2063SBarry Smith 174617ab2063SBarry Smith /* read in row lengths */ 17470452661fSBarry Smith rowlengths = (int*) PetscMalloc( M*sizeof(int) ); CHKPTRQ(rowlengths); 174877c4ece6SBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,BINARY_INT); CHKERRQ(ierr); 174917ab2063SBarry Smith 175017ab2063SBarry Smith /* create our matrix */ 1751416022c9SBarry Smith ierr = MatCreateSeqAIJ(comm,M,N,0,rowlengths,A); CHKERRQ(ierr); 1752416022c9SBarry Smith B = *A; 1753416022c9SBarry Smith a = (Mat_SeqAIJ *) B->data; 1754416022c9SBarry Smith shift = a->indexshift; 175517ab2063SBarry Smith 175617ab2063SBarry Smith /* read in column indices and adjust for Fortran indexing*/ 175777c4ece6SBarry Smith ierr = PetscBinaryRead(fd,a->j,nz,BINARY_INT); CHKERRQ(ierr); 175817ab2063SBarry Smith if (shift) { 175917ab2063SBarry Smith for ( i=0; i<nz; i++ ) { 1760416022c9SBarry Smith a->j[i] += 1; 176117ab2063SBarry Smith } 176217ab2063SBarry Smith } 176317ab2063SBarry Smith 176417ab2063SBarry Smith /* read in nonzero values */ 176577c4ece6SBarry Smith ierr = PetscBinaryRead(fd,a->a,nz,BINARY_SCALAR); CHKERRQ(ierr); 176617ab2063SBarry Smith 176717ab2063SBarry Smith /* set matrix "i" values */ 1768416022c9SBarry Smith a->i[0] = -shift; 176917ab2063SBarry Smith for ( i=1; i<= M; i++ ) { 1770416022c9SBarry Smith a->i[i] = a->i[i-1] + rowlengths[i-1]; 1771416022c9SBarry Smith a->ilen[i-1] = rowlengths[i-1]; 177217ab2063SBarry Smith } 17730452661fSBarry Smith PetscFree(rowlengths); 177417ab2063SBarry Smith 17756d4a8577SBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 17766d4a8577SBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 177717ab2063SBarry Smith return 0; 177817ab2063SBarry Smith } 177917ab2063SBarry Smith 1780*026e39d0SSatish Balay #undef __FUNCTION__ 1781*026e39d0SSatish Balay #define __FUNCTION__ "MatEqual_SeqAIJ" 1782686e14cbSSatish Balay static int MatEqual_SeqAIJ(Mat A,Mat B, PetscTruth* flg) 17837264ac53SSatish Balay { 17847264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data, *b = (Mat_SeqAIJ *)B->data; 17857264ac53SSatish Balay 1786bcd2baecSBarry Smith if (B->type !=MATSEQAIJ)SETERRQ(1,"MatEqual_SeqAIJ:Matrices must be same type"); 17877264ac53SSatish Balay 17887264ac53SSatish Balay /* If the matrix dimensions are not equal, or no of nonzeros or shift */ 17897264ac53SSatish Balay if ((a->m != b->m ) || (a->n !=b->n) ||( a->nz != b->nz)|| 1790bcd2baecSBarry Smith (a->indexshift != b->indexshift)) { 179177c4ece6SBarry Smith *flg = PETSC_FALSE; return 0; 1792bcd2baecSBarry Smith } 17937264ac53SSatish Balay 17947264ac53SSatish Balay /* if the a->i are the same */ 1795bcd2baecSBarry Smith if (PetscMemcmp(a->i,b->i, (a->n+1)*sizeof(int))) { 179677c4ece6SBarry Smith *flg = PETSC_FALSE; return 0; 17977264ac53SSatish Balay } 17987264ac53SSatish Balay 17997264ac53SSatish Balay /* if a->j are the same */ 1800bcd2baecSBarry Smith if (PetscMemcmp(a->j, b->j, (a->nz)*sizeof(int))) { 180177c4ece6SBarry Smith *flg = PETSC_FALSE; return 0; 1802bcd2baecSBarry Smith } 1803bcd2baecSBarry Smith 1804bcd2baecSBarry Smith /* if a->a are the same */ 180519bcc07fSBarry Smith if (PetscMemcmp(a->a, b->a, (a->nz)*sizeof(Scalar))) { 180677c4ece6SBarry Smith *flg = PETSC_FALSE; return 0; 18077264ac53SSatish Balay } 180877c4ece6SBarry Smith *flg = PETSC_TRUE; 18097264ac53SSatish Balay return 0; 18107264ac53SSatish Balay 18117264ac53SSatish Balay } 1812