16d84be18SBarry Smith 26945ee14SBarry Smith 317ab2063SBarry Smith #ifndef lint 4*a93ec695SBarry Smith static char vcid[] = "$Id: aij.c,v 1.187 1996/09/23 16:21:45 bsmith Exp bsmith $"; 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 */ 20a2ce50c7SBarry Smith int MatILUDTFactor_SeqAIJ(Mat A,double dt,int maxnz,IS row,IS col,Mat *fact) 21a2ce50c7SBarry Smith { 22a2ce50c7SBarry Smith /* Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; */ 23a2ce50c7SBarry Smith int ierr = 1; 24a2ce50c7SBarry Smith 25a2ce50c7SBarry Smith SETERRQ(ierr,"MatILUDTFactor_SeqAIJ:Not implemented"); 26a2ce50c7SBarry Smith } 27a2ce50c7SBarry Smith 28bcd2baecSBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**); 2917ab2063SBarry Smith 303b2fbd54SBarry Smith static int MatGetRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja, 316945ee14SBarry Smith PetscTruth *done) 3217ab2063SBarry Smith { 33416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 346945ee14SBarry Smith int ierr,i,ishift; 3517ab2063SBarry Smith 366945ee14SBarry Smith *n = A->n; 376945ee14SBarry Smith if (!ia) return 0; 386945ee14SBarry Smith ishift = a->indexshift; 396945ee14SBarry Smith if (symmetric) { 406945ee14SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(a->n,a->i,a->j,ishift,oshift,ia,ja); CHKERRQ(ierr); 416945ee14SBarry Smith } else if (oshift == 0 && ishift == -1) { 426945ee14SBarry Smith int nz = a->i[a->n]; 433b2fbd54SBarry Smith /* malloc space and subtract 1 from i and j indices */ 443b2fbd54SBarry Smith *ia = (int *) PetscMalloc( (a->n+1)*sizeof(int) ); CHKPTRQ(*ia); 453b2fbd54SBarry Smith *ja = (int *) PetscMalloc( (nz+1)*sizeof(int) ); CHKPTRQ(*ja); 463b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) (*ja)[i] = a->j[i] - 1; 473b2fbd54SBarry Smith for ( i=0; i<a->n+1; i++ ) (*ia)[i] = a->i[i] - 1; 486945ee14SBarry Smith } else if (oshift == 1 && ishift == 0) { 496945ee14SBarry Smith int nz = a->i[a->n] + 1; 503b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 513b2fbd54SBarry Smith *ia = (int *) PetscMalloc( (a->n+1)*sizeof(int) ); CHKPTRQ(*ia); 523b2fbd54SBarry Smith *ja = (int *) PetscMalloc( (nz+1)*sizeof(int) ); CHKPTRQ(*ja); 533b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) (*ja)[i] = a->j[i] + 1; 543b2fbd54SBarry Smith for ( i=0; i<a->n+1; i++ ) (*ia)[i] = a->i[i] + 1; 556945ee14SBarry Smith } else { 566945ee14SBarry Smith *ia = a->i; *ja = a->j; 57a2ce50c7SBarry Smith } 58a2ce50c7SBarry Smith 59a2744918SBarry Smith return 0; 60a2744918SBarry Smith } 61a2744918SBarry Smith 623b2fbd54SBarry Smith static int MatRestoreRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja, 636945ee14SBarry Smith PetscTruth *done) 646945ee14SBarry Smith { 656945ee14SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 663b2fbd54SBarry Smith int ishift = a->indexshift; 676945ee14SBarry Smith 686945ee14SBarry Smith if (!ia) return 0; 693b2fbd54SBarry Smith if (symmetric || (oshift == 0 && ishift == -1) || (oshift == 1 && ishift == 0)) { 706945ee14SBarry Smith PetscFree(*ia); 716945ee14SBarry Smith PetscFree(*ja); 72bcd2baecSBarry Smith } 7317ab2063SBarry Smith return 0; 7417ab2063SBarry Smith } 7517ab2063SBarry Smith 763b2fbd54SBarry Smith static int MatGetColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja, 773b2fbd54SBarry Smith PetscTruth *done) 783b2fbd54SBarry Smith { 793b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 80*a93ec695SBarry Smith int ierr,i,ishift = a->indexshift,*collengths,*cia,*cja,n = A->n,m = A->m; 81*a93ec695SBarry Smith int nz = a->i[m]+ishift,row,*jj,mr,col; 823b2fbd54SBarry Smith 833b2fbd54SBarry Smith *nn = A->n; 843b2fbd54SBarry Smith if (!ia) return 0; 853b2fbd54SBarry Smith if (symmetric) { 863b2fbd54SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(a->n,a->i,a->j,ishift,oshift,ia,ja); CHKERRQ(ierr); 873b2fbd54SBarry Smith } else { 883b2fbd54SBarry Smith collengths = (int *) PetscMalloc( n*sizeof(int) ); CHKPTRQ(collengths); 893b2fbd54SBarry Smith PetscMemzero(collengths,n*sizeof(int)); 903b2fbd54SBarry Smith cia = (int *) PetscMalloc( (n+1)*sizeof(int) ); CHKPTRQ(cia); 91*a93ec695SBarry Smith cja = (int *) PetscMalloc( (nz+1)*sizeof(int) ); CHKPTRQ(cja); 923b2fbd54SBarry Smith jj = a->j; 933b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) { 943b2fbd54SBarry Smith collengths[jj[i] + ishift]++; 953b2fbd54SBarry Smith } 963b2fbd54SBarry Smith cia[0] = oshift; 973b2fbd54SBarry Smith for ( i=0; i<n; i++) { 983b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 993b2fbd54SBarry Smith } 1003b2fbd54SBarry Smith PetscMemzero(collengths,n*sizeof(int)); 1013b2fbd54SBarry Smith jj = a->j; 102*a93ec695SBarry Smith for ( row=0; row<m; row++ ) { 103*a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 104*a93ec695SBarry Smith for ( i=0; i<mr; i++ ) { 1053b2fbd54SBarry Smith col = *jj++ + ishift; 1063b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 1073b2fbd54SBarry Smith } 1083b2fbd54SBarry Smith } 1093b2fbd54SBarry Smith PetscFree(collengths); 1103b2fbd54SBarry Smith *ia = cia; *ja = cja; 1113b2fbd54SBarry Smith } 1123b2fbd54SBarry Smith 1133b2fbd54SBarry Smith return 0; 1143b2fbd54SBarry Smith } 1153b2fbd54SBarry Smith 1163b2fbd54SBarry Smith static int MatRestoreColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia, 1173b2fbd54SBarry Smith int **ja,PetscTruth *done) 1183b2fbd54SBarry Smith { 1193b2fbd54SBarry Smith if (!ia) return 0; 1203b2fbd54SBarry Smith 1213b2fbd54SBarry Smith PetscFree(*ia); 1223b2fbd54SBarry Smith PetscFree(*ja); 1233b2fbd54SBarry Smith 1243b2fbd54SBarry Smith return 0; 1253b2fbd54SBarry Smith } 1263b2fbd54SBarry Smith 127227d817aSBarry Smith #define CHUNKSIZE 15 12817ab2063SBarry Smith 12917ab2063SBarry Smith /* This version has row oriented v */ 130416022c9SBarry Smith static int MatSetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 13117ab2063SBarry Smith { 132416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 133416022c9SBarry Smith int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax, N, sorted = a->sorted; 1344b0e389bSBarry Smith int *imax = a->imax, *ai = a->i, *ailen = a->ilen,roworiented = a->roworiented; 135d5d45c9bSBarry Smith int *aj = a->j, nonew = a->nonew,shift = a->indexshift; 136416022c9SBarry Smith Scalar *ap,value, *aa = a->a; 13717ab2063SBarry Smith 13817ab2063SBarry Smith for ( k=0; k<m; k++ ) { /* loop over added rows */ 139416022c9SBarry Smith row = im[k]; 1403b2fbd54SBarry Smith #if defined(PETSC_BOPT_g) 14117ab2063SBarry Smith if (row < 0) SETERRQ(1,"MatSetValues_SeqAIJ:Negative row"); 142416022c9SBarry Smith if (row >= a->m) SETERRQ(1,"MatSetValues_SeqAIJ:Row too large"); 1433b2fbd54SBarry Smith #endif 14417ab2063SBarry Smith rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 14517ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 146416022c9SBarry Smith low = 0; 14717ab2063SBarry Smith for ( l=0; l<n; l++ ) { /* loop over added columns */ 1483b2fbd54SBarry Smith #if defined(PETSC_BOPT_g) 149416022c9SBarry Smith if (in[l] < 0) SETERRQ(1,"MatSetValues_SeqAIJ:Negative column"); 150416022c9SBarry Smith if (in[l] >= a->n) SETERRQ(1,"MatSetValues_SeqAIJ:Column too large"); 1513b2fbd54SBarry Smith #endif 1524b0e389bSBarry Smith col = in[l] - shift; 1534b0e389bSBarry Smith if (roworiented) { 1544b0e389bSBarry Smith value = *v++; 1554b0e389bSBarry Smith } 1564b0e389bSBarry Smith else { 1574b0e389bSBarry Smith value = v[k + l*m]; 1584b0e389bSBarry Smith } 159416022c9SBarry Smith if (!sorted) low = 0; high = nrow; 160416022c9SBarry Smith while (high-low > 5) { 161416022c9SBarry Smith t = (low+high)/2; 162416022c9SBarry Smith if (rp[t] > col) high = t; 163416022c9SBarry Smith else low = t; 16417ab2063SBarry Smith } 165416022c9SBarry Smith for ( i=low; i<high; i++ ) { 16617ab2063SBarry Smith if (rp[i] > col) break; 16717ab2063SBarry Smith if (rp[i] == col) { 168416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 16917ab2063SBarry Smith else ap[i] = value; 17017ab2063SBarry Smith goto noinsert; 17117ab2063SBarry Smith } 17217ab2063SBarry Smith } 17317ab2063SBarry Smith if (nonew) goto noinsert; 17417ab2063SBarry Smith if (nrow >= rmax) { 17517ab2063SBarry Smith /* there is no extra room in row, therefore enlarge */ 176416022c9SBarry Smith int new_nz = ai[a->m] + CHUNKSIZE,len,*new_i,*new_j; 17717ab2063SBarry Smith Scalar *new_a; 17817ab2063SBarry Smith 17917ab2063SBarry Smith /* malloc new storage space */ 180416022c9SBarry Smith len = new_nz*(sizeof(int)+sizeof(Scalar))+(a->m+1)*sizeof(int); 1810452661fSBarry Smith new_a = (Scalar *) PetscMalloc( len ); CHKPTRQ(new_a); 18217ab2063SBarry Smith new_j = (int *) (new_a + new_nz); 18317ab2063SBarry Smith new_i = new_j + new_nz; 18417ab2063SBarry Smith 18517ab2063SBarry Smith /* copy over old data into new slots */ 18617ab2063SBarry Smith for ( ii=0; ii<row+1; ii++ ) {new_i[ii] = ai[ii];} 187416022c9SBarry Smith for ( ii=row+1; ii<a->m+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;} 188416022c9SBarry Smith PetscMemcpy(new_j,aj,(ai[row]+nrow+shift)*sizeof(int)); 189416022c9SBarry Smith len = (new_nz - CHUNKSIZE - ai[row] - nrow - shift); 190416022c9SBarry Smith PetscMemcpy(new_j+ai[row]+shift+nrow+CHUNKSIZE,aj+ai[row]+shift+nrow, 19117ab2063SBarry Smith len*sizeof(int)); 192416022c9SBarry Smith PetscMemcpy(new_a,aa,(ai[row]+nrow+shift)*sizeof(Scalar)); 193416022c9SBarry Smith PetscMemcpy(new_a+ai[row]+shift+nrow+CHUNKSIZE,aa+ai[row]+shift+nrow, 19417ab2063SBarry Smith len*sizeof(Scalar)); 19517ab2063SBarry Smith /* free up old matrix storage */ 1960452661fSBarry Smith PetscFree(a->a); 1970452661fSBarry Smith if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);} 198416022c9SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 199416022c9SBarry Smith a->singlemalloc = 1; 20017ab2063SBarry Smith 20117ab2063SBarry Smith rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 202416022c9SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 203416022c9SBarry Smith PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + sizeof(Scalar))); 204416022c9SBarry Smith a->maxnz += CHUNKSIZE; 205b810aeb4SBarry Smith a->reallocs++; 20617ab2063SBarry Smith } 207416022c9SBarry Smith N = nrow++ - 1; a->nz++; 208416022c9SBarry Smith /* shift up all the later entries in this row */ 209416022c9SBarry Smith for ( ii=N; ii>=i; ii-- ) { 21017ab2063SBarry Smith rp[ii+1] = rp[ii]; 21117ab2063SBarry Smith ap[ii+1] = ap[ii]; 21217ab2063SBarry Smith } 21317ab2063SBarry Smith rp[i] = col; 21417ab2063SBarry Smith ap[i] = value; 21517ab2063SBarry Smith noinsert:; 216416022c9SBarry Smith low = i + 1; 21717ab2063SBarry Smith } 21817ab2063SBarry Smith ailen[row] = nrow; 21917ab2063SBarry Smith } 22017ab2063SBarry Smith return 0; 22117ab2063SBarry Smith } 22217ab2063SBarry Smith 2237eb43aa7SLois Curfman McInnes static int MatGetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v) 2247eb43aa7SLois Curfman McInnes { 2257eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 226b49de8d1SLois Curfman McInnes int *rp, k, low, high, t, row, nrow, i, col, l, *aj = a->j; 2277eb43aa7SLois Curfman McInnes int *ai = a->i, *ailen = a->ilen, shift = a->indexshift; 2287eb43aa7SLois Curfman McInnes Scalar *ap, *aa = a->a, zero = 0.0; 2297eb43aa7SLois Curfman McInnes 2307eb43aa7SLois Curfman McInnes for ( k=0; k<m; k++ ) { /* loop over rows */ 2317eb43aa7SLois Curfman McInnes row = im[k]; 2327eb43aa7SLois Curfman McInnes if (row < 0) SETERRQ(1,"MatGetValues_SeqAIJ:Negative row"); 2337eb43aa7SLois Curfman McInnes if (row >= a->m) SETERRQ(1,"MatGetValues_SeqAIJ:Row too large"); 2347eb43aa7SLois Curfman McInnes rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 2357eb43aa7SLois Curfman McInnes nrow = ailen[row]; 2367eb43aa7SLois Curfman McInnes for ( l=0; l<n; l++ ) { /* loop over columns */ 2377eb43aa7SLois Curfman McInnes if (in[l] < 0) SETERRQ(1,"MatGetValues_SeqAIJ:Negative column"); 2387eb43aa7SLois Curfman McInnes if (in[l] >= a->n) SETERRQ(1,"MatGetValues_SeqAIJ:Column too large"); 2397eb43aa7SLois Curfman McInnes col = in[l] - shift; 2407eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 2417eb43aa7SLois Curfman McInnes while (high-low > 5) { 2427eb43aa7SLois Curfman McInnes t = (low+high)/2; 2437eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 2447eb43aa7SLois Curfman McInnes else low = t; 2457eb43aa7SLois Curfman McInnes } 2467eb43aa7SLois Curfman McInnes for ( i=low; i<high; i++ ) { 2477eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 2487eb43aa7SLois Curfman McInnes if (rp[i] == col) { 249b49de8d1SLois Curfman McInnes *v++ = ap[i]; 2507eb43aa7SLois Curfman McInnes goto finished; 2517eb43aa7SLois Curfman McInnes } 2527eb43aa7SLois Curfman McInnes } 253b49de8d1SLois Curfman McInnes *v++ = zero; 2547eb43aa7SLois Curfman McInnes finished:; 2557eb43aa7SLois Curfman McInnes } 2567eb43aa7SLois Curfman McInnes } 2577eb43aa7SLois Curfman McInnes return 0; 2587eb43aa7SLois Curfman McInnes } 2597eb43aa7SLois Curfman McInnes 26017ab2063SBarry Smith #include "draw.h" 26117ab2063SBarry Smith #include "pinclude/pviewer.h" 26277c4ece6SBarry Smith #include "sys.h" 26317ab2063SBarry Smith 264416022c9SBarry Smith static int MatView_SeqAIJ_Binary(Mat A,Viewer viewer) 26517ab2063SBarry Smith { 266416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 267416022c9SBarry Smith int i, fd, *col_lens, ierr; 26817ab2063SBarry Smith 26990ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 2700452661fSBarry Smith col_lens = (int *) PetscMalloc( (4+a->m)*sizeof(int) ); CHKPTRQ(col_lens); 271416022c9SBarry Smith col_lens[0] = MAT_COOKIE; 272416022c9SBarry Smith col_lens[1] = a->m; 273416022c9SBarry Smith col_lens[2] = a->n; 274416022c9SBarry Smith col_lens[3] = a->nz; 275416022c9SBarry Smith 276416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 277416022c9SBarry Smith for ( i=0; i<a->m; i++ ) { 278416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 27917ab2063SBarry Smith } 28077c4ece6SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+a->m,BINARY_INT,1); CHKERRQ(ierr); 2810452661fSBarry Smith PetscFree(col_lens); 282416022c9SBarry Smith 283416022c9SBarry Smith /* store column indices (zero start index) */ 284416022c9SBarry Smith if (a->indexshift) { 285416022c9SBarry Smith for ( i=0; i<a->nz; i++ ) a->j[i]--; 28617ab2063SBarry Smith } 28777c4ece6SBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,BINARY_INT,0); CHKERRQ(ierr); 288416022c9SBarry Smith if (a->indexshift) { 289416022c9SBarry Smith for ( i=0; i<a->nz; i++ ) a->j[i]++; 29017ab2063SBarry Smith } 291416022c9SBarry Smith 292416022c9SBarry Smith /* store nonzero values */ 29377c4ece6SBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,BINARY_SCALAR,0); CHKERRQ(ierr); 29417ab2063SBarry Smith return 0; 29517ab2063SBarry Smith } 296416022c9SBarry Smith 297416022c9SBarry Smith static int MatView_SeqAIJ_ASCII(Mat A,Viewer viewer) 298416022c9SBarry Smith { 299416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 300496e697eSBarry Smith int ierr, i,j, m = a->m, shift = a->indexshift, format, flg1,flg2; 30117ab2063SBarry Smith FILE *fd; 30217ab2063SBarry Smith char *outputname; 30317ab2063SBarry Smith 30490ace30eSBarry Smith ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr); 305416022c9SBarry Smith ierr = ViewerFileGetOutputname_Private(viewer,&outputname); CHKERRQ(ierr); 30690ace30eSBarry Smith ierr = ViewerGetFormat(viewer,&format); 307*a93ec695SBarry Smith if (format == VIEWER_FORMAT_ASCII_INFO) { 30895e01e2fSLois Curfman McInnes return 0; 30995e01e2fSLois Curfman McInnes } 310*a93ec695SBarry Smith else if (format == VIEWER_FORMAT_ASCII_INFO_LONG) { 311496e697eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_aij_no_inode",&flg1); CHKERRQ(ierr); 312496e697eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg2); CHKERRQ(ierr); 313496e697eSBarry Smith if (flg1 || flg2) fprintf(fd," not using I-node routines\n"); 31495e01e2fSLois Curfman McInnes else fprintf(fd," using I-node routines: found %d nodes, limit used is %d\n", 31595e01e2fSLois Curfman McInnes a->inode.node_count,a->inode.limit); 31617ab2063SBarry Smith } 317*a93ec695SBarry Smith else if (format == VIEWER_FORMAT_ASCII_MATLAB) { 318416022c9SBarry Smith fprintf(fd,"%% Size = %d %d \n",m,a->n); 3194e220ebcSLois Curfman McInnes fprintf(fd,"%% Nonzeros = %d \n",a->nz); 3204e220ebcSLois Curfman McInnes fprintf(fd,"zzz = zeros(%d,3);\n",a->nz); 32117ab2063SBarry Smith fprintf(fd,"zzz = [\n"); 32217ab2063SBarry Smith 32317ab2063SBarry Smith for (i=0; i<m; i++) { 324416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 32517ab2063SBarry Smith #if defined(PETSC_COMPLEX) 3266945ee14SBarry Smith fprintf(fd,"%d %d %18.16e + %18.16e i \n",i+1,a->j[j]+!shift,real(a->a[j]), 327416022c9SBarry Smith imag(a->a[j])); 32817ab2063SBarry Smith #else 3297a743949SBarry Smith fprintf(fd,"%d %d %18.16e\n", i+1, a->j[j]+!shift, a->a[j]); 33017ab2063SBarry Smith #endif 33117ab2063SBarry Smith } 33217ab2063SBarry Smith } 33317ab2063SBarry Smith fprintf(fd,"];\n %s = spconvert(zzz);\n",outputname); 33417ab2063SBarry Smith } 335*a93ec695SBarry Smith else if (format == VIEWER_FORMAT_ASCII_COMMON) { 33644cd7ae7SLois Curfman McInnes for ( i=0; i<m; i++ ) { 33744cd7ae7SLois Curfman McInnes fprintf(fd,"row %d:",i); 33844cd7ae7SLois Curfman McInnes for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 33944cd7ae7SLois Curfman McInnes #if defined(PETSC_COMPLEX) 34044cd7ae7SLois Curfman McInnes if (imag(a->a[j]) != 0.0 && real(a->a[j]) != 0.0) 34144cd7ae7SLois Curfman McInnes fprintf(fd," %d %g + %g i",a->j[j]+shift,real(a->a[j]),imag(a->a[j])); 34244cd7ae7SLois Curfman McInnes else if (real(a->a[j]) != 0.0) 34344cd7ae7SLois Curfman McInnes fprintf(fd," %d %g ",a->j[j]+shift,real(a->a[j])); 34444cd7ae7SLois Curfman McInnes #else 34544cd7ae7SLois Curfman McInnes if (a->a[j] != 0.0) fprintf(fd," %d %g ",a->j[j]+shift,a->a[j]); 34644cd7ae7SLois Curfman McInnes #endif 34744cd7ae7SLois Curfman McInnes } 34844cd7ae7SLois Curfman McInnes fprintf(fd,"\n"); 34944cd7ae7SLois Curfman McInnes } 35044cd7ae7SLois Curfman McInnes } 35117ab2063SBarry Smith else { 35217ab2063SBarry Smith for ( i=0; i<m; i++ ) { 35317ab2063SBarry Smith fprintf(fd,"row %d:",i); 354416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 35517ab2063SBarry Smith #if defined(PETSC_COMPLEX) 356416022c9SBarry Smith if (imag(a->a[j]) != 0.0) { 357416022c9SBarry Smith fprintf(fd," %d %g + %g i",a->j[j]+shift,real(a->a[j]),imag(a->a[j])); 35817ab2063SBarry Smith } 35917ab2063SBarry Smith else { 360416022c9SBarry Smith fprintf(fd," %d %g ",a->j[j]+shift,real(a->a[j])); 36117ab2063SBarry Smith } 36217ab2063SBarry Smith #else 363416022c9SBarry Smith fprintf(fd," %d %g ",a->j[j]+shift,a->a[j]); 36417ab2063SBarry Smith #endif 36517ab2063SBarry Smith } 36617ab2063SBarry Smith fprintf(fd,"\n"); 36717ab2063SBarry Smith } 36817ab2063SBarry Smith } 36917ab2063SBarry Smith fflush(fd); 370416022c9SBarry Smith return 0; 371416022c9SBarry Smith } 372416022c9SBarry Smith 373416022c9SBarry Smith static int MatView_SeqAIJ_Draw(Mat A,Viewer viewer) 374416022c9SBarry Smith { 375416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 376cddf8d76SBarry Smith int ierr, i,j, m = a->m, shift = a->indexshift,pause,color; 377cddf8d76SBarry Smith double xl,yl,xr,yr,w,h,xc,yc,scale = 1.0,x_l,x_r,y_l,y_r; 378bcd2baecSBarry Smith Draw draw; 379cddf8d76SBarry Smith DrawButton button; 38019bcc07fSBarry Smith PetscTruth isnull; 381cddf8d76SBarry Smith 382bcd2baecSBarry Smith ViewerDrawGetDraw(viewer,&draw); 38319bcc07fSBarry Smith ierr = DrawIsNull(draw,&isnull); CHKERRQ(ierr); if (isnull) return 0; 38419bcc07fSBarry Smith 385416022c9SBarry Smith xr = a->n; yr = a->m; h = yr/10.0; w = xr/10.0; 386416022c9SBarry Smith xr += w; yr += h; xl = -w; yl = -h; 387416022c9SBarry Smith ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr); 388416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 389cddf8d76SBarry Smith color = DRAW_BLUE; 390416022c9SBarry Smith for ( i=0; i<m; i++ ) { 391cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 392416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 393cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 394cddf8d76SBarry Smith #if defined(PETSC_COMPLEX) 395cddf8d76SBarry Smith if (real(a->a[j]) >= 0.) continue; 396cddf8d76SBarry Smith #else 397cddf8d76SBarry Smith if (a->a[j] >= 0.) continue; 398cddf8d76SBarry Smith #endif 399cddf8d76SBarry Smith DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color); 400cddf8d76SBarry Smith } 401cddf8d76SBarry Smith } 402cddf8d76SBarry Smith color = DRAW_CYAN; 403cddf8d76SBarry Smith for ( i=0; i<m; i++ ) { 404cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 405cddf8d76SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 406cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 407cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 408cddf8d76SBarry Smith DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color); 409cddf8d76SBarry Smith } 410cddf8d76SBarry Smith } 411cddf8d76SBarry Smith color = DRAW_RED; 412cddf8d76SBarry Smith for ( i=0; i<m; i++ ) { 413cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 414cddf8d76SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 415cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 416cddf8d76SBarry Smith #if defined(PETSC_COMPLEX) 417cddf8d76SBarry Smith if (real(a->a[j]) <= 0.) continue; 418cddf8d76SBarry Smith #else 419cddf8d76SBarry Smith if (a->a[j] <= 0.) continue; 420cddf8d76SBarry Smith #endif 421cddf8d76SBarry Smith DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color); 422416022c9SBarry Smith } 423416022c9SBarry Smith } 424416022c9SBarry Smith DrawFlush(draw); 425cddf8d76SBarry Smith DrawGetPause(draw,&pause); 426cddf8d76SBarry Smith if (pause >= 0) { PetscSleep(pause); return 0;} 427cddf8d76SBarry Smith 428cddf8d76SBarry Smith /* allow the matrix to zoom or shrink */ 4296945ee14SBarry Smith ierr = DrawCheckResizedWindow(draw); 430cddf8d76SBarry Smith ierr = DrawGetMouseButton(draw,&button,&xc,&yc,0,0); 431cddf8d76SBarry Smith while (button != BUTTON_RIGHT) { 432cddf8d76SBarry Smith DrawClear(draw); 433cddf8d76SBarry Smith if (button == BUTTON_LEFT) scale = .5; 434cddf8d76SBarry Smith else if (button == BUTTON_CENTER) scale = 2.; 435cddf8d76SBarry Smith xl = scale*(xl + w - xc) + xc - w*scale; 436cddf8d76SBarry Smith xr = scale*(xr - w - xc) + xc + w*scale; 437cddf8d76SBarry Smith yl = scale*(yl + h - yc) + yc - h*scale; 438cddf8d76SBarry Smith yr = scale*(yr - h - yc) + yc + h*scale; 439cddf8d76SBarry Smith w *= scale; h *= scale; 440cddf8d76SBarry Smith ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr); 441cddf8d76SBarry Smith color = DRAW_BLUE; 442cddf8d76SBarry Smith for ( i=0; i<m; i++ ) { 443cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 444cddf8d76SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 445cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 446cddf8d76SBarry Smith #if defined(PETSC_COMPLEX) 447cddf8d76SBarry Smith if (real(a->a[j]) >= 0.) continue; 448cddf8d76SBarry Smith #else 449cddf8d76SBarry Smith if (a->a[j] >= 0.) continue; 450cddf8d76SBarry Smith #endif 451cddf8d76SBarry Smith DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color); 452cddf8d76SBarry Smith } 453cddf8d76SBarry Smith } 454cddf8d76SBarry Smith color = DRAW_CYAN; 455cddf8d76SBarry Smith for ( i=0; i<m; i++ ) { 456cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 457cddf8d76SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 458cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 459cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 460cddf8d76SBarry Smith DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color); 461cddf8d76SBarry Smith } 462cddf8d76SBarry Smith } 463cddf8d76SBarry Smith color = DRAW_RED; 464cddf8d76SBarry Smith for ( i=0; i<m; i++ ) { 465cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 466cddf8d76SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 467cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 468cddf8d76SBarry Smith #if defined(PETSC_COMPLEX) 469cddf8d76SBarry Smith if (real(a->a[j]) <= 0.) continue; 470cddf8d76SBarry Smith #else 471cddf8d76SBarry Smith if (a->a[j] <= 0.) continue; 472cddf8d76SBarry Smith #endif 473cddf8d76SBarry Smith DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color); 474cddf8d76SBarry Smith } 475cddf8d76SBarry Smith } 4766945ee14SBarry Smith ierr = DrawCheckResizedWindow(draw); 477cddf8d76SBarry Smith ierr = DrawGetMouseButton(draw,&button,&xc,&yc,0,0); 478cddf8d76SBarry Smith } 479416022c9SBarry Smith return 0; 480416022c9SBarry Smith } 481416022c9SBarry Smith 482416022c9SBarry Smith static int MatView_SeqAIJ(PetscObject obj,Viewer viewer) 483416022c9SBarry Smith { 484416022c9SBarry Smith Mat A = (Mat) obj; 485416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 486bcd2baecSBarry Smith ViewerType vtype; 487bcd2baecSBarry Smith int ierr; 488416022c9SBarry Smith 489bcd2baecSBarry Smith ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 490bcd2baecSBarry Smith if (vtype == MATLAB_VIEWER) { 491416022c9SBarry Smith return ViewerMatlabPutSparse_Private(viewer,a->m,a->n,a->nz,a->a,a->i,a->j); 492416022c9SBarry Smith } 493bcd2baecSBarry Smith else if (vtype == ASCII_FILE_VIEWER || vtype == ASCII_FILES_VIEWER){ 494416022c9SBarry Smith return MatView_SeqAIJ_ASCII(A,viewer); 495416022c9SBarry Smith } 496bcd2baecSBarry Smith else if (vtype == BINARY_FILE_VIEWER) { 497416022c9SBarry Smith return MatView_SeqAIJ_Binary(A,viewer); 498416022c9SBarry Smith } 499bcd2baecSBarry Smith else if (vtype == DRAW_VIEWER) { 500bcd2baecSBarry Smith return MatView_SeqAIJ_Draw(A,viewer); 50117ab2063SBarry Smith } 50217ab2063SBarry Smith return 0; 50317ab2063SBarry Smith } 50419bcc07fSBarry Smith 505c456f294SBarry Smith extern int Mat_AIJ_CheckInode(Mat); 506416022c9SBarry Smith static int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 50717ab2063SBarry Smith { 508416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 50941c01911SSatish Balay int fshift = 0,i,j,*ai = a->i, *aj = a->j, *imax = a->imax,ierr; 510416022c9SBarry Smith int m = a->m, *ip, N, *ailen = a->ilen,shift = a->indexshift; 511416022c9SBarry Smith Scalar *aa = a->a, *ap; 51217ab2063SBarry Smith 5136d4a8577SBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) return 0; 51417ab2063SBarry Smith 51517ab2063SBarry Smith for ( i=1; i<m; i++ ) { 516416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 51717ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 51817ab2063SBarry Smith if (fshift) { 519416022c9SBarry Smith ip = aj + ai[i] + shift; ap = aa + ai[i] + shift; 52017ab2063SBarry Smith N = ailen[i]; 52117ab2063SBarry Smith for ( j=0; j<N; j++ ) { 52217ab2063SBarry Smith ip[j-fshift] = ip[j]; 52317ab2063SBarry Smith ap[j-fshift] = ap[j]; 52417ab2063SBarry Smith } 52517ab2063SBarry Smith } 52617ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 52717ab2063SBarry Smith } 52817ab2063SBarry Smith if (m) { 52917ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 53017ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 53117ab2063SBarry Smith } 53217ab2063SBarry Smith /* reset ilen and imax for each row */ 53317ab2063SBarry Smith for ( i=0; i<m; i++ ) { 53417ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 53517ab2063SBarry Smith } 536416022c9SBarry Smith a->nz = ai[m] + shift; 53717ab2063SBarry Smith 53817ab2063SBarry Smith /* diagonals may have moved, so kill the diagonal pointers */ 539416022c9SBarry Smith if (fshift && a->diag) { 5400452661fSBarry Smith PetscFree(a->diag); 541416022c9SBarry Smith PLogObjectMemory(A,-(m+1)*sizeof(int)); 542416022c9SBarry Smith a->diag = 0; 54317ab2063SBarry Smith } 5444e220ebcSLois Curfman McInnes PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded, %d used\n", 5454e220ebcSLois Curfman McInnes m,a->n,fshift,a->nz); 5464e220ebcSLois Curfman McInnes PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues is %d\n", 547b810aeb4SBarry Smith a->reallocs); 5484e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift; 5494e220ebcSLois Curfman McInnes 55076dd722bSSatish Balay /* check out for identical nodes. If found, use inode functions */ 55141c01911SSatish Balay ierr = Mat_AIJ_CheckInode(A); CHKERRQ(ierr); 55217ab2063SBarry Smith return 0; 55317ab2063SBarry Smith } 55417ab2063SBarry Smith 555416022c9SBarry Smith static int MatZeroEntries_SeqAIJ(Mat A) 55617ab2063SBarry Smith { 557416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 558cddf8d76SBarry Smith PetscMemzero(a->a,(a->i[a->m]+a->indexshift)*sizeof(Scalar)); 55917ab2063SBarry Smith return 0; 56017ab2063SBarry Smith } 561416022c9SBarry Smith 56217ab2063SBarry Smith int MatDestroy_SeqAIJ(PetscObject obj) 56317ab2063SBarry Smith { 564416022c9SBarry Smith Mat A = (Mat) obj; 565416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 566d5d45c9bSBarry Smith 56717ab2063SBarry Smith #if defined(PETSC_LOG) 568416022c9SBarry Smith PLogObjectState(obj,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz); 56917ab2063SBarry Smith #endif 5700452661fSBarry Smith PetscFree(a->a); 5710452661fSBarry Smith if (!a->singlemalloc) { PetscFree(a->i); PetscFree(a->j);} 5720452661fSBarry Smith if (a->diag) PetscFree(a->diag); 5730452661fSBarry Smith if (a->ilen) PetscFree(a->ilen); 5740452661fSBarry Smith if (a->imax) PetscFree(a->imax); 5750452661fSBarry Smith if (a->solve_work) PetscFree(a->solve_work); 57676dd722bSSatish Balay if (a->inode.size) PetscFree(a->inode.size); 5770452661fSBarry Smith PetscFree(a); 578f2655603SLois Curfman McInnes PLogObjectDestroy(A); 579f2655603SLois Curfman McInnes PetscHeaderDestroy(A); 58017ab2063SBarry Smith return 0; 58117ab2063SBarry Smith } 58217ab2063SBarry Smith 583416022c9SBarry Smith static int MatCompress_SeqAIJ(Mat A) 58417ab2063SBarry Smith { 58517ab2063SBarry Smith return 0; 58617ab2063SBarry Smith } 58717ab2063SBarry Smith 588416022c9SBarry Smith static int MatSetOption_SeqAIJ(Mat A,MatOption op) 58917ab2063SBarry Smith { 590416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 5916d4a8577SBarry Smith if (op == MAT_ROW_ORIENTED) a->roworiented = 1; 5926d4a8577SBarry Smith else if (op == MAT_COLUMN_ORIENTED) a->roworiented = 0; 5936d4a8577SBarry Smith else if (op == MAT_COLUMNS_SORTED) a->sorted = 1; 5946d4a8577SBarry Smith else if (op == MAT_NO_NEW_NONZERO_LOCATIONS) a->nonew = 1; 5956d4a8577SBarry Smith else if (op == MAT_YES_NEW_NONZERO_LOCATIONS) a->nonew = 0; 5966d4a8577SBarry Smith else if (op == MAT_ROWS_SORTED || 5976d4a8577SBarry Smith op == MAT_SYMMETRIC || 5986d4a8577SBarry Smith op == MAT_STRUCTURALLY_SYMMETRIC || 5996d4a8577SBarry Smith op == MAT_YES_NEW_DIAGONALS) 60094a424c1SBarry Smith PLogInfo(A,"Info:MatSetOption_SeqAIJ:Option ignored\n"); 6016d4a8577SBarry Smith else if (op == MAT_NO_NEW_DIAGONALS) 6026d4a8577SBarry Smith {SETERRQ(PETSC_ERR_SUP,"MatSetOption_SeqAIJ:MAT_NO_NEW_DIAGONALS");} 6036d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_1) a->inode.limit = 1; 6046d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_2) a->inode.limit = 2; 6056d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_3) a->inode.limit = 3; 6066d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_4) a->inode.limit = 4; 6076d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_5) a->inode.limit = 5; 608e2f28af5SBarry Smith else 6094d39ef84SLois Curfman McInnes {SETERRQ(PETSC_ERR_SUP,"MatSetOption_SeqAIJ:unknown option");} 61017ab2063SBarry Smith return 0; 61117ab2063SBarry Smith } 61217ab2063SBarry Smith 613416022c9SBarry Smith static int MatGetDiagonal_SeqAIJ(Mat A,Vec v) 61417ab2063SBarry Smith { 615416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 616416022c9SBarry Smith int i,j, n,shift = a->indexshift; 61717ab2063SBarry Smith Scalar *x, zero = 0.0; 61817ab2063SBarry Smith 61917ab2063SBarry Smith VecSet(&zero,v); 62017ab2063SBarry Smith VecGetArray(v,&x); VecGetLocalSize(v,&n); 621416022c9SBarry Smith if (n != a->m) SETERRQ(1,"MatGetDiagonal_SeqAIJ:Nonconforming matrix and vector"); 622416022c9SBarry Smith for ( i=0; i<a->m; i++ ) { 623416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 624416022c9SBarry Smith if (a->j[j]+shift == i) { 625416022c9SBarry Smith x[i] = a->a[j]; 62617ab2063SBarry Smith break; 62717ab2063SBarry Smith } 62817ab2063SBarry Smith } 62917ab2063SBarry Smith } 63017ab2063SBarry Smith return 0; 63117ab2063SBarry Smith } 63217ab2063SBarry Smith 63317ab2063SBarry Smith /* -------------------------------------------------------*/ 63417ab2063SBarry Smith /* Should check that shapes of vectors and matrices match */ 63517ab2063SBarry Smith /* -------------------------------------------------------*/ 63644cd7ae7SLois Curfman McInnes int MatMultTrans_SeqAIJ(Mat A,Vec xx,Vec yy) 63717ab2063SBarry Smith { 638416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 63917ab2063SBarry Smith Scalar *x, *y, *v, alpha; 640416022c9SBarry Smith int m = a->m, n, i, *idx, shift = a->indexshift; 64117ab2063SBarry Smith 64217ab2063SBarry Smith VecGetArray(xx,&x); VecGetArray(yy,&y); 643cddf8d76SBarry Smith PetscMemzero(y,a->n*sizeof(Scalar)); 64417ab2063SBarry Smith y = y + shift; /* shift for Fortran start by 1 indexing */ 64517ab2063SBarry Smith for ( i=0; i<m; i++ ) { 646416022c9SBarry Smith idx = a->j + a->i[i] + shift; 647416022c9SBarry Smith v = a->a + a->i[i] + shift; 648416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 64917ab2063SBarry Smith alpha = x[i]; 65017ab2063SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 65117ab2063SBarry Smith } 652416022c9SBarry Smith PLogFlops(2*a->nz - a->n); 65317ab2063SBarry Smith return 0; 65417ab2063SBarry Smith } 655d5d45c9bSBarry Smith 65644cd7ae7SLois Curfman McInnes int MatMultTransAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 65717ab2063SBarry Smith { 658416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 65917ab2063SBarry Smith Scalar *x, *y, *v, alpha; 660416022c9SBarry Smith int m = a->m, n, i, *idx,shift = a->indexshift; 66117ab2063SBarry Smith 66217ab2063SBarry Smith VecGetArray(xx,&x); VecGetArray(yy,&y); 66317ab2063SBarry Smith if (zz != yy) VecCopy(zz,yy); 66417ab2063SBarry Smith y = y + shift; /* shift for Fortran start by 1 indexing */ 66517ab2063SBarry Smith for ( i=0; i<m; i++ ) { 666416022c9SBarry Smith idx = a->j + a->i[i] + shift; 667416022c9SBarry Smith v = a->a + a->i[i] + shift; 668416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 66917ab2063SBarry Smith alpha = x[i]; 67017ab2063SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 67117ab2063SBarry Smith } 67217ab2063SBarry Smith return 0; 67317ab2063SBarry Smith } 67417ab2063SBarry Smith 67544cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 67617ab2063SBarry Smith { 677416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 67817ab2063SBarry Smith Scalar *x, *y, *v, sum; 679416022c9SBarry Smith int m = a->m, n, i, *idx, shift = a->indexshift,*ii; 68017ab2063SBarry Smith 68117ab2063SBarry Smith VecGetArray(xx,&x); VecGetArray(yy,&y); 68217ab2063SBarry Smith x = x + shift; /* shift for Fortran start by 1 indexing */ 683416022c9SBarry Smith idx = a->j; 684416022c9SBarry Smith v = a->a; 685416022c9SBarry Smith ii = a->i; 68617ab2063SBarry Smith for ( i=0; i<m; i++ ) { 687416022c9SBarry Smith n = ii[1] - ii[0]; ii++; 68817ab2063SBarry Smith sum = 0.0; 68917ab2063SBarry Smith /* SPARSEDENSEDOT(sum,x,v,idx,n); */ 69017ab2063SBarry Smith /* for ( j=n-1; j>-1; j--) sum += v[j]*x[idx[j]]; */ 691416022c9SBarry Smith while (n--) sum += *v++ * x[*idx++]; 69217ab2063SBarry Smith y[i] = sum; 69317ab2063SBarry Smith } 694416022c9SBarry Smith PLogFlops(2*a->nz - m); 69517ab2063SBarry Smith return 0; 69617ab2063SBarry Smith } 69717ab2063SBarry Smith 69844cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 69917ab2063SBarry Smith { 700416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 70117ab2063SBarry Smith Scalar *x, *y, *z, *v, sum; 702cddf8d76SBarry Smith int m = a->m, n, i, *idx, shift = a->indexshift,*ii; 70317ab2063SBarry Smith 70417ab2063SBarry Smith VecGetArray(xx,&x); VecGetArray(yy,&y); VecGetArray(zz,&z); 70517ab2063SBarry Smith x = x + shift; /* shift for Fortran start by 1 indexing */ 706cddf8d76SBarry Smith idx = a->j; 707cddf8d76SBarry Smith v = a->a; 708cddf8d76SBarry Smith ii = a->i; 70917ab2063SBarry Smith for ( i=0; i<m; i++ ) { 710cddf8d76SBarry Smith n = ii[1] - ii[0]; ii++; 71117ab2063SBarry Smith sum = y[i]; 712cddf8d76SBarry Smith /* SPARSEDENSEDOT(sum,x,v,idx,n); */ 713cddf8d76SBarry Smith while (n--) sum += *v++ * x[*idx++]; 71417ab2063SBarry Smith z[i] = sum; 71517ab2063SBarry Smith } 716416022c9SBarry Smith PLogFlops(2*a->nz); 71717ab2063SBarry Smith return 0; 71817ab2063SBarry Smith } 71917ab2063SBarry Smith 72017ab2063SBarry Smith /* 72117ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 72217ab2063SBarry Smith */ 72317ab2063SBarry Smith 724416022c9SBarry Smith int MatMarkDiag_SeqAIJ(Mat A) 72517ab2063SBarry Smith { 726416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 727416022c9SBarry Smith int i,j, *diag, m = a->m,shift = a->indexshift; 72817ab2063SBarry Smith 7290452661fSBarry Smith diag = (int *) PetscMalloc( (m+1)*sizeof(int)); CHKPTRQ(diag); 730416022c9SBarry Smith PLogObjectMemory(A,(m+1)*sizeof(int)); 731416022c9SBarry Smith for ( i=0; i<a->m; i++ ) { 732416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 733416022c9SBarry Smith if (a->j[j]+shift == i) { 73417ab2063SBarry Smith diag[i] = j - shift; 73517ab2063SBarry Smith break; 73617ab2063SBarry Smith } 73717ab2063SBarry Smith } 73817ab2063SBarry Smith } 739416022c9SBarry Smith a->diag = diag; 74017ab2063SBarry Smith return 0; 74117ab2063SBarry Smith } 74217ab2063SBarry Smith 74344cd7ae7SLois Curfman McInnes int MatRelax_SeqAIJ(Mat A,Vec bb,double omega,MatSORType flag, 74417ab2063SBarry Smith double fshift,int its,Vec xx) 74517ab2063SBarry Smith { 746416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 747416022c9SBarry Smith Scalar *x, *b, *bs, d, *xs, sum, *v = a->a,*t,scale,*ts, *xb; 748d5d45c9bSBarry Smith int ierr, *idx, *diag,n = a->n, m = a->m, i, shift = a->indexshift; 74917ab2063SBarry Smith 75017ab2063SBarry Smith VecGetArray(xx,&x); VecGetArray(bb,&b); 751416022c9SBarry Smith if (!a->diag) {if ((ierr = MatMarkDiag_SeqAIJ(A))) return ierr;} 752416022c9SBarry Smith diag = a->diag; 753416022c9SBarry Smith xs = x + shift; /* shifted by one for index start of a or a->j*/ 75417ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 75517ab2063SBarry Smith /* apply ( U + D/omega) to the vector */ 75617ab2063SBarry Smith bs = b + shift; 75717ab2063SBarry Smith for ( i=0; i<m; i++ ) { 758416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 759416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 760416022c9SBarry Smith idx = a->j + diag[i] + (!shift); 761416022c9SBarry Smith v = a->a + diag[i] + (!shift); 76217ab2063SBarry Smith sum = b[i]*d/omega; 76317ab2063SBarry Smith SPARSEDENSEDOT(sum,bs,v,idx,n); 76417ab2063SBarry Smith x[i] = sum; 76517ab2063SBarry Smith } 76617ab2063SBarry Smith return 0; 76717ab2063SBarry Smith } 76817ab2063SBarry Smith if (flag == SOR_APPLY_LOWER) { 76917ab2063SBarry Smith SETERRQ(1,"MatRelax_SeqAIJ:SOR_APPLY_LOWER is not done"); 77017ab2063SBarry Smith } 771416022c9SBarry Smith else if (flag & SOR_EISENSTAT) { 77217ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 77317ab2063SBarry Smith U is upper triangular, E is diagonal; This routine applies 77417ab2063SBarry Smith 77517ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 77617ab2063SBarry Smith 77717ab2063SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 77817ab2063SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 77917ab2063SBarry Smith is the relaxation factor. 78017ab2063SBarry Smith */ 7810452661fSBarry Smith t = (Scalar *) PetscMalloc( m*sizeof(Scalar) ); CHKPTRQ(t); 78217ab2063SBarry Smith scale = (2.0/omega) - 1.0; 78317ab2063SBarry Smith 78417ab2063SBarry Smith /* x = (E + U)^{-1} b */ 78517ab2063SBarry Smith for ( i=m-1; i>=0; i-- ) { 786416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 787416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 788416022c9SBarry Smith idx = a->j + diag[i] + (!shift); 789416022c9SBarry Smith v = a->a + diag[i] + (!shift); 79017ab2063SBarry Smith sum = b[i]; 79117ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 79217ab2063SBarry Smith x[i] = omega*(sum/d); 79317ab2063SBarry Smith } 79417ab2063SBarry Smith 79517ab2063SBarry Smith /* t = b - (2*E - D)x */ 796416022c9SBarry Smith v = a->a; 79717ab2063SBarry Smith for ( i=0; i<m; i++ ) { t[i] = b[i] - scale*(v[*diag++ + shift])*x[i]; } 79817ab2063SBarry Smith 79917ab2063SBarry Smith /* t = (E + L)^{-1}t */ 800416022c9SBarry Smith ts = t + shift; /* shifted by one for index start of a or a->j*/ 801416022c9SBarry Smith diag = a->diag; 80217ab2063SBarry Smith for ( i=0; i<m; i++ ) { 803416022c9SBarry Smith d = fshift + a->a[diag[i]+shift]; 804416022c9SBarry Smith n = diag[i] - a->i[i]; 805416022c9SBarry Smith idx = a->j + a->i[i] + shift; 806416022c9SBarry Smith v = a->a + a->i[i] + shift; 80717ab2063SBarry Smith sum = t[i]; 80817ab2063SBarry Smith SPARSEDENSEMDOT(sum,ts,v,idx,n); 80917ab2063SBarry Smith t[i] = omega*(sum/d); 81017ab2063SBarry Smith } 81117ab2063SBarry Smith 81217ab2063SBarry Smith /* x = x + t */ 81317ab2063SBarry Smith for ( i=0; i<m; i++ ) { x[i] += t[i]; } 8140452661fSBarry Smith PetscFree(t); 81517ab2063SBarry Smith return 0; 81617ab2063SBarry Smith } 81717ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 81817ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 81917ab2063SBarry Smith for ( i=0; i<m; i++ ) { 820416022c9SBarry Smith d = fshift + a->a[diag[i]+shift]; 821416022c9SBarry Smith n = diag[i] - a->i[i]; 822416022c9SBarry Smith idx = a->j + a->i[i] + shift; 823416022c9SBarry Smith v = a->a + a->i[i] + shift; 82417ab2063SBarry Smith sum = b[i]; 82517ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 82617ab2063SBarry Smith x[i] = omega*(sum/d); 82717ab2063SBarry Smith } 82817ab2063SBarry Smith xb = x; 82917ab2063SBarry Smith } 83017ab2063SBarry Smith else xb = b; 83117ab2063SBarry Smith if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) && 83217ab2063SBarry Smith (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) { 83317ab2063SBarry Smith for ( i=0; i<m; i++ ) { 834416022c9SBarry Smith x[i] *= a->a[diag[i]+shift]; 83517ab2063SBarry Smith } 83617ab2063SBarry Smith } 83717ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 83817ab2063SBarry Smith for ( i=m-1; i>=0; i-- ) { 839416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 840416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 841416022c9SBarry Smith idx = a->j + diag[i] + (!shift); 842416022c9SBarry Smith v = a->a + diag[i] + (!shift); 84317ab2063SBarry Smith sum = xb[i]; 84417ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 84517ab2063SBarry Smith x[i] = omega*(sum/d); 84617ab2063SBarry Smith } 84717ab2063SBarry Smith } 84817ab2063SBarry Smith its--; 84917ab2063SBarry Smith } 85017ab2063SBarry Smith while (its--) { 85117ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 85217ab2063SBarry Smith for ( i=0; i<m; i++ ) { 853416022c9SBarry Smith d = fshift + a->a[diag[i]+shift]; 854416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 855416022c9SBarry Smith idx = a->j + a->i[i] + shift; 856416022c9SBarry Smith v = a->a + a->i[i] + shift; 85717ab2063SBarry Smith sum = b[i]; 85817ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 8597e33a6baSBarry Smith x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d; 86017ab2063SBarry Smith } 86117ab2063SBarry Smith } 86217ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 86317ab2063SBarry Smith for ( i=m-1; i>=0; i-- ) { 864416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 865416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 866416022c9SBarry Smith idx = a->j + a->i[i] + shift; 867416022c9SBarry Smith v = a->a + a->i[i] + shift; 86817ab2063SBarry Smith sum = b[i]; 86917ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 8707e33a6baSBarry Smith x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d; 87117ab2063SBarry Smith } 87217ab2063SBarry Smith } 87317ab2063SBarry Smith } 87417ab2063SBarry Smith return 0; 87517ab2063SBarry Smith } 87617ab2063SBarry Smith 8774e220ebcSLois Curfman McInnes static int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 87817ab2063SBarry Smith { 879416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 8804e220ebcSLois Curfman McInnes 8814e220ebcSLois Curfman McInnes info->rows_global = (double)a->m; 8824e220ebcSLois Curfman McInnes info->columns_global = (double)a->n; 8834e220ebcSLois Curfman McInnes info->rows_local = (double)a->m; 8844e220ebcSLois Curfman McInnes info->columns_local = (double)a->n; 8854e220ebcSLois Curfman McInnes info->block_size = 1.0; 8864e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 8874e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 8884e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 8894e220ebcSLois Curfman McInnes /* if (info->nz_unneeded != A->info.nz_unneeded) 8904e220ebcSLois Curfman McInnes printf("space descrepancy: maxnz-nz = %d, nz_unneeded = %d\n",(int)info->nz_unneeded,(int)A->info.nz_unneeded); */ 8914e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 8924e220ebcSLois Curfman McInnes info->mallocs = (double)a->reallocs; 8934e220ebcSLois Curfman McInnes info->memory = A->mem; 8944e220ebcSLois Curfman McInnes if (A->factor) { 8954e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 8964e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 8974e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 8984e220ebcSLois Curfman McInnes } else { 8994e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 9004e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 9014e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 9024e220ebcSLois Curfman McInnes } 90317ab2063SBarry Smith return 0; 90417ab2063SBarry Smith } 90517ab2063SBarry Smith 90617ab2063SBarry Smith extern int MatLUFactorSymbolic_SeqAIJ(Mat,IS,IS,double,Mat*); 90717ab2063SBarry Smith extern int MatLUFactorNumeric_SeqAIJ(Mat,Mat*); 90817ab2063SBarry Smith extern int MatLUFactor_SeqAIJ(Mat,IS,IS,double); 90917ab2063SBarry Smith extern int MatSolve_SeqAIJ(Mat,Vec,Vec); 91017ab2063SBarry Smith extern int MatSolveAdd_SeqAIJ(Mat,Vec,Vec,Vec); 91117ab2063SBarry Smith extern int MatSolveTrans_SeqAIJ(Mat,Vec,Vec); 91217ab2063SBarry Smith extern int MatSolveTransAdd_SeqAIJ(Mat,Vec,Vec,Vec); 91317ab2063SBarry Smith 91417ab2063SBarry Smith static int MatZeroRows_SeqAIJ(Mat A,IS is,Scalar *diag) 91517ab2063SBarry Smith { 916416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 917416022c9SBarry Smith int i,ierr,N, *rows,m = a->m - 1,shift = a->indexshift; 91817ab2063SBarry Smith 91977c4ece6SBarry Smith ierr = ISGetSize(is,&N); CHKERRQ(ierr); 92017ab2063SBarry Smith ierr = ISGetIndices(is,&rows); CHKERRQ(ierr); 92117ab2063SBarry Smith if (diag) { 92217ab2063SBarry Smith for ( i=0; i<N; i++ ) { 923416022c9SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(1,"MatZeroRows_SeqAIJ:row out of range"); 924416022c9SBarry Smith if (a->ilen[rows[i]] > 0) { /* in case row was completely empty */ 925416022c9SBarry Smith a->ilen[rows[i]] = 1; 926416022c9SBarry Smith a->a[a->i[rows[i]]+shift] = *diag; 927416022c9SBarry Smith a->j[a->i[rows[i]]+shift] = rows[i]+shift; 92817ab2063SBarry Smith } 92917ab2063SBarry Smith else { 93017ab2063SBarry Smith ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES); 93117ab2063SBarry Smith CHKERRQ(ierr); 93217ab2063SBarry Smith } 93317ab2063SBarry Smith } 93417ab2063SBarry Smith } 93517ab2063SBarry Smith else { 93617ab2063SBarry Smith for ( i=0; i<N; i++ ) { 937416022c9SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(1,"MatZeroRows_SeqAIJ:row out of range"); 938416022c9SBarry Smith a->ilen[rows[i]] = 0; 93917ab2063SBarry Smith } 94017ab2063SBarry Smith } 94117ab2063SBarry Smith ISRestoreIndices(is,&rows); 9426d4a8577SBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 9436d4a8577SBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 94417ab2063SBarry Smith return 0; 94517ab2063SBarry Smith } 94617ab2063SBarry Smith 947416022c9SBarry Smith static int MatGetSize_SeqAIJ(Mat A,int *m,int *n) 94817ab2063SBarry Smith { 949416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 950416022c9SBarry Smith *m = a->m; *n = a->n; 95117ab2063SBarry Smith return 0; 95217ab2063SBarry Smith } 95317ab2063SBarry Smith 954416022c9SBarry Smith static int MatGetOwnershipRange_SeqAIJ(Mat A,int *m,int *n) 95517ab2063SBarry Smith { 956416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 957416022c9SBarry Smith *m = 0; *n = a->m; 95817ab2063SBarry Smith return 0; 95917ab2063SBarry Smith } 9604e093b46SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 96117ab2063SBarry Smith { 962416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 963c456f294SBarry Smith int *itmp,i,shift = a->indexshift; 96417ab2063SBarry Smith 965416022c9SBarry Smith if (row < 0 || row >= a->m) SETERRQ(1,"MatGetRow_SeqAIJ:Row out of range"); 96617ab2063SBarry Smith 967416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 968416022c9SBarry Smith if (v) *v = a->a + a->i[row] + shift; 96917ab2063SBarry Smith if (idx) { 970416022c9SBarry Smith itmp = a->j + a->i[row] + shift; 9714e093b46SBarry Smith if (*nz && shift) { 9720452661fSBarry Smith *idx = (int *) PetscMalloc( (*nz)*sizeof(int) ); CHKPTRQ(*idx); 97317ab2063SBarry Smith for ( i=0; i<(*nz); i++ ) {(*idx)[i] = itmp[i] + shift;} 9744e093b46SBarry Smith } else if (*nz) { 9754e093b46SBarry Smith *idx = itmp; 97617ab2063SBarry Smith } 97717ab2063SBarry Smith else *idx = 0; 97817ab2063SBarry Smith } 97917ab2063SBarry Smith return 0; 98017ab2063SBarry Smith } 98117ab2063SBarry Smith 9824e093b46SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 98317ab2063SBarry Smith { 9844e093b46SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 9854e093b46SBarry Smith if (idx) {if (*idx && a->indexshift) PetscFree(*idx);} 98617ab2063SBarry Smith return 0; 98717ab2063SBarry Smith } 98817ab2063SBarry Smith 989cddf8d76SBarry Smith static int MatNorm_SeqAIJ(Mat A,NormType type,double *norm) 99017ab2063SBarry Smith { 991416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 992416022c9SBarry Smith Scalar *v = a->a; 99317ab2063SBarry Smith double sum = 0.0; 994416022c9SBarry Smith int i, j,shift = a->indexshift; 99517ab2063SBarry Smith 99617ab2063SBarry Smith if (type == NORM_FROBENIUS) { 997416022c9SBarry Smith for (i=0; i<a->nz; i++ ) { 99817ab2063SBarry Smith #if defined(PETSC_COMPLEX) 99917ab2063SBarry Smith sum += real(conj(*v)*(*v)); v++; 100017ab2063SBarry Smith #else 100117ab2063SBarry Smith sum += (*v)*(*v); v++; 100217ab2063SBarry Smith #endif 100317ab2063SBarry Smith } 100417ab2063SBarry Smith *norm = sqrt(sum); 100517ab2063SBarry Smith } 100617ab2063SBarry Smith else if (type == NORM_1) { 100717ab2063SBarry Smith double *tmp; 1008416022c9SBarry Smith int *jj = a->j; 10090452661fSBarry Smith tmp = (double *) PetscMalloc( a->n*sizeof(double) ); CHKPTRQ(tmp); 1010cddf8d76SBarry Smith PetscMemzero(tmp,a->n*sizeof(double)); 101117ab2063SBarry Smith *norm = 0.0; 1012416022c9SBarry Smith for ( j=0; j<a->nz; j++ ) { 1013a2744918SBarry Smith tmp[*jj++ + shift] += PetscAbsScalar(*v); v++; 101417ab2063SBarry Smith } 1015416022c9SBarry Smith for ( j=0; j<a->n; j++ ) { 101617ab2063SBarry Smith if (tmp[j] > *norm) *norm = tmp[j]; 101717ab2063SBarry Smith } 10180452661fSBarry Smith PetscFree(tmp); 101917ab2063SBarry Smith } 102017ab2063SBarry Smith else if (type == NORM_INFINITY) { 102117ab2063SBarry Smith *norm = 0.0; 1022416022c9SBarry Smith for ( j=0; j<a->m; j++ ) { 1023416022c9SBarry Smith v = a->a + a->i[j] + shift; 102417ab2063SBarry Smith sum = 0.0; 1025416022c9SBarry Smith for ( i=0; i<a->i[j+1]-a->i[j]; i++ ) { 1026cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 102717ab2063SBarry Smith } 102817ab2063SBarry Smith if (sum > *norm) *norm = sum; 102917ab2063SBarry Smith } 103017ab2063SBarry Smith } 103117ab2063SBarry Smith else { 103248d91487SBarry Smith SETERRQ(1,"MatNorm_SeqAIJ:No support for two norm yet"); 103317ab2063SBarry Smith } 103417ab2063SBarry Smith return 0; 103517ab2063SBarry Smith } 103617ab2063SBarry Smith 1037416022c9SBarry Smith static int MatTranspose_SeqAIJ(Mat A,Mat *B) 103817ab2063SBarry Smith { 1039416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1040416022c9SBarry Smith Mat C; 1041416022c9SBarry Smith int i, ierr, *aj = a->j, *ai = a->i, m = a->m, len, *col; 1042416022c9SBarry Smith int shift = a->indexshift; 1043d5d45c9bSBarry Smith Scalar *array = a->a; 104417ab2063SBarry Smith 10453638b69dSLois Curfman McInnes if (B == PETSC_NULL && m != a->n) 1046dfa27b74SSatish Balay SETERRQ(1,"MatTranspose_SeqAIJ:Square matrix only for in-place"); 10470452661fSBarry Smith col = (int *) PetscMalloc((1+a->n)*sizeof(int)); CHKPTRQ(col); 1048cddf8d76SBarry Smith PetscMemzero(col,(1+a->n)*sizeof(int)); 104917ab2063SBarry Smith if (shift) { 105017ab2063SBarry Smith for ( i=0; i<ai[m]-1; i++ ) aj[i] -= 1; 105117ab2063SBarry Smith } 105217ab2063SBarry Smith for ( i=0; i<ai[m]+shift; i++ ) col[aj[i]] += 1; 1053416022c9SBarry Smith ierr = MatCreateSeqAIJ(A->comm,a->n,m,0,col,&C); CHKERRQ(ierr); 10540452661fSBarry Smith PetscFree(col); 105517ab2063SBarry Smith for ( i=0; i<m; i++ ) { 105617ab2063SBarry Smith len = ai[i+1]-ai[i]; 1057416022c9SBarry Smith ierr = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES); CHKERRQ(ierr); 105817ab2063SBarry Smith array += len; aj += len; 105917ab2063SBarry Smith } 106017ab2063SBarry Smith if (shift) { 106117ab2063SBarry Smith for ( i=0; i<ai[m]-1; i++ ) aj[i] += 1; 106217ab2063SBarry Smith } 106317ab2063SBarry Smith 10646d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 10656d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 106617ab2063SBarry Smith 10673638b69dSLois Curfman McInnes if (B != PETSC_NULL) { 1068416022c9SBarry Smith *B = C; 106917ab2063SBarry Smith } else { 1070416022c9SBarry Smith /* This isn't really an in-place transpose */ 10710452661fSBarry Smith PetscFree(a->a); 10720452661fSBarry Smith if (!a->singlemalloc) {PetscFree(a->i); PetscFree(a->j);} 10730452661fSBarry Smith if (a->diag) PetscFree(a->diag); 10740452661fSBarry Smith if (a->ilen) PetscFree(a->ilen); 10750452661fSBarry Smith if (a->imax) PetscFree(a->imax); 10760452661fSBarry Smith if (a->solve_work) PetscFree(a->solve_work); 10771073c447SSatish Balay if (a->inode.size) PetscFree(a->inode.size); 10780452661fSBarry Smith PetscFree(a); 1079416022c9SBarry Smith PetscMemcpy(A,C,sizeof(struct _Mat)); 10800452661fSBarry Smith PetscHeaderDestroy(C); 108117ab2063SBarry Smith } 108217ab2063SBarry Smith return 0; 108317ab2063SBarry Smith } 108417ab2063SBarry Smith 1085f0b747eeSBarry Smith static int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 108617ab2063SBarry Smith { 1087416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 108817ab2063SBarry Smith Scalar *l,*r,x,*v; 1089d5d45c9bSBarry Smith int i,j,m = a->m, n = a->n, M, nz = a->nz, *jj,shift = a->indexshift; 109017ab2063SBarry Smith 109117ab2063SBarry Smith if (ll) { 109217ab2063SBarry Smith VecGetArray(ll,&l); VecGetSize(ll,&m); 1093f0b747eeSBarry Smith if (m != a->m) SETERRQ(1,"MatDiagonalScale_SeqAIJ:Left scaling vector wrong length"); 1094416022c9SBarry Smith v = a->a; 109517ab2063SBarry Smith for ( i=0; i<m; i++ ) { 109617ab2063SBarry Smith x = l[i]; 1097416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 109817ab2063SBarry Smith for ( j=0; j<M; j++ ) { (*v++) *= x;} 109917ab2063SBarry Smith } 110044cd7ae7SLois Curfman McInnes PLogFlops(nz); 110117ab2063SBarry Smith } 110217ab2063SBarry Smith if (rr) { 110317ab2063SBarry Smith VecGetArray(rr,&r); VecGetSize(rr,&n); 1104f0b747eeSBarry Smith if (n != a->n) SETERRQ(1,"MatDiagonalScale_SeqAIJ:Right scaling vector wrong length"); 1105416022c9SBarry Smith v = a->a; jj = a->j; 110617ab2063SBarry Smith for ( i=0; i<nz; i++ ) { 110717ab2063SBarry Smith (*v++) *= r[*jj++ + shift]; 110817ab2063SBarry Smith } 110944cd7ae7SLois Curfman McInnes PLogFlops(nz); 111017ab2063SBarry Smith } 111117ab2063SBarry Smith return 0; 111217ab2063SBarry Smith } 111317ab2063SBarry Smith 1114cddf8d76SBarry Smith static int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,MatGetSubMatrixCall scall,Mat *B) 111517ab2063SBarry Smith { 1116db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data,*c; 111702834360SBarry Smith int nznew, *smap, i, k, kstart, kend, ierr, oldcols = a->n,*lens; 111899141d43SSatish Balay int row,mat_i,*mat_j,tcol,first,step,*mat_ilen; 1119a2744918SBarry Smith register int sum,lensi; 112099141d43SSatish Balay int *irow, *icol, nrows, ncols, shift = a->indexshift,*ssmap; 112199141d43SSatish Balay int *starts,*j_new,*i_new,*aj = a->j, *ai = a->i,ii,*ailen = a->ilen; 112299141d43SSatish Balay Scalar *a_new,*mat_a; 1123416022c9SBarry Smith Mat C; 112417ab2063SBarry Smith 1125b48a1e75SSatish Balay ierr = ISSorted(isrow,(PetscTruth*)&i); 1126b48a1e75SSatish Balay if (!i) SETERRQ(1,"MatGetSubmatrices_SeqAIJ:ISrow is not sorted"); 112799141d43SSatish Balay ierr = ISSorted(iscol,(PetscTruth*)&i); 1128b48a1e75SSatish Balay if (!i) SETERRQ(1,"MatGetSubmatrices_SeqAIJ:IScol is not sorted"); 112999141d43SSatish Balay 113017ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow); CHKERRQ(ierr); 113117ab2063SBarry Smith ierr = ISGetSize(isrow,&nrows); CHKERRQ(ierr); 113217ab2063SBarry Smith ierr = ISGetSize(iscol,&ncols); CHKERRQ(ierr); 113317ab2063SBarry Smith 11347264ac53SSatish Balay if (ISStrideGetInfo(iscol,&first,&step) && step == 1) { /* no need to sort */ 113502834360SBarry Smith /* special case of contiguous rows */ 113657faeb66SBarry Smith lens = (int *) PetscMalloc((ncols+nrows+1)*sizeof(int)); CHKPTRQ(lens); 113702834360SBarry Smith starts = lens + ncols; 113802834360SBarry Smith /* loop over new rows determining lens and starting points */ 113902834360SBarry Smith for (i=0; i<nrows; i++) { 1140a2744918SBarry Smith kstart = ai[irow[i]]+shift; 1141a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 114202834360SBarry Smith for ( k=kstart; k<kend; k++ ) { 1143d8ced48eSBarry Smith if (aj[k]+shift >= first) { 114402834360SBarry Smith starts[i] = k; 114502834360SBarry Smith break; 114602834360SBarry Smith } 114702834360SBarry Smith } 1148a2744918SBarry Smith sum = 0; 114902834360SBarry Smith while (k < kend) { 1150d8ced48eSBarry Smith if (aj[k++]+shift >= first+ncols) break; 1151a2744918SBarry Smith sum++; 115202834360SBarry Smith } 1153a2744918SBarry Smith lens[i] = sum; 115402834360SBarry Smith } 115502834360SBarry Smith /* create submatrix */ 1156cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 115708480c60SBarry Smith int n_cols,n_rows; 115808480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols); CHKERRQ(ierr); 115908480c60SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(1,"MatGetSubMatrix_SeqAIJ:"); 1160d8ced48eSBarry Smith ierr = MatZeroEntries(*B); CHKERRQ(ierr); 116108480c60SBarry Smith C = *B; 116208480c60SBarry Smith } 116308480c60SBarry Smith else { 116402834360SBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 116508480c60SBarry Smith } 1166db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*) C->data; 1167db02288aSLois Curfman McInnes 116802834360SBarry Smith /* loop over rows inserting into submatrix */ 1169db02288aSLois Curfman McInnes a_new = c->a; 1170db02288aSLois Curfman McInnes j_new = c->j; 1171db02288aSLois Curfman McInnes i_new = c->i; 1172db02288aSLois Curfman McInnes i_new[0] = -shift; 117302834360SBarry Smith for (i=0; i<nrows; i++) { 1174a2744918SBarry Smith ii = starts[i]; 1175a2744918SBarry Smith lensi = lens[i]; 1176a2744918SBarry Smith for ( k=0; k<lensi; k++ ) { 1177a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 117802834360SBarry Smith } 1179a2744918SBarry Smith PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(Scalar)); 1180a2744918SBarry Smith a_new += lensi; 1181a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 1182a2744918SBarry Smith c->ilen[i] = lensi; 118302834360SBarry Smith } 11840452661fSBarry Smith PetscFree(lens); 118502834360SBarry Smith } 118602834360SBarry Smith else { 118702834360SBarry Smith ierr = ISGetIndices(iscol,&icol); CHKERRQ(ierr); 11880452661fSBarry Smith smap = (int *) PetscMalloc((1+oldcols)*sizeof(int)); CHKPTRQ(smap); 118902834360SBarry Smith ssmap = smap + shift; 119099141d43SSatish Balay lens = (int *) PetscMalloc((1+nrows)*sizeof(int)); CHKPTRQ(lens); 1191cddf8d76SBarry Smith PetscMemzero(smap,oldcols*sizeof(int)); 119217ab2063SBarry Smith for ( i=0; i<ncols; i++ ) smap[icol[i]] = i+1; 119302834360SBarry Smith /* determine lens of each row */ 119402834360SBarry Smith for (i=0; i<nrows; i++) { 1195d8ced48eSBarry Smith kstart = ai[irow[i]]+shift; 119602834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 119702834360SBarry Smith lens[i] = 0; 119802834360SBarry Smith for ( k=kstart; k<kend; k++ ) { 1199d8ced48eSBarry Smith if (ssmap[aj[k]]) { 120002834360SBarry Smith lens[i]++; 120102834360SBarry Smith } 120202834360SBarry Smith } 120302834360SBarry Smith } 120417ab2063SBarry Smith /* Create and fill new matrix */ 1205a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 120699141d43SSatish Balay c = (Mat_SeqAIJ *)((*B)->data); 120799141d43SSatish Balay 120899141d43SSatish Balay if (c->m != nrows || c->n != ncols) SETERRQ(1,"MatGetSubMatrix_SeqAIJ:"); 120999141d43SSatish Balay if (PetscMemcmp(c->ilen,lens, c->m *sizeof(int))) { 121099141d43SSatish Balay SETERRQ(1,"MatGetSubmatrices_SeqAIJ:Cannot reuse matrix. wrong no of nonzeros"); 121199141d43SSatish Balay } 121299141d43SSatish Balay PetscMemzero(c->ilen,c->m*sizeof(int)); 121308480c60SBarry Smith C = *B; 121408480c60SBarry Smith } 121508480c60SBarry Smith else { 121602834360SBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 121708480c60SBarry Smith } 121899141d43SSatish Balay c = (Mat_SeqAIJ *)(C->data); 121917ab2063SBarry Smith for (i=0; i<nrows; i++) { 122099141d43SSatish Balay row = irow[i]; 122117ab2063SBarry Smith nznew = 0; 122299141d43SSatish Balay kstart = ai[row]+shift; 122399141d43SSatish Balay kend = kstart + a->ilen[row]; 122499141d43SSatish Balay mat_i = c->i[i]+shift; 122599141d43SSatish Balay mat_j = c->j + mat_i; 122699141d43SSatish Balay mat_a = c->a + mat_i; 122799141d43SSatish Balay mat_ilen = c->ilen + i; 122817ab2063SBarry Smith for ( k=kstart; k<kend; k++ ) { 122999141d43SSatish Balay if ((tcol=ssmap[a->j[k]])) { 123099141d43SSatish Balay *mat_j++ = tcol - (!shift); 123199141d43SSatish Balay *mat_a++ = a->a[k]; 123299141d43SSatish Balay (*mat_ilen)++; 123399141d43SSatish Balay 123417ab2063SBarry Smith } 123517ab2063SBarry Smith } 123617ab2063SBarry Smith } 123702834360SBarry Smith /* Free work space */ 123802834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol); CHKERRQ(ierr); 123999141d43SSatish Balay PetscFree(smap); PetscFree(lens); 124002834360SBarry Smith } 12416d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 12426d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 124317ab2063SBarry Smith 124417ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow); CHKERRQ(ierr); 1245416022c9SBarry Smith *B = C; 124617ab2063SBarry Smith return 0; 124717ab2063SBarry Smith } 124817ab2063SBarry Smith 1249a871dcd8SBarry Smith /* 125063b91edcSBarry Smith note: This can only work for identity for row and col. It would 125163b91edcSBarry Smith be good to check this and otherwise generate an error. 1252a871dcd8SBarry Smith */ 125363b91edcSBarry Smith static int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,double efill,int fill) 1254a871dcd8SBarry Smith { 125563b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) inA->data; 125608480c60SBarry Smith int ierr; 125763b91edcSBarry Smith Mat outA; 125863b91edcSBarry Smith 1259a871dcd8SBarry Smith if (fill != 0) SETERRQ(1,"MatILUFactor_SeqAIJ:Only fill=0 supported"); 1260a871dcd8SBarry Smith 126163b91edcSBarry Smith outA = inA; 126263b91edcSBarry Smith inA->factor = FACTOR_LU; 126363b91edcSBarry Smith a->row = row; 126463b91edcSBarry Smith a->col = col; 126563b91edcSBarry Smith 12660452661fSBarry Smith a->solve_work = (Scalar *) PetscMalloc( (a->m+1)*sizeof(Scalar)); CHKPTRQ(a->solve_work); 126763b91edcSBarry Smith 126808480c60SBarry Smith if (!a->diag) { 126908480c60SBarry Smith ierr = MatMarkDiag_SeqAIJ(inA); CHKERRQ(ierr); 127063b91edcSBarry Smith } 127163b91edcSBarry Smith ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA); CHKERRQ(ierr); 1272a871dcd8SBarry Smith return 0; 1273a871dcd8SBarry Smith } 1274a871dcd8SBarry Smith 1275f0b747eeSBarry Smith #include "pinclude/plapack.h" 1276f0b747eeSBarry Smith static int MatScale_SeqAIJ(Scalar *alpha,Mat inA) 1277f0b747eeSBarry Smith { 1278f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) inA->data; 1279f0b747eeSBarry Smith int one = 1; 1280f0b747eeSBarry Smith BLscal_( &a->nz, alpha, a->a, &one ); 1281f0b747eeSBarry Smith PLogFlops(a->nz); 1282f0b747eeSBarry Smith return 0; 1283f0b747eeSBarry Smith } 1284f0b747eeSBarry Smith 1285cddf8d76SBarry Smith static int MatGetSubMatrices_SeqAIJ(Mat A,int n, IS *irow,IS *icol,MatGetSubMatrixCall scall, 1286cddf8d76SBarry Smith Mat **B) 1287cddf8d76SBarry Smith { 1288cddf8d76SBarry Smith int ierr,i; 1289cddf8d76SBarry Smith 1290cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 12910452661fSBarry Smith *B = (Mat *) PetscMalloc( (n+1)*sizeof(Mat) ); CHKPTRQ(*B); 1292cddf8d76SBarry Smith } 1293cddf8d76SBarry Smith 1294cddf8d76SBarry Smith for ( i=0; i<n; i++ ) { 1295905e6a2fSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],scall,&(*B)[i]);CHKERRQ(ierr); 1296cddf8d76SBarry Smith } 1297cddf8d76SBarry Smith return 0; 1298cddf8d76SBarry Smith } 1299cddf8d76SBarry Smith 13005a838052SSatish Balay static int MatGetBlockSize_SeqAIJ(Mat A, int *bs) 13015a838052SSatish Balay { 13025a838052SSatish Balay *bs = 1; 13035a838052SSatish Balay return 0; 13045a838052SSatish Balay } 13055a838052SSatish Balay 1306e4d965acSSatish Balay static int MatIncreaseOverlap_SeqAIJ(Mat A, int is_max, IS *is, int ov) 13074dcbc457SBarry Smith { 1308e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 130906763907SSatish Balay int shift, row, i,j,k,l,m,n, *idx,ierr, *nidx, isz, val; 13108a047759SSatish Balay int start, end, *ai, *aj; 131106763907SSatish Balay char *table; 13128a047759SSatish Balay shift = a->indexshift; 1313e4d965acSSatish Balay m = a->m; 1314e4d965acSSatish Balay ai = a->i; 13158a047759SSatish Balay aj = a->j+shift; 13168a047759SSatish Balay 1317e4d965acSSatish Balay if (ov < 0) SETERRQ(1,"MatIncreaseOverlap_SeqAIJ: illegal overlap value used"); 131806763907SSatish Balay 131906763907SSatish Balay table = (char *) PetscMalloc((m/BITSPERBYTE +1)*sizeof(char)); CHKPTRQ(table); 132006763907SSatish Balay nidx = (int *) PetscMalloc((m+1)*sizeof(int)); CHKPTRQ(nidx); 132106763907SSatish Balay 1322e4d965acSSatish Balay for ( i=0; i<is_max; i++ ) { 1323e4d965acSSatish Balay /* Initialise the two local arrays */ 1324e4d965acSSatish Balay isz = 0; 132506763907SSatish Balay PetscMemzero(table,(m/BITSPERBYTE +1)*sizeof(char)); 1326e4d965acSSatish Balay 1327e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 13284dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx); CHKERRQ(ierr); 132977c4ece6SBarry Smith ierr = ISGetSize(is[i],&n); CHKERRQ(ierr); 1330e4d965acSSatish Balay 1331e4d965acSSatish Balay /* Enter these into the temp arrays i.e mark table[row], enter row into new index */ 1332e4d965acSSatish Balay for ( j=0; j<n ; ++j){ 133306763907SSatish Balay if(!BT_LOOKUP(table, idx[j])) { nidx[isz++] = idx[j];} 13344dcbc457SBarry Smith } 133506763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx); CHKERRQ(ierr); 133606763907SSatish Balay ierr = ISDestroy(is[i]); CHKERRQ(ierr); 1337e4d965acSSatish Balay 133804a348a9SBarry Smith k = 0; 133904a348a9SBarry Smith for ( j=0; j<ov; j++){ /* for each overlap*/ 134004a348a9SBarry Smith n = isz; 134106763907SSatish Balay for ( ; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */ 1342e4d965acSSatish Balay row = nidx[k]; 1343e4d965acSSatish Balay start = ai[row]; 1344e4d965acSSatish Balay end = ai[row+1]; 134504a348a9SBarry Smith for ( l = start; l<end ; l++){ 13468a047759SSatish Balay val = aj[l] + shift; 134706763907SSatish Balay if (!BT_LOOKUP(table,val)) {nidx[isz++] = val;} 1348e4d965acSSatish Balay } 1349e4d965acSSatish Balay } 1350e4d965acSSatish Balay } 1351537820f0SBarry Smith ierr = ISCreateGeneral(MPI_COMM_SELF, isz, nidx, (is+i)); CHKERRQ(ierr); 1352e4d965acSSatish Balay } 135304a348a9SBarry Smith PetscFree(table); 135406763907SSatish Balay PetscFree(nidx); 1355e4d965acSSatish Balay return 0; 13564dcbc457SBarry Smith } 135717ab2063SBarry Smith 1358682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A) 1359682d7d0cSBarry Smith { 1360682d7d0cSBarry Smith static int called = 0; 1361682d7d0cSBarry Smith MPI_Comm comm = A->comm; 1362682d7d0cSBarry Smith 1363682d7d0cSBarry Smith if (called) return 0; else called = 1; 136477c4ece6SBarry Smith PetscPrintf(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n"); 136577c4ece6SBarry Smith PetscPrintf(comm," -mat_lu_pivotthreshold <threshold>\n"); 136677c4ece6SBarry Smith PetscPrintf(comm," -mat_aij_oneindex - internal indices begin at 1 instead of the default 0.\n"); 136777c4ece6SBarry Smith PetscPrintf(comm," -mat_aij_no_inode - Do not use inodes\n"); 136877c4ece6SBarry Smith PetscPrintf(comm," -mat_aij_inode_limit <limit> - Set inode limit (max limit=5)\n"); 1369682d7d0cSBarry Smith #if defined(HAVE_ESSL) 137077c4ece6SBarry Smith PetscPrintf(comm," -mat_aij_essl - Use IBM sparse LU factorization and solve.\n"); 1371682d7d0cSBarry Smith #endif 1372682d7d0cSBarry Smith return 0; 1373682d7d0cSBarry Smith } 1374205e38a3SBarry Smith static int MatEqual_SeqAIJ(Mat A,Mat B, PetscTruth* flg); 1375*a93ec695SBarry Smith extern int MatFDColoringCreate_SeqAIJ(Mat,ISColoring,MatFDColoring); 1376*a93ec695SBarry Smith extern int MatColoringPatch_SeqAIJ(Mat,int,int *,ISColoring *); 1377*a93ec695SBarry Smith 1378682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 137917ab2063SBarry Smith static struct _MatOps MatOps = {MatSetValues_SeqAIJ, 138017ab2063SBarry Smith MatGetRow_SeqAIJ,MatRestoreRow_SeqAIJ, 1381416022c9SBarry Smith MatMult_SeqAIJ,MatMultAdd_SeqAIJ, 1382416022c9SBarry Smith MatMultTrans_SeqAIJ,MatMultTransAdd_SeqAIJ, 138317ab2063SBarry Smith MatSolve_SeqAIJ,MatSolveAdd_SeqAIJ, 138417ab2063SBarry Smith MatSolveTrans_SeqAIJ,MatSolveTransAdd_SeqAIJ, 138517ab2063SBarry Smith MatLUFactor_SeqAIJ,0, 138617ab2063SBarry Smith MatRelax_SeqAIJ, 138717ab2063SBarry Smith MatTranspose_SeqAIJ, 13887264ac53SSatish Balay MatGetInfo_SeqAIJ,MatEqual_SeqAIJ, 1389f0b747eeSBarry Smith MatGetDiagonal_SeqAIJ,MatDiagonalScale_SeqAIJ,MatNorm_SeqAIJ, 139017ab2063SBarry Smith 0,MatAssemblyEnd_SeqAIJ, 139117ab2063SBarry Smith MatCompress_SeqAIJ, 139217ab2063SBarry Smith MatSetOption_SeqAIJ,MatZeroEntries_SeqAIJ,MatZeroRows_SeqAIJ, 139317ab2063SBarry Smith MatLUFactorSymbolic_SeqAIJ,MatLUFactorNumeric_SeqAIJ,0,0, 139417ab2063SBarry Smith MatGetSize_SeqAIJ,MatGetSize_SeqAIJ,MatGetOwnershipRange_SeqAIJ, 139517ab2063SBarry Smith MatILUFactorSymbolic_SeqAIJ,0, 139617ab2063SBarry Smith 0,0,MatConvert_SeqAIJ, 13973d1612f7SBarry Smith MatConvertSameType_SeqAIJ,0,0, 1398cddf8d76SBarry Smith MatILUFactor_SeqAIJ,0,0, 13997eb43aa7SLois Curfman McInnes MatGetSubMatrices_SeqAIJ,MatIncreaseOverlap_SeqAIJ, 1400682d7d0cSBarry Smith MatGetValues_SeqAIJ,0, 1401f0b747eeSBarry Smith MatPrintHelp_SeqAIJ, 14025a838052SSatish Balay MatScale_SeqAIJ,0,0, 14036945ee14SBarry Smith MatILUDTFactor_SeqAIJ, 14046945ee14SBarry Smith MatGetBlockSize_SeqAIJ, 14053b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 14063b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 14073b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 1408*a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 1409*a93ec695SBarry Smith MatFDColoringCreate_SeqAIJ, 1410*a93ec695SBarry Smith MatColoringPatch_SeqAIJ}; 141117ab2063SBarry Smith 141217ab2063SBarry Smith extern int MatUseSuperLU_SeqAIJ(Mat); 141317ab2063SBarry Smith extern int MatUseEssl_SeqAIJ(Mat); 141417ab2063SBarry Smith extern int MatUseDXML_SeqAIJ(Mat); 141517ab2063SBarry Smith 141617ab2063SBarry Smith /*@C 1417682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 14180d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 14196e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 14202bd5e0b2SLois Curfman McInnes (or the array nzz). By setting these parameters accurately, performance 14212bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 142217ab2063SBarry Smith 142317ab2063SBarry Smith Input Parameters: 142417ab2063SBarry Smith . comm - MPI communicator, set to MPI_COMM_SELF 142517ab2063SBarry Smith . m - number of rows 142617ab2063SBarry Smith . n - number of columns 142717ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 14282bd5e0b2SLois Curfman McInnes . nzz - array containing the number of nonzeros in the various rows 14292bd5e0b2SLois Curfman McInnes (possibly different for each row) or PETSC_NULL 143017ab2063SBarry Smith 143117ab2063SBarry Smith Output Parameter: 1432416022c9SBarry Smith . A - the matrix 143317ab2063SBarry Smith 143417ab2063SBarry Smith Notes: 143517ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 143617ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 14370002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 143844cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 143917ab2063SBarry Smith 144017ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 1441a40aa06bSLois Curfman McInnes Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 14423d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 14433d323bbdSBarry Smith will get TERRIBLE performance, see the users' manual chapter on 14440d15e28bSLois Curfman McInnes matrices and the file $(PETSC_DIR)/Performance. 144517ab2063SBarry Smith 1446682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 1447682d7d0cSBarry Smith improve numerical efficiency of Matrix vector products and solves. We 1448682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 14496c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 14506c7ebb05SLois Curfman McInnes 14516c7ebb05SLois Curfman McInnes Options Database Keys: 14526c7ebb05SLois Curfman McInnes $ -mat_aij_no_inode - Do not use inodes 14536e62573dSLois Curfman McInnes $ -mat_aij_inode_limit <limit> - Set inode limit. 14546e62573dSLois Curfman McInnes $ (max limit=5) 14556e62573dSLois Curfman McInnes $ -mat_aij_oneindex - Internally use indexing starting at 1 14566e62573dSLois Curfman McInnes $ rather than 0. Note: When calling MatSetValues(), 14576e62573dSLois Curfman McInnes $ the user still MUST index entries starting at 0! 145817ab2063SBarry Smith 145917ab2063SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues() 146017ab2063SBarry Smith @*/ 1461416022c9SBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,int *nnz, Mat *A) 146217ab2063SBarry Smith { 1463416022c9SBarry Smith Mat B; 1464416022c9SBarry Smith Mat_SeqAIJ *b; 14656945ee14SBarry Smith int i, len, ierr, flg,size; 14666945ee14SBarry Smith 14676945ee14SBarry Smith MPI_Comm_size(comm,&size); 14686945ee14SBarry Smith if (size > 1) SETERRQ(1,"MatCreateSeqAIJ:Comm must be of size 1"); 1469d5d45c9bSBarry Smith 1470416022c9SBarry Smith *A = 0; 14710452661fSBarry Smith PetscHeaderCreate(B,_Mat,MAT_COOKIE,MATSEQAIJ,comm); 1472416022c9SBarry Smith PLogObjectCreate(B); 14730452661fSBarry Smith B->data = (void *) (b = PetscNew(Mat_SeqAIJ)); CHKPTRQ(b); 147444cd7ae7SLois Curfman McInnes PetscMemzero(b,sizeof(Mat_SeqAIJ)); 1475416022c9SBarry Smith PetscMemcpy(&B->ops,&MatOps,sizeof(struct _MatOps)); 1476416022c9SBarry Smith B->destroy = MatDestroy_SeqAIJ; 1477416022c9SBarry Smith B->view = MatView_SeqAIJ; 1478416022c9SBarry Smith B->factor = 0; 1479416022c9SBarry Smith B->lupivotthreshold = 1.0; 14807a743949SBarry Smith ierr = OptionsGetDouble(PETSC_NULL,"-mat_lu_pivotthreshold",&B->lupivotthreshold, 148169957df2SSatish Balay &flg); CHKERRQ(ierr); 14827a743949SBarry Smith b->ilu_preserve_row_sums = PETSC_FALSE; 14837a743949SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-pc_ilu_preserve_row_sums", 14847a743949SBarry Smith (int*) &b->ilu_preserve_row_sums); CHKERRQ(ierr); 1485416022c9SBarry Smith b->row = 0; 1486416022c9SBarry Smith b->col = 0; 1487416022c9SBarry Smith b->indexshift = 0; 1488b810aeb4SBarry Smith b->reallocs = 0; 148969957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_oneindex", &flg); CHKERRQ(ierr); 149069957df2SSatish Balay if (flg) b->indexshift = -1; 149117ab2063SBarry Smith 149244cd7ae7SLois Curfman McInnes b->m = m; B->m = m; B->M = m; 149344cd7ae7SLois Curfman McInnes b->n = n; B->n = n; B->N = n; 14940452661fSBarry Smith b->imax = (int *) PetscMalloc( (m+1)*sizeof(int) ); CHKPTRQ(b->imax); 1495b4fd4287SBarry Smith if (nnz == PETSC_NULL) { 14967b8455f0SLois Curfman McInnes if (nz == PETSC_DEFAULT) nz = 10; 14977b8455f0SLois Curfman McInnes else if (nz <= 0) nz = 1; 1498416022c9SBarry Smith for ( i=0; i<m; i++ ) b->imax[i] = nz; 149917ab2063SBarry Smith nz = nz*m; 150017ab2063SBarry Smith } 150117ab2063SBarry Smith else { 150217ab2063SBarry Smith nz = 0; 1503416022c9SBarry Smith for ( i=0; i<m; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];} 150417ab2063SBarry Smith } 150517ab2063SBarry Smith 150617ab2063SBarry Smith /* allocate the matrix space */ 1507416022c9SBarry Smith len = nz*(sizeof(int) + sizeof(Scalar)) + (b->m+1)*sizeof(int); 15080452661fSBarry Smith b->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(b->a); 1509416022c9SBarry Smith b->j = (int *) (b->a + nz); 1510cddf8d76SBarry Smith PetscMemzero(b->j,nz*sizeof(int)); 1511416022c9SBarry Smith b->i = b->j + nz; 1512416022c9SBarry Smith b->singlemalloc = 1; 151317ab2063SBarry Smith 1514416022c9SBarry Smith b->i[0] = -b->indexshift; 151517ab2063SBarry Smith for (i=1; i<m+1; i++) { 1516416022c9SBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 151717ab2063SBarry Smith } 151817ab2063SBarry Smith 1519416022c9SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 15200452661fSBarry Smith b->ilen = (int *) PetscMalloc((m+1)*sizeof(int)); 1521416022c9SBarry Smith PLogObjectMemory(B,len+2*(m+1)*sizeof(int)+sizeof(struct _Mat)+sizeof(Mat_SeqAIJ)); 1522416022c9SBarry Smith for ( i=0; i<b->m; i++ ) { b->ilen[i] = 0;} 152317ab2063SBarry Smith 1524416022c9SBarry Smith b->nz = 0; 1525416022c9SBarry Smith b->maxnz = nz; 1526416022c9SBarry Smith b->sorted = 0; 1527416022c9SBarry Smith b->roworiented = 1; 1528416022c9SBarry Smith b->nonew = 0; 1529416022c9SBarry Smith b->diag = 0; 1530416022c9SBarry Smith b->solve_work = 0; 153171bd300dSLois Curfman McInnes b->spptr = 0; 1532754ec7b1SSatish Balay b->inode.node_count = 0; 1533754ec7b1SSatish Balay b->inode.size = 0; 15346c7ebb05SLois Curfman McInnes b->inode.limit = 5; 15356c7ebb05SLois Curfman McInnes b->inode.max_limit = 5; 15364e220ebcSLois Curfman McInnes B->info.nz_unneeded = (double)b->maxnz; 153717ab2063SBarry Smith 1538416022c9SBarry Smith *A = B; 15394e220ebcSLois Curfman McInnes 15404b14c69eSBarry Smith /* SuperLU is not currently supported through PETSc */ 15414b14c69eSBarry Smith #if defined(HAVE_SUPERLU) 154269957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_superlu", &flg); CHKERRQ(ierr); 154369957df2SSatish Balay if (flg) { ierr = MatUseSuperLU_SeqAIJ(B); CHKERRQ(ierr); } 15444b14c69eSBarry Smith #endif 154569957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_essl", &flg); CHKERRQ(ierr); 154669957df2SSatish Balay if (flg) { ierr = MatUseEssl_SeqAIJ(B); CHKERRQ(ierr); } 154769957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_dxml", &flg); CHKERRQ(ierr); 154869957df2SSatish Balay if (flg) { 1549416022c9SBarry Smith if (!b->indexshift) SETERRQ(1,"MatCreateSeqAIJ:need -mat_aij_oneindex with -mat_aij_dxml"); 1550416022c9SBarry Smith ierr = MatUseDXML_SeqAIJ(B); CHKERRQ(ierr); 155117ab2063SBarry Smith } 155269957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr); 155369957df2SSatish Balay if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); } 155417ab2063SBarry Smith return 0; 155517ab2063SBarry Smith } 155617ab2063SBarry Smith 15573d1612f7SBarry Smith int MatConvertSameType_SeqAIJ(Mat A,Mat *B,int cpvalues) 155817ab2063SBarry Smith { 1559416022c9SBarry Smith Mat C; 1560416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ *) A->data; 156108480c60SBarry Smith int i,len, m = a->m,shift = a->indexshift; 156217ab2063SBarry Smith 15634043dd9cSLois Curfman McInnes *B = 0; 15640452661fSBarry Smith PetscHeaderCreate(C,_Mat,MAT_COOKIE,MATSEQAIJ,A->comm); 1565416022c9SBarry Smith PLogObjectCreate(C); 15660452661fSBarry Smith C->data = (void *) (c = PetscNew(Mat_SeqAIJ)); CHKPTRQ(c); 156741c01911SSatish Balay PetscMemcpy(&C->ops,&A->ops,sizeof(struct _MatOps)); 1568416022c9SBarry Smith C->destroy = MatDestroy_SeqAIJ; 1569416022c9SBarry Smith C->view = MatView_SeqAIJ; 1570416022c9SBarry Smith C->factor = A->factor; 1571416022c9SBarry Smith c->row = 0; 1572416022c9SBarry Smith c->col = 0; 1573416022c9SBarry Smith c->indexshift = shift; 1574c456f294SBarry Smith C->assembled = PETSC_TRUE; 157517ab2063SBarry Smith 157644cd7ae7SLois Curfman McInnes c->m = C->m = a->m; 157744cd7ae7SLois Curfman McInnes c->n = C->n = a->n; 157844cd7ae7SLois Curfman McInnes C->M = a->m; 157944cd7ae7SLois Curfman McInnes C->N = a->n; 158017ab2063SBarry Smith 15810452661fSBarry Smith c->imax = (int *) PetscMalloc((m+1)*sizeof(int)); CHKPTRQ(c->imax); 15820452661fSBarry Smith c->ilen = (int *) PetscMalloc((m+1)*sizeof(int)); CHKPTRQ(c->ilen); 158317ab2063SBarry Smith for ( i=0; i<m; i++ ) { 1584416022c9SBarry Smith c->imax[i] = a->imax[i]; 1585416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 158617ab2063SBarry Smith } 158717ab2063SBarry Smith 158817ab2063SBarry Smith /* allocate the matrix space */ 1589416022c9SBarry Smith c->singlemalloc = 1; 1590416022c9SBarry Smith len = (m+1)*sizeof(int)+(a->i[m])*(sizeof(Scalar)+sizeof(int)); 15910452661fSBarry Smith c->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(c->a); 1592416022c9SBarry Smith c->j = (int *) (c->a + a->i[m] + shift); 1593416022c9SBarry Smith c->i = c->j + a->i[m] + shift; 1594416022c9SBarry Smith PetscMemcpy(c->i,a->i,(m+1)*sizeof(int)); 159517ab2063SBarry Smith if (m > 0) { 1596416022c9SBarry Smith PetscMemcpy(c->j,a->j,(a->i[m]+shift)*sizeof(int)); 159708480c60SBarry Smith if (cpvalues == COPY_VALUES) { 1598416022c9SBarry Smith PetscMemcpy(c->a,a->a,(a->i[m]+shift)*sizeof(Scalar)); 159917ab2063SBarry Smith } 160008480c60SBarry Smith } 160117ab2063SBarry Smith 1602416022c9SBarry Smith PLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _Mat)+sizeof(Mat_SeqAIJ)); 1603416022c9SBarry Smith c->sorted = a->sorted; 1604416022c9SBarry Smith c->roworiented = a->roworiented; 1605416022c9SBarry Smith c->nonew = a->nonew; 16067a743949SBarry Smith c->ilu_preserve_row_sums = a->ilu_preserve_row_sums; 160717ab2063SBarry Smith 1608416022c9SBarry Smith if (a->diag) { 16090452661fSBarry Smith c->diag = (int *) PetscMalloc( (m+1)*sizeof(int) ); CHKPTRQ(c->diag); 1610416022c9SBarry Smith PLogObjectMemory(C,(m+1)*sizeof(int)); 161117ab2063SBarry Smith for ( i=0; i<m; i++ ) { 1612416022c9SBarry Smith c->diag[i] = a->diag[i]; 161317ab2063SBarry Smith } 161417ab2063SBarry Smith } 1615416022c9SBarry Smith else c->diag = 0; 16166c7ebb05SLois Curfman McInnes c->inode.limit = a->inode.limit; 16176c7ebb05SLois Curfman McInnes c->inode.max_limit = a->inode.max_limit; 1618754ec7b1SSatish Balay if (a->inode.size){ 1619daed632aSSatish Balay c->inode.size = (int *) PetscMalloc( (m+1)*sizeof(int) ); CHKPTRQ(c->inode.size); 1620754ec7b1SSatish Balay c->inode.node_count = a->inode.node_count; 1621daed632aSSatish Balay PetscMemcpy( c->inode.size, a->inode.size, (m+1)*sizeof(int)); 1622754ec7b1SSatish Balay } else { 1623754ec7b1SSatish Balay c->inode.size = 0; 1624754ec7b1SSatish Balay c->inode.node_count = 0; 1625754ec7b1SSatish Balay } 1626416022c9SBarry Smith c->nz = a->nz; 1627416022c9SBarry Smith c->maxnz = a->maxnz; 1628416022c9SBarry Smith c->solve_work = 0; 162976dd722bSSatish Balay c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 1630754ec7b1SSatish Balay 1631416022c9SBarry Smith *B = C; 163217ab2063SBarry Smith return 0; 163317ab2063SBarry Smith } 163417ab2063SBarry Smith 163519bcc07fSBarry Smith int MatLoad_SeqAIJ(Viewer viewer,MatType type,Mat *A) 163617ab2063SBarry Smith { 1637416022c9SBarry Smith Mat_SeqAIJ *a; 1638416022c9SBarry Smith Mat B; 163917699dbbSLois Curfman McInnes int i, nz, ierr, fd, header[4],size,*rowlengths = 0,M,N,shift; 1640bcd2baecSBarry Smith MPI_Comm comm; 164117ab2063SBarry Smith 164219bcc07fSBarry Smith PetscObjectGetComm((PetscObject) viewer,&comm); 164317699dbbSLois Curfman McInnes MPI_Comm_size(comm,&size); 164417699dbbSLois Curfman McInnes if (size > 1) SETERRQ(1,"MatLoad_SeqAIJ:view must have one processor"); 164590ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 164677c4ece6SBarry Smith ierr = PetscBinaryRead(fd,header,4,BINARY_INT); CHKERRQ(ierr); 164748d91487SBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(1,"MatLoad_SeqAIJ:not matrix object in file"); 164817ab2063SBarry Smith M = header[1]; N = header[2]; nz = header[3]; 164917ab2063SBarry Smith 165017ab2063SBarry Smith /* read in row lengths */ 16510452661fSBarry Smith rowlengths = (int*) PetscMalloc( M*sizeof(int) ); CHKPTRQ(rowlengths); 165277c4ece6SBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,BINARY_INT); CHKERRQ(ierr); 165317ab2063SBarry Smith 165417ab2063SBarry Smith /* create our matrix */ 1655416022c9SBarry Smith ierr = MatCreateSeqAIJ(comm,M,N,0,rowlengths,A); CHKERRQ(ierr); 1656416022c9SBarry Smith B = *A; 1657416022c9SBarry Smith a = (Mat_SeqAIJ *) B->data; 1658416022c9SBarry Smith shift = a->indexshift; 165917ab2063SBarry Smith 166017ab2063SBarry Smith /* read in column indices and adjust for Fortran indexing*/ 166177c4ece6SBarry Smith ierr = PetscBinaryRead(fd,a->j,nz,BINARY_INT); CHKERRQ(ierr); 166217ab2063SBarry Smith if (shift) { 166317ab2063SBarry Smith for ( i=0; i<nz; i++ ) { 1664416022c9SBarry Smith a->j[i] += 1; 166517ab2063SBarry Smith } 166617ab2063SBarry Smith } 166717ab2063SBarry Smith 166817ab2063SBarry Smith /* read in nonzero values */ 166977c4ece6SBarry Smith ierr = PetscBinaryRead(fd,a->a,nz,BINARY_SCALAR); CHKERRQ(ierr); 167017ab2063SBarry Smith 167117ab2063SBarry Smith /* set matrix "i" values */ 1672416022c9SBarry Smith a->i[0] = -shift; 167317ab2063SBarry Smith for ( i=1; i<= M; i++ ) { 1674416022c9SBarry Smith a->i[i] = a->i[i-1] + rowlengths[i-1]; 1675416022c9SBarry Smith a->ilen[i-1] = rowlengths[i-1]; 167617ab2063SBarry Smith } 16770452661fSBarry Smith PetscFree(rowlengths); 167817ab2063SBarry Smith 16796d4a8577SBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 16806d4a8577SBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 168117ab2063SBarry Smith return 0; 168217ab2063SBarry Smith } 168317ab2063SBarry Smith 1684686e14cbSSatish Balay static int MatEqual_SeqAIJ(Mat A,Mat B, PetscTruth* flg) 16857264ac53SSatish Balay { 16867264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data, *b = (Mat_SeqAIJ *)B->data; 16877264ac53SSatish Balay 1688bcd2baecSBarry Smith if (B->type !=MATSEQAIJ)SETERRQ(1,"MatEqual_SeqAIJ:Matrices must be same type"); 16897264ac53SSatish Balay 16907264ac53SSatish Balay /* If the matrix dimensions are not equal, or no of nonzeros or shift */ 16917264ac53SSatish Balay if ((a->m != b->m ) || (a->n !=b->n) ||( a->nz != b->nz)|| 1692bcd2baecSBarry Smith (a->indexshift != b->indexshift)) { 169377c4ece6SBarry Smith *flg = PETSC_FALSE; return 0; 1694bcd2baecSBarry Smith } 16957264ac53SSatish Balay 16967264ac53SSatish Balay /* if the a->i are the same */ 1697bcd2baecSBarry Smith if (PetscMemcmp(a->i,b->i, (a->n+1)*sizeof(int))) { 169877c4ece6SBarry Smith *flg = PETSC_FALSE; return 0; 16997264ac53SSatish Balay } 17007264ac53SSatish Balay 17017264ac53SSatish Balay /* if a->j are the same */ 1702bcd2baecSBarry Smith if (PetscMemcmp(a->j, b->j, (a->nz)*sizeof(int))) { 170377c4ece6SBarry Smith *flg = PETSC_FALSE; return 0; 1704bcd2baecSBarry Smith } 1705bcd2baecSBarry Smith 1706bcd2baecSBarry Smith /* if a->a are the same */ 170719bcc07fSBarry Smith if (PetscMemcmp(a->a, b->a, (a->nz)*sizeof(Scalar))) { 170877c4ece6SBarry Smith *flg = PETSC_FALSE; return 0; 17097264ac53SSatish Balay } 171077c4ece6SBarry Smith *flg = PETSC_TRUE; 17117264ac53SSatish Balay return 0; 17127264ac53SSatish Balay 17137264ac53SSatish Balay } 1714