1*c38d4ed2SBarry Smith /*$Id: aij.c,v 1.332 1999/11/05 14:45:18 bsmith Exp bsmith $*/ 2d5d45c9bSBarry Smith /* 33369ce9aSBarry Smith Defines the basic matrix operations for the AIJ (compressed row) 4d5d45c9bSBarry Smith matrix storage format. 5d5d45c9bSBarry Smith */ 63369ce9aSBarry Smith 73369ce9aSBarry Smith #include "sys.h" 870f55243SBarry Smith #include "src/mat/impls/aij/seq/aij.h" 9f5eb4b81SSatish Balay #include "src/vec/vecimpl.h" 10f5eb4b81SSatish Balay #include "src/inline/spops.h" 118d195f9aSBarry Smith #include "src/inline/dot.h" 12eeb667a2SSatish Balay #include "bitarray.h" 1317ab2063SBarry Smith 14a2ce50c7SBarry Smith /* 15a2ce50c7SBarry Smith Basic AIJ format ILU based on drop tolerance 16a2ce50c7SBarry Smith */ 175615d1e5SSatish Balay #undef __FUNC__ 185615d1e5SSatish Balay #define __FUNC__ "MatILUDTFactor_SeqAIJ" 19a2ce50c7SBarry Smith int MatILUDTFactor_SeqAIJ(Mat A,double dt,int maxnz,IS row,IS col,Mat *fact) 20a2ce50c7SBarry Smith { 21a2ce50c7SBarry Smith /* Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; */ 22a2ce50c7SBarry Smith 233a40ed3dSBarry Smith PetscFunctionBegin; 243f1db9ecSBarry Smith SETERRQ(1,0,"Not implemented"); 25aa482453SBarry Smith #if !defined(PETSC_USE_DEBUG) 26d64ed03dSBarry Smith PetscFunctionReturn(0); 27d64ed03dSBarry Smith #endif 28a2ce50c7SBarry Smith } 29a2ce50c7SBarry Smith 30bcd2baecSBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**); 3117ab2063SBarry Smith 325615d1e5SSatish Balay #undef __FUNC__ 335615d1e5SSatish Balay #define __FUNC__ "MatGetRowIJ_SeqAIJ" 348f6be9afSLois Curfman McInnes 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 403a40ed3dSBarry Smith PetscFunctionBegin; 4131625ec5SSatish Balay *m = A->m; 423a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 436945ee14SBarry Smith ishift = a->indexshift; 446945ee14SBarry Smith if (symmetric) { 4531625ec5SSatish Balay ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr); 466945ee14SBarry Smith } else if (oshift == 0 && ishift == -1) { 4731625ec5SSatish Balay int nz = a->i[a->m]; 483b2fbd54SBarry Smith /* malloc space and subtract 1 from i and j indices */ 4931625ec5SSatish Balay *ia = (int *) PetscMalloc( (a->m+1)*sizeof(int) );CHKPTRQ(*ia); 503b2fbd54SBarry Smith *ja = (int *) PetscMalloc( (nz+1)*sizeof(int) );CHKPTRQ(*ja); 513b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) (*ja)[i] = a->j[i] - 1; 5231625ec5SSatish Balay for ( i=0; i<a->m+1; i++ ) (*ia)[i] = a->i[i] - 1; 536945ee14SBarry Smith } else if (oshift == 1 && ishift == 0) { 5431625ec5SSatish Balay int nz = a->i[a->m] + 1; 553b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 5631625ec5SSatish Balay *ia = (int *) PetscMalloc( (a->m+1)*sizeof(int) );CHKPTRQ(*ia); 573b2fbd54SBarry Smith *ja = (int *) PetscMalloc( (nz+1)*sizeof(int) );CHKPTRQ(*ja); 583b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) (*ja)[i] = a->j[i] + 1; 5931625ec5SSatish Balay for ( i=0; i<a->m+1; i++ ) (*ia)[i] = a->i[i] + 1; 606945ee14SBarry Smith } else { 616945ee14SBarry Smith *ia = a->i; *ja = a->j; 62a2ce50c7SBarry Smith } 63a2ce50c7SBarry Smith 643a40ed3dSBarry Smith PetscFunctionReturn(0); 65a2744918SBarry Smith } 66a2744918SBarry Smith 675615d1e5SSatish Balay #undef __FUNC__ 685615d1e5SSatish Balay #define __FUNC__ "MatRestoreRowIJ_SeqAIJ" 698f6be9afSLois Curfman McInnes int MatRestoreRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja, 706945ee14SBarry Smith PetscTruth *done) 716945ee14SBarry Smith { 726945ee14SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 73606d414cSSatish Balay int ishift = a->indexshift,ierr; 746945ee14SBarry Smith 753a40ed3dSBarry Smith PetscFunctionBegin; 763a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 773b2fbd54SBarry Smith if (symmetric || (oshift == 0 && ishift == -1) || (oshift == 1 && ishift == 0)) { 78606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 79606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 80bcd2baecSBarry Smith } 813a40ed3dSBarry Smith PetscFunctionReturn(0); 8217ab2063SBarry Smith } 8317ab2063SBarry Smith 845615d1e5SSatish Balay #undef __FUNC__ 855615d1e5SSatish Balay #define __FUNC__ "MatGetColumnIJ_SeqAIJ" 8643a90d84SBarry Smith int MatGetColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja, 873b2fbd54SBarry Smith PetscTruth *done) 883b2fbd54SBarry Smith { 893b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 90a93ec695SBarry Smith int ierr,i,ishift = a->indexshift,*collengths,*cia,*cja,n = A->n,m = A->m; 91a93ec695SBarry Smith int nz = a->i[m]+ishift,row,*jj,mr,col; 923b2fbd54SBarry Smith 933a40ed3dSBarry Smith PetscFunctionBegin; 943b2fbd54SBarry Smith *nn = A->n; 953a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 963b2fbd54SBarry Smith if (symmetric) { 97179192dfSSatish Balay ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr); 983b2fbd54SBarry Smith } else { 9961d2ded1SBarry Smith collengths = (int *) PetscMalloc( (n+1)*sizeof(int) );CHKPTRQ(collengths); 100549d3d68SSatish Balay ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr); 1013b2fbd54SBarry Smith cia = (int *) PetscMalloc( (n+1)*sizeof(int) );CHKPTRQ(cia); 102a93ec695SBarry Smith cja = (int *) PetscMalloc( (nz+1)*sizeof(int) );CHKPTRQ(cja); 1033b2fbd54SBarry Smith jj = a->j; 1043b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) { 1053b2fbd54SBarry Smith collengths[jj[i] + ishift]++; 1063b2fbd54SBarry Smith } 1073b2fbd54SBarry Smith cia[0] = oshift; 1083b2fbd54SBarry Smith for ( i=0; i<n; i++) { 1093b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 1103b2fbd54SBarry Smith } 111549d3d68SSatish Balay ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr); 1123b2fbd54SBarry Smith jj = a->j; 113a93ec695SBarry Smith for ( row=0; row<m; row++ ) { 114a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 115a93ec695SBarry Smith for ( i=0; i<mr; i++ ) { 1163b2fbd54SBarry Smith col = *jj++ + ishift; 1173b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 1183b2fbd54SBarry Smith } 1193b2fbd54SBarry Smith } 120606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 1213b2fbd54SBarry Smith *ia = cia; *ja = cja; 1223b2fbd54SBarry Smith } 1233b2fbd54SBarry Smith 1243a40ed3dSBarry Smith PetscFunctionReturn(0); 1253b2fbd54SBarry Smith } 1263b2fbd54SBarry Smith 1275615d1e5SSatish Balay #undef __FUNC__ 1285615d1e5SSatish Balay #define __FUNC__ "MatRestoreColumnIJ_SeqAIJ" 12943a90d84SBarry Smith int MatRestoreColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia, 1303b2fbd54SBarry Smith int **ja,PetscTruth *done) 1313b2fbd54SBarry Smith { 132606d414cSSatish Balay int ierr; 133606d414cSSatish Balay 1343a40ed3dSBarry Smith PetscFunctionBegin; 1353a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 1363b2fbd54SBarry Smith 137606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 138606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 1393b2fbd54SBarry Smith 1403a40ed3dSBarry Smith PetscFunctionReturn(0); 1413b2fbd54SBarry Smith } 1423b2fbd54SBarry Smith 143227d817aSBarry Smith #define CHUNKSIZE 15 14417ab2063SBarry Smith 1455615d1e5SSatish Balay #undef __FUNC__ 1465615d1e5SSatish Balay #define __FUNC__ "MatSetValues_SeqAIJ" 14761d2ded1SBarry Smith int MatSetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 14817ab2063SBarry Smith { 149416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 150416022c9SBarry Smith int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax, N, sorted = a->sorted; 1514b0e389bSBarry Smith int *imax = a->imax, *ai = a->i, *ailen = a->ilen,roworiented = a->roworiented; 152549d3d68SSatish Balay int *aj = a->j, nonew = a->nonew,shift = a->indexshift,ierr; 153416022c9SBarry Smith Scalar *ap,value, *aa = a->a; 15417ab2063SBarry Smith 1553a40ed3dSBarry Smith PetscFunctionBegin; 15617ab2063SBarry Smith for ( k=0; k<m; k++ ) { /* loop over added rows */ 157416022c9SBarry Smith row = im[k]; 1585ef9f2a5SBarry Smith if (row < 0) continue; 159aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 16032e87ba3SBarry Smith if (row >= a->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large: row %d max %d",row,a->m); 1613b2fbd54SBarry Smith #endif 16217ab2063SBarry Smith rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 16317ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 164416022c9SBarry Smith low = 0; 16517ab2063SBarry Smith for ( l=0; l<n; l++ ) { /* loop over added columns */ 1665ef9f2a5SBarry Smith if (in[l] < 0) continue; 167aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 16832e87ba3SBarry Smith if (in[l] >= a->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large: col %d max %d",in[l],a->n); 1693b2fbd54SBarry Smith #endif 1704b0e389bSBarry Smith col = in[l] - shift; 1714b0e389bSBarry Smith if (roworiented) { 1725ef9f2a5SBarry Smith value = v[l + k*n]; 173bef8e0ddSBarry Smith } else { 1744b0e389bSBarry Smith value = v[k + l*m]; 1754b0e389bSBarry Smith } 176416022c9SBarry Smith if (!sorted) low = 0; high = nrow; 177416022c9SBarry Smith while (high-low > 5) { 178416022c9SBarry Smith t = (low+high)/2; 179416022c9SBarry Smith if (rp[t] > col) high = t; 180416022c9SBarry Smith else low = t; 18117ab2063SBarry Smith } 182416022c9SBarry Smith for ( i=low; i<high; i++ ) { 18317ab2063SBarry Smith if (rp[i] > col) break; 18417ab2063SBarry Smith if (rp[i] == col) { 185416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 18617ab2063SBarry Smith else ap[i] = value; 18717ab2063SBarry Smith goto noinsert; 18817ab2063SBarry Smith } 18917ab2063SBarry Smith } 190c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 191a8c6a408SBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 19217ab2063SBarry Smith if (nrow >= rmax) { 19317ab2063SBarry Smith /* there is no extra room in row, therefore enlarge */ 194416022c9SBarry Smith int new_nz = ai[a->m] + CHUNKSIZE,len,*new_i,*new_j; 19517ab2063SBarry Smith Scalar *new_a; 19617ab2063SBarry Smith 197a8c6a408SBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 19896854ed6SLois Curfman McInnes 19917ab2063SBarry Smith /* malloc new storage space */ 200416022c9SBarry Smith len = new_nz*(sizeof(int)+sizeof(Scalar))+(a->m+1)*sizeof(int); 2010452661fSBarry Smith new_a = (Scalar *) PetscMalloc( len );CHKPTRQ(new_a); 20217ab2063SBarry Smith new_j = (int *) (new_a + new_nz); 20317ab2063SBarry Smith new_i = new_j + new_nz; 20417ab2063SBarry Smith 20517ab2063SBarry Smith /* copy over old data into new slots */ 20617ab2063SBarry Smith for ( ii=0; ii<row+1; ii++ ) {new_i[ii] = ai[ii];} 207416022c9SBarry Smith for ( ii=row+1; ii<a->m+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;} 208549d3d68SSatish Balay ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow+shift)*sizeof(int));CHKERRQ(ierr); 209416022c9SBarry Smith len = (new_nz - CHUNKSIZE - ai[row] - nrow - shift); 210549d3d68SSatish Balay ierr = PetscMemcpy(new_j+ai[row]+shift+nrow+CHUNKSIZE,aj+ai[row]+shift+nrow,len*sizeof(int));CHKERRQ(ierr); 211549d3d68SSatish Balay ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow+shift)*sizeof(Scalar));CHKERRQ(ierr); 212549d3d68SSatish Balay ierr = PetscMemcpy(new_a+ai[row]+shift+nrow+CHUNKSIZE,aa+ai[row]+shift+nrow,len*sizeof(Scalar));CHKERRQ(ierr); 21317ab2063SBarry Smith /* free up old matrix storage */ 214606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 215606d414cSSatish Balay if (!a->singlemalloc) { 216606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 217606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 218606d414cSSatish Balay } 219416022c9SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 220416022c9SBarry Smith a->singlemalloc = 1; 22117ab2063SBarry Smith 22217ab2063SBarry Smith rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 223416022c9SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 224416022c9SBarry Smith PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + sizeof(Scalar))); 225416022c9SBarry Smith a->maxnz += CHUNKSIZE; 226b810aeb4SBarry Smith a->reallocs++; 22717ab2063SBarry Smith } 228416022c9SBarry Smith N = nrow++ - 1; a->nz++; 229416022c9SBarry Smith /* shift up all the later entries in this row */ 230416022c9SBarry Smith for ( ii=N; ii>=i; ii-- ) { 23117ab2063SBarry Smith rp[ii+1] = rp[ii]; 23217ab2063SBarry Smith ap[ii+1] = ap[ii]; 23317ab2063SBarry Smith } 23417ab2063SBarry Smith rp[i] = col; 23517ab2063SBarry Smith ap[i] = value; 23617ab2063SBarry Smith noinsert:; 237416022c9SBarry Smith low = i + 1; 23817ab2063SBarry Smith } 23917ab2063SBarry Smith ailen[row] = nrow; 24017ab2063SBarry Smith } 2413a40ed3dSBarry Smith PetscFunctionReturn(0); 24217ab2063SBarry Smith } 24317ab2063SBarry Smith 2445615d1e5SSatish Balay #undef __FUNC__ 2455615d1e5SSatish Balay #define __FUNC__ "MatGetValues_SeqAIJ" 2468f6be9afSLois Curfman McInnes int MatGetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v) 2477eb43aa7SLois Curfman McInnes { 2487eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 249b49de8d1SLois Curfman McInnes int *rp, k, low, high, t, row, nrow, i, col, l, *aj = a->j; 2507eb43aa7SLois Curfman McInnes int *ai = a->i, *ailen = a->ilen, shift = a->indexshift; 2517eb43aa7SLois Curfman McInnes Scalar *ap, *aa = a->a, zero = 0.0; 2527eb43aa7SLois Curfman McInnes 2533a40ed3dSBarry Smith PetscFunctionBegin; 2547eb43aa7SLois Curfman McInnes for ( k=0; k<m; k++ ) { /* loop over rows */ 2557eb43aa7SLois Curfman McInnes row = im[k]; 256a8c6a408SBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 257a8c6a408SBarry Smith if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 2587eb43aa7SLois Curfman McInnes rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 2597eb43aa7SLois Curfman McInnes nrow = ailen[row]; 2607eb43aa7SLois Curfman McInnes for ( l=0; l<n; l++ ) { /* loop over columns */ 261a8c6a408SBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 262a8c6a408SBarry Smith if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 2637eb43aa7SLois Curfman McInnes col = in[l] - shift; 2647eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 2657eb43aa7SLois Curfman McInnes while (high-low > 5) { 2667eb43aa7SLois Curfman McInnes t = (low+high)/2; 2677eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 2687eb43aa7SLois Curfman McInnes else low = t; 2697eb43aa7SLois Curfman McInnes } 2707eb43aa7SLois Curfman McInnes for ( i=low; i<high; i++ ) { 2717eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 2727eb43aa7SLois Curfman McInnes if (rp[i] == col) { 273b49de8d1SLois Curfman McInnes *v++ = ap[i]; 2747eb43aa7SLois Curfman McInnes goto finished; 2757eb43aa7SLois Curfman McInnes } 2767eb43aa7SLois Curfman McInnes } 277b49de8d1SLois Curfman McInnes *v++ = zero; 2787eb43aa7SLois Curfman McInnes finished:; 2797eb43aa7SLois Curfman McInnes } 2807eb43aa7SLois Curfman McInnes } 2813a40ed3dSBarry Smith PetscFunctionReturn(0); 2827eb43aa7SLois Curfman McInnes } 2837eb43aa7SLois Curfman McInnes 28417ab2063SBarry Smith 2855615d1e5SSatish Balay #undef __FUNC__ 2865615d1e5SSatish Balay #define __FUNC__ "MatView_SeqAIJ_Binary" 287480ef9eaSBarry Smith int MatView_SeqAIJ_Binary(Mat A,Viewer viewer) 28817ab2063SBarry Smith { 289416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 290416022c9SBarry Smith int i, fd, *col_lens, ierr; 29117ab2063SBarry Smith 2923a40ed3dSBarry Smith PetscFunctionBegin; 29390ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 2940452661fSBarry Smith col_lens = (int *) PetscMalloc( (4+a->m)*sizeof(int) );CHKPTRQ(col_lens); 295416022c9SBarry Smith col_lens[0] = MAT_COOKIE; 296416022c9SBarry Smith col_lens[1] = a->m; 297416022c9SBarry Smith col_lens[2] = a->n; 298416022c9SBarry Smith col_lens[3] = a->nz; 299416022c9SBarry Smith 300416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 301416022c9SBarry Smith for ( i=0; i<a->m; i++ ) { 302416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 30317ab2063SBarry Smith } 3040752156aSBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1);CHKERRQ(ierr); 305606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 306416022c9SBarry Smith 307416022c9SBarry Smith /* store column indices (zero start index) */ 308416022c9SBarry Smith if (a->indexshift) { 309416022c9SBarry Smith for ( i=0; i<a->nz; i++ ) a->j[i]--; 31017ab2063SBarry Smith } 3110752156aSBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,0);CHKERRQ(ierr); 312416022c9SBarry Smith if (a->indexshift) { 313416022c9SBarry Smith for ( i=0; i<a->nz; i++ ) a->j[i]++; 31417ab2063SBarry Smith } 315416022c9SBarry Smith 316416022c9SBarry Smith /* store nonzero values */ 3170752156aSBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,0);CHKERRQ(ierr); 3183a40ed3dSBarry Smith PetscFunctionReturn(0); 31917ab2063SBarry Smith } 320416022c9SBarry Smith 3215615d1e5SSatish Balay #undef __FUNC__ 3225615d1e5SSatish Balay #define __FUNC__ "MatView_SeqAIJ_ASCII" 323480ef9eaSBarry Smith int MatView_SeqAIJ_ASCII(Mat A,Viewer viewer) 324416022c9SBarry Smith { 325416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 3266831982aSBarry Smith int ierr, i,j, m = a->m, shift = a->indexshift, format; 32717ab2063SBarry Smith char *outputname; 32817ab2063SBarry Smith 3293a40ed3dSBarry Smith PetscFunctionBegin; 330fb4b0f7fSBarry Smith ierr = ViewerGetOutputname(viewer,&outputname);CHKERRQ(ierr); 331888f2ed8SSatish Balay ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr); 3326831982aSBarry Smith if (format == VIEWER_FORMAT_ASCII_INFO_LONG || format == VIEWER_FORMAT_ASCII_INFO) { 3336831982aSBarry Smith if (a->inode.size) { 3346831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"using I-node routines: found %d nodes, limit used is %d\n",a->inode.node_count,a->inode.limit);CHKERRQ(ierr); 3356831982aSBarry Smith } else { 3366831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"not using I-node routines\n");CHKERRQ(ierr); 3376831982aSBarry Smith } 3383a40ed3dSBarry Smith } else if (format == VIEWER_FORMAT_ASCII_MATLAB) { 339d00d2cf4SBarry Smith int nofinalvalue = 0; 340d00d2cf4SBarry Smith if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != a->n-!shift)) { 341d00d2cf4SBarry Smith nofinalvalue = 1; 342d00d2cf4SBarry Smith } 3436831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 3446831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"%% Size = %d %d \n",m,a->n);CHKERRQ(ierr); 3456831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"%% Nonzeros = %d \n",a->nz);CHKERRQ(ierr); 3466831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"zzz = zeros(%d,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 3476831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 34817ab2063SBarry Smith 34917ab2063SBarry Smith for (i=0; i<m; i++) { 350416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 351aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 3526831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"%d %d %18.16e + %18.16e i \n",i+1,a->j[j]+!shift,PetscReal(a->a[j]),PetscImaginary(a->a[j]));CHKERRQ(ierr); 35317ab2063SBarry Smith #else 3546831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"%d %d %18.16e\n", i+1, a->j[j]+!shift, a->a[j]);CHKERRQ(ierr); 35517ab2063SBarry Smith #endif 35617ab2063SBarry Smith } 35717ab2063SBarry Smith } 358d00d2cf4SBarry Smith if (nofinalvalue) { 3596831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"%d %d %18.16e\n", m, a->n, 0.0);CHKERRQ(ierr); 360d00d2cf4SBarry Smith } 3616831982aSBarry Smith if (outputname) {ierr = ViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",outputname);CHKERRQ(ierr);} 3626831982aSBarry Smith else {ierr = ViewerASCIIPrintf(viewer,"];\n M = spconvert(zzz);\n");CHKERRQ(ierr);} 3636831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 3643a40ed3dSBarry Smith } else if (format == VIEWER_FORMAT_ASCII_COMMON) { 3656831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 36644cd7ae7SLois Curfman McInnes for ( i=0; i<m; i++ ) { 3676831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr); 36844cd7ae7SLois Curfman McInnes for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 369aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 3706831982aSBarry Smith if (PetscImaginary(a->a[j]) > 0.0 && PetscReal(a->a[j]) != 0.0) { 3716831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",a->j[j]+shift,PetscReal(a->a[j]),PetscImaginary(a->a[j]));CHKERRQ(ierr); 3726831982aSBarry Smith } else if (PetscImaginary(a->a[j]) < 0.0 && PetscReal(a->a[j]) != 0.0) { 3736831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",a->j[j]+shift,PetscReal(a->a[j]),-PetscImaginary(a->a[j]));CHKERRQ(ierr); 3746831982aSBarry Smith } else if (PetscReal(a->a[j]) != 0.0) { 3756831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,PetscReal(a->a[j]));CHKERRQ(ierr); 3766831982aSBarry Smith } 37744cd7ae7SLois Curfman McInnes #else 3786831982aSBarry Smith if (a->a[j] != 0.0) {ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);} 37944cd7ae7SLois Curfman McInnes #endif 38044cd7ae7SLois Curfman McInnes } 3816831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 38244cd7ae7SLois Curfman McInnes } 3836831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 38402594712SBarry Smith } else if (format == VIEWER_FORMAT_ASCII_SYMMODU) { 385496be53dSLois Curfman McInnes int nzd=0, fshift=1, *sptr; 3866831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 3872e44a96cSLois Curfman McInnes sptr = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(sptr); 388496be53dSLois Curfman McInnes for ( i=0; i<m; i++ ) { 389496be53dSLois Curfman McInnes sptr[i] = nzd+1; 390496be53dSLois Curfman McInnes for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 391496be53dSLois Curfman McInnes if (a->j[j] >= i) { 392aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 393e20fef11SSatish Balay if (PetscImaginary(a->a[j]) != 0.0 || PetscReal(a->a[j]) != 0.0) nzd++; 394496be53dSLois Curfman McInnes #else 395496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 396496be53dSLois Curfman McInnes #endif 397496be53dSLois Curfman McInnes } 398496be53dSLois Curfman McInnes } 399496be53dSLois Curfman McInnes } 4002e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 4016831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %d\n\n",m,nzd);CHKERRQ(ierr); 4022e44a96cSLois Curfman McInnes for ( i=0; i<m+1; i+=6 ) { 4036831982aSBarry Smith if (i+4<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4],sptr[i+5]);CHKERRQ(ierr);} 4046831982aSBarry Smith else if (i+3<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4]);CHKERRQ(ierr);} 4056831982aSBarry Smith else if (i+2<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);} 4066831982aSBarry Smith else if (i+1<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);} 4076831982aSBarry Smith else if (i<m) {ierr = ViewerASCIIPrintf(viewer," %d %d\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);} 4086831982aSBarry Smith else {ierr = ViewerASCIIPrintf(viewer," %d\n",sptr[i]);CHKERRQ(ierr);} 409496be53dSLois Curfman McInnes } 4106831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 411606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 412496be53dSLois Curfman McInnes for ( i=0; i<m; i++ ) { 413496be53dSLois Curfman McInnes for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 4146831982aSBarry Smith if (a->j[j] >= i) {ierr = ViewerASCIIPrintf(viewer," %d ",a->j[j]+fshift);CHKERRQ(ierr);} 415496be53dSLois Curfman McInnes } 4166831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 417496be53dSLois Curfman McInnes } 4186831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 419496be53dSLois Curfman McInnes for ( i=0; i<m; i++ ) { 420496be53dSLois Curfman McInnes for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 421496be53dSLois Curfman McInnes if (a->j[j] >= i) { 422aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 4236831982aSBarry Smith if (PetscImaginary(a->a[j]) != 0.0 || PetscReal(a->a[j]) != 0.0) { 4246831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscReal(a->a[j]),PetscImaginary(a->a[j]));CHKERRQ(ierr); 4256831982aSBarry Smith } 426496be53dSLois Curfman McInnes #else 4276831982aSBarry Smith if (a->a[j] != 0.0) {ierr = ViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);} 428496be53dSLois Curfman McInnes #endif 429496be53dSLois Curfman McInnes } 430496be53dSLois Curfman McInnes } 4316831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 432496be53dSLois Curfman McInnes } 4336831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 43402594712SBarry Smith } else if (format == VIEWER_FORMAT_ASCII_DENSE) { 43502594712SBarry Smith int cnt = 0,jcnt; 43602594712SBarry Smith Scalar value; 43702594712SBarry Smith 4386831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 43902594712SBarry Smith for ( i=0; i<m; i++ ) { 44002594712SBarry Smith jcnt = 0; 44102594712SBarry Smith for ( j=0; j<a->n; j++ ) { 442e24b481bSBarry Smith if ( jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 44302594712SBarry Smith value = a->a[cnt++]; 444e24b481bSBarry Smith jcnt++; 44502594712SBarry Smith } else { 44602594712SBarry Smith value = 0.0; 44702594712SBarry Smith } 448aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 4496831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscReal(value),PetscImaginary(value));CHKERRQ(ierr); 45002594712SBarry Smith #else 4516831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr); 45202594712SBarry Smith #endif 45302594712SBarry Smith } 4546831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 45502594712SBarry Smith } 4566831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 4573a40ed3dSBarry Smith } else { 4586831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 45917ab2063SBarry Smith for ( i=0; i<m; i++ ) { 4606831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr); 461416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 462aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 463e20fef11SSatish Balay if (PetscImaginary(a->a[j]) > 0.0) { 4646831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",a->j[j]+shift,PetscReal(a->a[j]),PetscImaginary(a->a[j]));CHKERRQ(ierr); 465e20fef11SSatish Balay } else if (PetscImaginary(a->a[j]) < 0.0) { 4666831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",a->j[j]+shift,PetscReal(a->a[j]),-PetscImaginary(a->a[j]));CHKERRQ(ierr); 4673a40ed3dSBarry Smith } else { 4686831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,PetscReal(a->a[j]));CHKERRQ(ierr); 46917ab2063SBarry Smith } 47017ab2063SBarry Smith #else 4716831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 47217ab2063SBarry Smith #endif 47317ab2063SBarry Smith } 4746831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 47517ab2063SBarry Smith } 4766831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 47717ab2063SBarry Smith } 4786831982aSBarry Smith ierr = ViewerFlush(viewer);CHKERRQ(ierr); 4793a40ed3dSBarry Smith PetscFunctionReturn(0); 480416022c9SBarry Smith } 481416022c9SBarry Smith 4825615d1e5SSatish Balay #undef __FUNC__ 483480ef9eaSBarry Smith #define __FUNC__ "MatView_SeqAIJ_Draw_Zoom" 484480ef9eaSBarry Smith int MatView_SeqAIJ_Draw_Zoom(Draw draw,void *Aa) 485416022c9SBarry Smith { 486480ef9eaSBarry Smith Mat A = (Mat) Aa; 487416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 48877ed5343SBarry Smith int ierr, i,j, m = a->m, shift = a->indexshift,color,rank; 4890513a670SBarry Smith int format; 490480ef9eaSBarry Smith double xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0; 491480ef9eaSBarry Smith Viewer viewer; 49277ed5343SBarry Smith MPI_Comm comm; 493cddf8d76SBarry Smith 4943a40ed3dSBarry Smith PetscFunctionBegin; 49577ed5343SBarry Smith /* 49677ed5343SBarry Smith This is nasty. If this is called from an originally parallel matrix 49777ed5343SBarry Smith then all processes call this, but only the first has the matrix so the 49877ed5343SBarry Smith rest should return immediately. 49977ed5343SBarry Smith */ 50077ed5343SBarry Smith ierr = PetscObjectGetComm((PetscObject)draw,&comm);CHKERRQ(ierr); 501d132466eSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 50277ed5343SBarry Smith if (rank) PetscFunctionReturn(0); 50377ed5343SBarry Smith 504480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*) &viewer);CHKERRQ(ierr); 5050513a670SBarry Smith ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr); 50619bcc07fSBarry Smith 507480ef9eaSBarry Smith ierr = DrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 508416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 5090513a670SBarry Smith 5100513a670SBarry Smith if (format != VIEWER_FORMAT_DRAW_CONTOUR) { 5110513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 512cddf8d76SBarry Smith color = DRAW_BLUE; 513416022c9SBarry Smith for ( i=0; i<m; i++ ) { 514cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 515416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 516cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 517aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 518e20fef11SSatish Balay if (PetscReal(a->a[j]) >= 0.) continue; 519cddf8d76SBarry Smith #else 520cddf8d76SBarry Smith if (a->a[j] >= 0.) continue; 521cddf8d76SBarry Smith #endif 522480ef9eaSBarry Smith ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 523cddf8d76SBarry Smith } 524cddf8d76SBarry Smith } 525cddf8d76SBarry Smith color = DRAW_CYAN; 526cddf8d76SBarry Smith for ( i=0; i<m; i++ ) { 527cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 528cddf8d76SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 529cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 530cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 531480ef9eaSBarry Smith ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 532cddf8d76SBarry Smith } 533cddf8d76SBarry Smith } 534cddf8d76SBarry Smith color = DRAW_RED; 535cddf8d76SBarry Smith for ( i=0; i<m; i++ ) { 536cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 537cddf8d76SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 538cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 539aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 540e20fef11SSatish Balay if (PetscReal(a->a[j]) <= 0.) continue; 541cddf8d76SBarry Smith #else 542cddf8d76SBarry Smith if (a->a[j] <= 0.) continue; 543cddf8d76SBarry Smith #endif 544480ef9eaSBarry Smith ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 545416022c9SBarry Smith } 546416022c9SBarry Smith } 5470513a670SBarry Smith } else { 5480513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 5490513a670SBarry Smith /* first determine max of all nonzero values */ 5500513a670SBarry Smith int nz = a->nz,count; 5510513a670SBarry Smith Draw popup; 552480ef9eaSBarry Smith double scale; 5530513a670SBarry Smith 5540513a670SBarry Smith for ( i=0; i<nz; i++ ) { 5550513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 5560513a670SBarry Smith } 557480ef9eaSBarry Smith scale = (245.0 - DRAW_BASIC_COLORS)/maxv; 558522c5e43SBarry Smith ierr = DrawGetPopup(draw,&popup);CHKERRQ(ierr); 5590513a670SBarry Smith ierr = DrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr); 5600513a670SBarry Smith count = 0; 5610513a670SBarry Smith for ( i=0; i<m; i++ ) { 5620513a670SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 5630513a670SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 5640513a670SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 5656d6b6c30SSatish Balay color = DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(a->a[count])); 566480ef9eaSBarry Smith ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 5670513a670SBarry Smith count++; 5680513a670SBarry Smith } 5690513a670SBarry Smith } 5700513a670SBarry Smith } 571480ef9eaSBarry Smith PetscFunctionReturn(0); 572480ef9eaSBarry Smith } 573cddf8d76SBarry Smith 574480ef9eaSBarry Smith #undef __FUNC__ 575480ef9eaSBarry Smith #define __FUNC__ "MatView_SeqAIJ_Draw" 576480ef9eaSBarry Smith int MatView_SeqAIJ_Draw(Mat A,Viewer viewer) 577480ef9eaSBarry Smith { 578480ef9eaSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 579480ef9eaSBarry Smith int ierr; 580480ef9eaSBarry Smith Draw draw; 581480ef9eaSBarry Smith double xr,yr,xl,yl,h,w; 582480ef9eaSBarry Smith PetscTruth isnull; 583480ef9eaSBarry Smith 584480ef9eaSBarry Smith PetscFunctionBegin; 58577ed5343SBarry Smith ierr = ViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 586480ef9eaSBarry Smith ierr = DrawIsNull(draw,&isnull);CHKERRQ(ierr); 587480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 588480ef9eaSBarry Smith 589480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 590480ef9eaSBarry Smith xr = a->n; yr = a->m; h = yr/10.0; w = xr/10.0; 591480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 592cddf8d76SBarry Smith ierr = DrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 593480ef9eaSBarry Smith ierr = DrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 594480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 5953a40ed3dSBarry Smith PetscFunctionReturn(0); 596416022c9SBarry Smith } 597416022c9SBarry Smith 5985615d1e5SSatish Balay #undef __FUNC__ 599d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqAIJ" 600e1311b90SBarry Smith int MatView_SeqAIJ(Mat A,Viewer viewer) 601416022c9SBarry Smith { 602416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 603bcd2baecSBarry Smith int ierr; 6046831982aSBarry Smith PetscTruth issocket,isascii,isbinary,isdraw; 605416022c9SBarry Smith 6063a40ed3dSBarry Smith PetscFunctionBegin; 6076831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,SOCKET_VIEWER,&issocket);CHKERRQ(ierr); 6086831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,ASCII_VIEWER,&isascii);CHKERRQ(ierr); 6096831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,BINARY_VIEWER,&isbinary);CHKERRQ(ierr); 6106831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,DRAW_VIEWER,&isdraw);CHKERRQ(ierr); 6110f5bd95cSBarry Smith if (issocket) { 6127b2a1423SBarry Smith ierr = ViewerSocketPutSparse_Private(viewer,a->m,a->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr); 6130f5bd95cSBarry Smith } else if (isascii) { 6143a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 6150f5bd95cSBarry Smith } else if (isbinary) { 6163a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 6170f5bd95cSBarry Smith } else if (isdraw) { 6183a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 6195cd90555SBarry Smith } else { 6200f5bd95cSBarry Smith SETERRQ1(1,1,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name); 62117ab2063SBarry Smith } 6223a40ed3dSBarry Smith PetscFunctionReturn(0); 62317ab2063SBarry Smith } 62419bcc07fSBarry Smith 625c456f294SBarry Smith extern int Mat_AIJ_CheckInode(Mat); 6265615d1e5SSatish Balay #undef __FUNC__ 6275615d1e5SSatish Balay #define __FUNC__ "MatAssemblyEnd_SeqAIJ" 6288f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 62917ab2063SBarry Smith { 630416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 63141c01911SSatish Balay int fshift = 0,i,j,*ai = a->i, *aj = a->j, *imax = a->imax,ierr; 63243ee02c3SBarry Smith int m = a->m, *ip, N, *ailen = a->ilen,shift = a->indexshift,rmax = 0; 633416022c9SBarry Smith Scalar *aa = a->a, *ap; 63417ab2063SBarry Smith 6353a40ed3dSBarry Smith PetscFunctionBegin; 6363a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 63717ab2063SBarry Smith 63843ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 63917ab2063SBarry Smith for ( i=1; i<m; i++ ) { 640416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 64117ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 64294a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 64317ab2063SBarry Smith if (fshift) { 6440f5bd95cSBarry Smith ip = aj + ai[i] + shift; 6450f5bd95cSBarry Smith ap = aa + ai[i] + shift; 64617ab2063SBarry Smith N = ailen[i]; 64717ab2063SBarry Smith for ( j=0; j<N; j++ ) { 64817ab2063SBarry Smith ip[j-fshift] = ip[j]; 64917ab2063SBarry Smith ap[j-fshift] = ap[j]; 65017ab2063SBarry Smith } 65117ab2063SBarry Smith } 65217ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 65317ab2063SBarry Smith } 65417ab2063SBarry Smith if (m) { 65517ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 65617ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 65717ab2063SBarry Smith } 65817ab2063SBarry Smith /* reset ilen and imax for each row */ 65917ab2063SBarry Smith for ( i=0; i<m; i++ ) { 66017ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 66117ab2063SBarry Smith } 662416022c9SBarry Smith a->nz = ai[m] + shift; 66317ab2063SBarry Smith 66417ab2063SBarry Smith /* diagonals may have moved, so kill the diagonal pointers */ 665416022c9SBarry Smith if (fshift && a->diag) { 666606d414cSSatish Balay ierr = PetscFree(a->diag);CHKERRQ(ierr); 667416022c9SBarry Smith PLogObjectMemory(A,-(m+1)*sizeof(int)); 668416022c9SBarry Smith a->diag = 0; 66917ab2063SBarry Smith } 670*c38d4ed2SBarry Smith PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded, %d used\n",m,a->n,fshift,a->nz); 671*c38d4ed2SBarry Smith PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues() is %d\n",a->reallocs); 67294a9d846SBarry Smith PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Most nonzeros in any row is %d\n",rmax); 673dd5f02e7SSatish Balay a->reallocs = 0; 6744e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift; 6754e220ebcSLois Curfman McInnes 67676dd722bSSatish Balay /* check out for identical nodes. If found, use inode functions */ 67741c01911SSatish Balay ierr = Mat_AIJ_CheckInode(A);CHKERRQ(ierr); 6783a40ed3dSBarry Smith PetscFunctionReturn(0); 67917ab2063SBarry Smith } 68017ab2063SBarry Smith 6815615d1e5SSatish Balay #undef __FUNC__ 6825615d1e5SSatish Balay #define __FUNC__ "MatZeroEntries_SeqAIJ" 6838f6be9afSLois Curfman McInnes int MatZeroEntries_SeqAIJ(Mat A) 68417ab2063SBarry Smith { 685416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 686549d3d68SSatish Balay int ierr; 6873a40ed3dSBarry Smith 6883a40ed3dSBarry Smith PetscFunctionBegin; 689549d3d68SSatish Balay ierr = PetscMemzero(a->a,(a->i[a->m]+a->indexshift)*sizeof(Scalar));CHKERRQ(ierr); 6903a40ed3dSBarry Smith PetscFunctionReturn(0); 69117ab2063SBarry Smith } 692416022c9SBarry Smith 6935615d1e5SSatish Balay #undef __FUNC__ 6945615d1e5SSatish Balay #define __FUNC__ "MatDestroy_SeqAIJ" 695e1311b90SBarry Smith int MatDestroy_SeqAIJ(Mat A) 69617ab2063SBarry Smith { 697416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 69882bf6240SBarry Smith int ierr; 699d5d45c9bSBarry Smith 7003a40ed3dSBarry Smith PetscFunctionBegin; 70194d884c6SBarry Smith 70294d884c6SBarry Smith if (A->mapping) { 70394d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(A->mapping);CHKERRQ(ierr); 70494d884c6SBarry Smith } 70594d884c6SBarry Smith if (A->bmapping) { 70694d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(A->bmapping);CHKERRQ(ierr); 70794d884c6SBarry Smith } 70861b13de0SBarry Smith if (A->rmap) { 70961b13de0SBarry Smith ierr = MapDestroy(A->rmap);CHKERRQ(ierr); 71061b13de0SBarry Smith } 71161b13de0SBarry Smith if (A->cmap) { 71261b13de0SBarry Smith ierr = MapDestroy(A->cmap);CHKERRQ(ierr); 71361b13de0SBarry Smith } 714606d414cSSatish Balay if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);} 715aa482453SBarry Smith #if defined(PETSC_USE_LOG) 716e1311b90SBarry Smith PLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz); 71717ab2063SBarry Smith #endif 718606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 719606d414cSSatish Balay if (!a->singlemalloc) { 720606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 721606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 722606d414cSSatish Balay } 723*c38d4ed2SBarry Smith if (a->row) { 724*c38d4ed2SBarry Smith ierr = ISDestroy(a->row);CHKERRQ(ierr); 725*c38d4ed2SBarry Smith } 726*c38d4ed2SBarry Smith if (a->col) { 727*c38d4ed2SBarry Smith ierr = ISDestroy(a->col);CHKERRQ(ierr); 728*c38d4ed2SBarry Smith } 729606d414cSSatish Balay if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);} 730606d414cSSatish Balay if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);} 731606d414cSSatish Balay if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);} 732606d414cSSatish Balay if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);} 733606d414cSSatish Balay if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);} 73482bf6240SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 735606d414cSSatish Balay if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);} 736606d414cSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 737eed86810SBarry Smith 738f2655603SLois Curfman McInnes PLogObjectDestroy(A); 739f2655603SLois Curfman McInnes PetscHeaderDestroy(A); 7403a40ed3dSBarry Smith PetscFunctionReturn(0); 74117ab2063SBarry Smith } 74217ab2063SBarry Smith 7435615d1e5SSatish Balay #undef __FUNC__ 7445615d1e5SSatish Balay #define __FUNC__ "MatCompress_SeqAIJ" 7458f6be9afSLois Curfman McInnes int MatCompress_SeqAIJ(Mat A) 74617ab2063SBarry Smith { 7473a40ed3dSBarry Smith PetscFunctionBegin; 7483a40ed3dSBarry Smith PetscFunctionReturn(0); 74917ab2063SBarry Smith } 75017ab2063SBarry Smith 7515615d1e5SSatish Balay #undef __FUNC__ 7525615d1e5SSatish Balay #define __FUNC__ "MatSetOption_SeqAIJ" 7538f6be9afSLois Curfman McInnes int MatSetOption_SeqAIJ(Mat A,MatOption op) 75417ab2063SBarry Smith { 755416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 7563a40ed3dSBarry Smith 7573a40ed3dSBarry Smith PetscFunctionBegin; 7586d4a8577SBarry Smith if (op == MAT_ROW_ORIENTED) a->roworiented = 1; 7596d4a8577SBarry Smith else if (op == MAT_COLUMN_ORIENTED) a->roworiented = 0; 7606d4a8577SBarry Smith else if (op == MAT_COLUMNS_SORTED) a->sorted = 1; 761219d9a1aSLois Curfman McInnes else if (op == MAT_COLUMNS_UNSORTED) a->sorted = 0; 7626d4a8577SBarry Smith else if (op == MAT_NO_NEW_NONZERO_LOCATIONS) a->nonew = 1; 7634787f768SSatish Balay else if (op == MAT_NEW_NONZERO_LOCATION_ERR) a->nonew = -1; 7644787f768SSatish Balay else if (op == MAT_NEW_NONZERO_ALLOCATION_ERR) a->nonew = -2; 7656d4a8577SBarry Smith else if (op == MAT_YES_NEW_NONZERO_LOCATIONS) a->nonew = 0; 7666d4a8577SBarry Smith else if (op == MAT_ROWS_SORTED || 767219d9a1aSLois Curfman McInnes op == MAT_ROWS_UNSORTED || 7686d4a8577SBarry Smith op == MAT_SYMMETRIC || 7696d4a8577SBarry Smith op == MAT_STRUCTURALLY_SYMMETRIC || 77090f02eecSBarry Smith op == MAT_YES_NEW_DIAGONALS || 771b51ba29fSSatish Balay op == MAT_IGNORE_OFF_PROC_ENTRIES|| 772b51ba29fSSatish Balay op == MAT_USE_HASH_TABLE) 773981c4779SBarry Smith PLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n"); 7743a40ed3dSBarry Smith else if (op == MAT_NO_NEW_DIAGONALS) { 7753a40ed3dSBarry Smith SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS"); 7763a40ed3dSBarry Smith } else if (op == MAT_INODE_LIMIT_1) a->inode.limit = 1; 7776d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_2) a->inode.limit = 2; 7786d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_3) a->inode.limit = 3; 7796d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_4) a->inode.limit = 4; 7806d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_5) a->inode.limit = 5; 7813a40ed3dSBarry Smith else SETERRQ(PETSC_ERR_SUP,0,"unknown option"); 7823a40ed3dSBarry Smith PetscFunctionReturn(0); 78317ab2063SBarry Smith } 78417ab2063SBarry Smith 7855615d1e5SSatish Balay #undef __FUNC__ 7865615d1e5SSatish Balay #define __FUNC__ "MatGetDiagonal_SeqAIJ" 7878f6be9afSLois Curfman McInnes int MatGetDiagonal_SeqAIJ(Mat A,Vec v) 78817ab2063SBarry Smith { 789416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 7903a40ed3dSBarry Smith int i,j, n,shift = a->indexshift,ierr; 79117ab2063SBarry Smith Scalar *x, zero = 0.0; 79217ab2063SBarry Smith 7933a40ed3dSBarry Smith PetscFunctionBegin; 7943a40ed3dSBarry Smith ierr = VecSet(&zero,v);CHKERRQ(ierr); 795e1311b90SBarry Smith ierr = VecGetArray(v,&x);;CHKERRQ(ierr); 796e1311b90SBarry Smith ierr = VecGetLocalSize(v,&n);;CHKERRQ(ierr); 797a8c6a408SBarry Smith if (n != a->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Nonconforming matrix and vector"); 798416022c9SBarry Smith for ( i=0; i<a->m; i++ ) { 799416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 800416022c9SBarry Smith if (a->j[j]+shift == i) { 801416022c9SBarry Smith x[i] = a->a[j]; 80217ab2063SBarry Smith break; 80317ab2063SBarry Smith } 80417ab2063SBarry Smith } 80517ab2063SBarry Smith } 806e1311b90SBarry Smith ierr = VecRestoreArray(v,&x);;CHKERRQ(ierr); 8073a40ed3dSBarry Smith PetscFunctionReturn(0); 80817ab2063SBarry Smith } 80917ab2063SBarry Smith 81017ab2063SBarry Smith /* -------------------------------------------------------*/ 81117ab2063SBarry Smith /* Should check that shapes of vectors and matrices match */ 81217ab2063SBarry Smith /* -------------------------------------------------------*/ 8135615d1e5SSatish Balay #undef __FUNC__ 8145615d1e5SSatish Balay #define __FUNC__ "MatMultTrans_SeqAIJ" 81544cd7ae7SLois Curfman McInnes int MatMultTrans_SeqAIJ(Mat A,Vec xx,Vec yy) 81617ab2063SBarry Smith { 817416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 818f1af5d2fSBarry Smith Scalar *x, *y, *v, alpha, zero = 0.0; 819e1311b90SBarry Smith int ierr,m = a->m, n, i, *idx, shift = a->indexshift; 82017ab2063SBarry Smith 8213a40ed3dSBarry Smith PetscFunctionBegin; 822f1af5d2fSBarry Smith ierr = VecSet(&zero,yy);CHKERRQ(ierr); 823e1311b90SBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 824e1311b90SBarry Smith ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 82517ab2063SBarry Smith y = y + shift; /* shift for Fortran start by 1 indexing */ 82617ab2063SBarry Smith for ( i=0; i<m; i++ ) { 827416022c9SBarry Smith idx = a->j + a->i[i] + shift; 828416022c9SBarry Smith v = a->a + a->i[i] + shift; 829416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 83017ab2063SBarry Smith alpha = x[i]; 83117ab2063SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 83217ab2063SBarry Smith } 833416022c9SBarry Smith PLogFlops(2*a->nz - a->n); 834e1311b90SBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 835e1311b90SBarry Smith ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 8363a40ed3dSBarry Smith PetscFunctionReturn(0); 83717ab2063SBarry Smith } 838d5d45c9bSBarry Smith 8395615d1e5SSatish Balay #undef __FUNC__ 8405615d1e5SSatish Balay #define __FUNC__ "MatMultTransAdd_SeqAIJ" 84144cd7ae7SLois Curfman McInnes int MatMultTransAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 84217ab2063SBarry Smith { 843416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 84417ab2063SBarry Smith Scalar *x, *y, *v, alpha; 845e1311b90SBarry Smith int ierr,m = a->m, n, i, *idx,shift = a->indexshift; 84617ab2063SBarry Smith 8473a40ed3dSBarry Smith PetscFunctionBegin; 8482e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 849e1311b90SBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 850e1311b90SBarry Smith ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 85117ab2063SBarry Smith y = y + shift; /* shift for Fortran start by 1 indexing */ 85217ab2063SBarry Smith for ( i=0; i<m; i++ ) { 853416022c9SBarry Smith idx = a->j + a->i[i] + shift; 854416022c9SBarry Smith v = a->a + a->i[i] + shift; 855416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 85617ab2063SBarry Smith alpha = x[i]; 85717ab2063SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 85817ab2063SBarry Smith } 85990f02eecSBarry Smith PLogFlops(2*a->nz); 860e1311b90SBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 861e1311b90SBarry Smith ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 8623a40ed3dSBarry Smith PetscFunctionReturn(0); 86317ab2063SBarry Smith } 86417ab2063SBarry Smith 8655615d1e5SSatish Balay #undef __FUNC__ 8665615d1e5SSatish Balay #define __FUNC__ "MatMult_SeqAIJ" 86744cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 86817ab2063SBarry Smith { 869416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 87017ab2063SBarry Smith Scalar *x, *y, *v, sum; 871e1311b90SBarry Smith int ierr,m = a->m, *idx, shift = a->indexshift,*ii; 872aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 873e36a17ebSSatish Balay int n, i, jrow,j; 874e36a17ebSSatish Balay #endif 87517ab2063SBarry Smith 876aa482453SBarry Smith #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 877fee21e36SBarry Smith #pragma disjoint(*x,*y,*v) 878fee21e36SBarry Smith #endif 879fee21e36SBarry Smith 8803a40ed3dSBarry Smith PetscFunctionBegin; 881e1311b90SBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 882e1311b90SBarry Smith ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 88317ab2063SBarry Smith x = x + shift; /* shift for Fortran start by 1 indexing */ 884416022c9SBarry Smith idx = a->j; 885d64ed03dSBarry Smith v = a->a; 886416022c9SBarry Smith ii = a->i; 887aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 88829b5ca8aSSatish Balay fortranmultaij_(&m,x,ii,idx+shift,v+shift,y); 8898d195f9aSBarry Smith #else 890d64ed03dSBarry Smith v += shift; /* shift for Fortran start by 1 indexing */ 891d64ed03dSBarry Smith idx += shift; 89217ab2063SBarry Smith for ( i=0; i<m; i++ ) { 8939ea0dfa2SSatish Balay jrow = ii[i]; 8949ea0dfa2SSatish Balay n = ii[i+1] - jrow; 89517ab2063SBarry Smith sum = 0.0; 8969ea0dfa2SSatish Balay for ( j=0; j<n; j++) { 8979ea0dfa2SSatish Balay sum += v[jrow]*x[idx[jrow]]; jrow++; 8989ea0dfa2SSatish Balay } 89917ab2063SBarry Smith y[i] = sum; 90017ab2063SBarry Smith } 9018d195f9aSBarry Smith #endif 902416022c9SBarry Smith PLogFlops(2*a->nz - m); 903e1311b90SBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 904e1311b90SBarry Smith ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 9053a40ed3dSBarry Smith PetscFunctionReturn(0); 90617ab2063SBarry Smith } 90717ab2063SBarry Smith 9085615d1e5SSatish Balay #undef __FUNC__ 9095615d1e5SSatish Balay #define __FUNC__ "MatMultAdd_SeqAIJ" 91044cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 91117ab2063SBarry Smith { 912416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 91317ab2063SBarry Smith Scalar *x, *y, *z, *v, sum; 914e1311b90SBarry Smith int ierr,m = a->m, *idx, shift = a->indexshift,*ii; 915aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 916e36a17ebSSatish Balay int n,i,jrow,j; 917e36a17ebSSatish Balay #endif 9189ea0dfa2SSatish Balay 9193a40ed3dSBarry Smith PetscFunctionBegin; 920e1311b90SBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 921e1311b90SBarry Smith ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 9222e8a6d31SBarry Smith if (zz != yy) { 923e1311b90SBarry Smith ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 9242e8a6d31SBarry Smith } else { 9252e8a6d31SBarry Smith z = y; 9262e8a6d31SBarry Smith } 92717ab2063SBarry Smith x = x + shift; /* shift for Fortran start by 1 indexing */ 928cddf8d76SBarry Smith idx = a->j; 929d64ed03dSBarry Smith v = a->a; 930cddf8d76SBarry Smith ii = a->i; 931aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 93229b5ca8aSSatish Balay fortranmultaddaij_(&m,x,ii,idx+shift,v+shift,y,z); 93302ab625aSSatish Balay #else 934d64ed03dSBarry Smith v += shift; /* shift for Fortran start by 1 indexing */ 935d64ed03dSBarry Smith idx += shift; 93617ab2063SBarry Smith for ( i=0; i<m; i++ ) { 9379ea0dfa2SSatish Balay jrow = ii[i]; 9389ea0dfa2SSatish Balay n = ii[i+1] - jrow; 93917ab2063SBarry Smith sum = y[i]; 9409ea0dfa2SSatish Balay for ( j=0; j<n; j++) { 9419ea0dfa2SSatish Balay sum += v[jrow]*x[idx[jrow]]; jrow++; 9429ea0dfa2SSatish Balay } 94317ab2063SBarry Smith z[i] = sum; 94417ab2063SBarry Smith } 94502ab625aSSatish Balay #endif 946416022c9SBarry Smith PLogFlops(2*a->nz); 947e1311b90SBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 948e1311b90SBarry Smith ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 9492e8a6d31SBarry Smith if (zz != yy) { 950e1311b90SBarry Smith ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 9512e8a6d31SBarry Smith } 9523a40ed3dSBarry Smith PetscFunctionReturn(0); 95317ab2063SBarry Smith } 95417ab2063SBarry Smith 95517ab2063SBarry Smith /* 95617ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 95717ab2063SBarry Smith */ 9585615d1e5SSatish Balay #undef __FUNC__ 9595615d1e5SSatish Balay #define __FUNC__ "MatMarkDiag_SeqAIJ" 960416022c9SBarry Smith int MatMarkDiag_SeqAIJ(Mat A) 96117ab2063SBarry Smith { 962416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 963416022c9SBarry Smith int i,j, *diag, m = a->m,shift = a->indexshift; 96417ab2063SBarry Smith 9653a40ed3dSBarry Smith PetscFunctionBegin; 9660452661fSBarry Smith diag = (int *) PetscMalloc( (m+1)*sizeof(int));CHKPTRQ(diag); 967416022c9SBarry Smith PLogObjectMemory(A,(m+1)*sizeof(int)); 968416022c9SBarry Smith for ( i=0; i<a->m; i++ ) { 96935b0346bSBarry Smith diag[i] = a->i[i+1]; 970416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 971416022c9SBarry Smith if (a->j[j]+shift == i) { 97217ab2063SBarry Smith diag[i] = j - shift; 97317ab2063SBarry Smith break; 97417ab2063SBarry Smith } 97517ab2063SBarry Smith } 97617ab2063SBarry Smith } 977416022c9SBarry Smith a->diag = diag; 9783a40ed3dSBarry Smith PetscFunctionReturn(0); 97917ab2063SBarry Smith } 98017ab2063SBarry Smith 981be5855fcSBarry Smith /* 982be5855fcSBarry Smith Checks for missing diagonals 983be5855fcSBarry Smith */ 984be5855fcSBarry Smith #undef __FUNC__ 985be5855fcSBarry Smith #define __FUNC__ "MatMissingDiag_SeqAIJ" 986be5855fcSBarry Smith int MatMissingDiag_SeqAIJ(Mat A) 987be5855fcSBarry Smith { 988be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 989be5855fcSBarry Smith int *diag = a->diag, *jj = a->j,i,shift = a->indexshift; 990be5855fcSBarry Smith 991be5855fcSBarry Smith PetscFunctionBegin; 992be5855fcSBarry Smith for ( i=0; i<a->m; i++ ) { 993be5855fcSBarry Smith if (jj[diag[i]+shift] != i-shift) { 994be5855fcSBarry Smith SETERRQ1(1,1,"Matrix is missing diagonal number %d",i); 995be5855fcSBarry Smith } 996be5855fcSBarry Smith } 997be5855fcSBarry Smith PetscFunctionReturn(0); 998be5855fcSBarry Smith } 999be5855fcSBarry Smith 10005615d1e5SSatish Balay #undef __FUNC__ 10015615d1e5SSatish Balay #define __FUNC__ "MatRelax_SeqAIJ" 1002be5855fcSBarry Smith int MatRelax_SeqAIJ(Mat A,Vec bb,double omega,MatSORType flag,double fshift,int its,Vec xx) 100317ab2063SBarry Smith { 1004416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1005d6ed3216SSatish Balay Scalar *x, *b, *bs, d, *xs, sum, *v = a->a,*t=0,scale,*ts, *xb,*idiag=0; 1006d5d45c9bSBarry Smith int ierr, *idx, *diag,n = a->n, m = a->m, i, shift = a->indexshift; 100717ab2063SBarry Smith 10083a40ed3dSBarry Smith PetscFunctionBegin; 1009e1311b90SBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 1010fb2e594dSBarry Smith if (xx != bb) { 1011e1311b90SBarry Smith ierr = VecGetArray(bb,&b);CHKERRQ(ierr); 1012fb2e594dSBarry Smith } else { 1013fb2e594dSBarry Smith b = x; 1014fb2e594dSBarry Smith } 1015fb2e594dSBarry Smith 1016d00d2cf4SBarry Smith if (!a->diag) {ierr = MatMarkDiag_SeqAIJ(A);CHKERRQ(ierr);} 1017416022c9SBarry Smith diag = a->diag; 1018416022c9SBarry Smith xs = x + shift; /* shifted by one for index start of a or a->j*/ 101917ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 102017ab2063SBarry Smith /* apply ( U + D/omega) to the vector */ 102117ab2063SBarry Smith bs = b + shift; 102217ab2063SBarry Smith for ( i=0; i<m; i++ ) { 1023416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 1024416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1025488ecbafSBarry Smith PLogFlops(2*n-1); 1026416022c9SBarry Smith idx = a->j + diag[i] + (!shift); 1027416022c9SBarry Smith v = a->a + diag[i] + (!shift); 102817ab2063SBarry Smith sum = b[i]*d/omega; 102917ab2063SBarry Smith SPARSEDENSEDOT(sum,bs,v,idx,n); 103017ab2063SBarry Smith x[i] = sum; 103117ab2063SBarry Smith } 1032cb5b572fSBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 1033fb2e594dSBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 10343a40ed3dSBarry Smith PetscFunctionReturn(0); 103517ab2063SBarry Smith } 1036c783ea89SBarry Smith 1037c783ea89SBarry Smith /* setup workspace for Eisenstat */ 1038c783ea89SBarry Smith if (flag & SOR_EISENSTAT) { 1039c783ea89SBarry Smith if (!a->idiag) { 1040c783ea89SBarry Smith a->idiag = (Scalar *) PetscMalloc(2*m*sizeof(Scalar));CHKPTRQ(a->idiag); 1041c783ea89SBarry Smith a->ssor = a->idiag + m; 1042c783ea89SBarry Smith v = a->a; 1043c783ea89SBarry Smith for ( i=0; i<m; i++ ) { a->idiag[i] = 1.0/v[diag[i]];} 1044c783ea89SBarry Smith } 1045c783ea89SBarry Smith t = a->ssor; 1046c783ea89SBarry Smith idiag = a->idiag; 1047c783ea89SBarry Smith } 1048fc3d8934SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1049fc3d8934SBarry Smith U is upper triangular, E is diagonal; This routine applies 1050fc3d8934SBarry Smith 1051fc3d8934SBarry Smith (L + E)^{-1} A (U + E)^{-1} 1052fc3d8934SBarry Smith 1053fc3d8934SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 1054fc3d8934SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 105548af12d7SBarry Smith is the relaxation factor. 1056fc3d8934SBarry Smith */ 1057fc3d8934SBarry Smith 105848af12d7SBarry Smith if (flag == SOR_APPLY_LOWER) { 105948af12d7SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"SOR_APPLY_LOWER is not done"); 106048af12d7SBarry Smith } else if ((flag & SOR_EISENSTAT) && omega == 1.0 && shift == 0 && fshift == 0.0) { 106148af12d7SBarry Smith /* special case for omega = 1.0 saves flops and some integer ops */ 1062733d66baSBarry Smith Scalar *v2; 106348af12d7SBarry Smith 1064733d66baSBarry Smith v2 = a->a; 1065fc3d8934SBarry Smith /* x = (E + U)^{-1} b */ 1066fc3d8934SBarry Smith for ( i=m-1; i>=0; i-- ) { 1067fc3d8934SBarry Smith n = a->i[i+1] - diag[i] - 1; 1068fc3d8934SBarry Smith idx = a->j + diag[i] + 1; 1069fc3d8934SBarry Smith v = a->a + diag[i] + 1; 1070fc3d8934SBarry Smith sum = b[i]; 1071fc3d8934SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1072b4632166SBarry Smith x[i] = sum*idiag[i]; 1073fc3d8934SBarry Smith 1074fc3d8934SBarry Smith /* t = b - (2*E - D)x */ 1075733d66baSBarry Smith t[i] = b[i] - (v2[diag[i]])*x[i]; 1076733d66baSBarry Smith } 1077fc3d8934SBarry Smith 1078fc3d8934SBarry Smith /* t = (E + L)^{-1}t */ 1079fc3d8934SBarry Smith diag = a->diag; 1080fc3d8934SBarry Smith for ( i=0; i<m; i++ ) { 1081fc3d8934SBarry Smith n = diag[i] - a->i[i]; 1082fc3d8934SBarry Smith idx = a->j + a->i[i]; 1083fc3d8934SBarry Smith v = a->a + a->i[i]; 1084fc3d8934SBarry Smith sum = t[i]; 1085fc3d8934SBarry Smith SPARSEDENSEMDOT(sum,t,v,idx,n); 1086b4632166SBarry Smith t[i] = sum*idiag[i]; 1087fc3d8934SBarry Smith 1088fc3d8934SBarry Smith /* x = x + t */ 1089733d66baSBarry Smith x[i] += t[i]; 1090733d66baSBarry Smith } 1091733d66baSBarry Smith 1092a4d9cbf6SBarry Smith PLogFlops(3*m-1 + 2*a->nz); 1093fc3d8934SBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 1094fc3d8934SBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 1095fc3d8934SBarry Smith PetscFunctionReturn(0); 10963a40ed3dSBarry Smith } else if (flag & SOR_EISENSTAT) { 109717ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 109817ab2063SBarry Smith U is upper triangular, E is diagonal; This routine applies 109917ab2063SBarry Smith 110017ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 110117ab2063SBarry Smith 110217ab2063SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 110317ab2063SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 110417ab2063SBarry Smith is the relaxation factor. 110517ab2063SBarry Smith */ 110617ab2063SBarry Smith scale = (2.0/omega) - 1.0; 110717ab2063SBarry Smith 110817ab2063SBarry Smith /* x = (E + U)^{-1} b */ 110917ab2063SBarry Smith for ( i=m-1; i>=0; i-- ) { 1110416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 1111416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1112416022c9SBarry Smith idx = a->j + diag[i] + (!shift); 1113416022c9SBarry Smith v = a->a + diag[i] + (!shift); 111417ab2063SBarry Smith sum = b[i]; 111517ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 111617ab2063SBarry Smith x[i] = omega*(sum/d); 111717ab2063SBarry Smith } 111817ab2063SBarry Smith 111917ab2063SBarry Smith /* t = b - (2*E - D)x */ 1120416022c9SBarry Smith v = a->a; 112117ab2063SBarry Smith for ( i=0; i<m; i++ ) { t[i] = b[i] - scale*(v[*diag++ + shift])*x[i]; } 112217ab2063SBarry Smith 112317ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1124416022c9SBarry Smith ts = t + shift; /* shifted by one for index start of a or a->j*/ 1125416022c9SBarry Smith diag = a->diag; 112617ab2063SBarry Smith for ( i=0; i<m; i++ ) { 1127416022c9SBarry Smith d = fshift + a->a[diag[i]+shift]; 1128416022c9SBarry Smith n = diag[i] - a->i[i]; 1129416022c9SBarry Smith idx = a->j + a->i[i] + shift; 1130416022c9SBarry Smith v = a->a + a->i[i] + shift; 113117ab2063SBarry Smith sum = t[i]; 113217ab2063SBarry Smith SPARSEDENSEMDOT(sum,ts,v,idx,n); 113317ab2063SBarry Smith t[i] = omega*(sum/d); 1134733d66baSBarry Smith /* x = x + t */ 1135733d66baSBarry Smith x[i] += t[i]; 113617ab2063SBarry Smith } 113717ab2063SBarry Smith 1138c783ea89SBarry Smith PLogFlops(6*m-1 + 2*a->nz); 1139cb5b572fSBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 1140fb2e594dSBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 11413a40ed3dSBarry Smith PetscFunctionReturn(0); 114217ab2063SBarry Smith } 114317ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 114417ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 114517ab2063SBarry Smith for ( i=0; i<m; i++ ) { 1146416022c9SBarry Smith d = fshift + a->a[diag[i]+shift]; 1147416022c9SBarry Smith n = diag[i] - a->i[i]; 1148488ecbafSBarry Smith PLogFlops(2*n-1); 1149416022c9SBarry Smith idx = a->j + a->i[i] + shift; 1150416022c9SBarry Smith v = a->a + a->i[i] + shift; 115117ab2063SBarry Smith sum = b[i]; 115217ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 115317ab2063SBarry Smith x[i] = omega*(sum/d); 115417ab2063SBarry Smith } 115517ab2063SBarry Smith xb = x; 11563a40ed3dSBarry Smith } else xb = b; 115717ab2063SBarry Smith if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) && 115817ab2063SBarry Smith (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) { 115917ab2063SBarry Smith for ( i=0; i<m; i++ ) { 1160416022c9SBarry Smith x[i] *= a->a[diag[i]+shift]; 116117ab2063SBarry Smith } 1162488ecbafSBarry Smith PLogFlops(m); 116317ab2063SBarry Smith } 116417ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 116517ab2063SBarry Smith for ( i=m-1; i>=0; i-- ) { 1166416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 1167416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1168488ecbafSBarry Smith PLogFlops(2*n-1); 1169416022c9SBarry Smith idx = a->j + diag[i] + (!shift); 1170416022c9SBarry Smith v = a->a + diag[i] + (!shift); 117117ab2063SBarry Smith sum = xb[i]; 117217ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 117317ab2063SBarry Smith x[i] = omega*(sum/d); 117417ab2063SBarry Smith } 117517ab2063SBarry Smith } 117617ab2063SBarry Smith its--; 117717ab2063SBarry Smith } 117817ab2063SBarry Smith while (its--) { 117917ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 118017ab2063SBarry Smith for ( i=0; i<m; i++ ) { 1181416022c9SBarry Smith d = fshift + a->a[diag[i]+shift]; 1182416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1183488ecbafSBarry Smith PLogFlops(2*n-1); 1184416022c9SBarry Smith idx = a->j + a->i[i] + shift; 1185416022c9SBarry Smith v = a->a + a->i[i] + shift; 118617ab2063SBarry Smith sum = b[i]; 118717ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 11887e33a6baSBarry Smith x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d; 118917ab2063SBarry Smith } 119017ab2063SBarry Smith } 119117ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 119217ab2063SBarry Smith for ( i=m-1; i>=0; i-- ) { 1193416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 1194416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1195488ecbafSBarry Smith PLogFlops(2*n-1); 1196416022c9SBarry Smith idx = a->j + a->i[i] + shift; 1197416022c9SBarry Smith v = a->a + a->i[i] + shift; 119817ab2063SBarry Smith sum = b[i]; 119917ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 12007e33a6baSBarry Smith x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d; 120117ab2063SBarry Smith } 120217ab2063SBarry Smith } 120317ab2063SBarry Smith } 1204cb5b572fSBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 1205fb2e594dSBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 12063a40ed3dSBarry Smith PetscFunctionReturn(0); 120717ab2063SBarry Smith } 120817ab2063SBarry Smith 12095615d1e5SSatish Balay #undef __FUNC__ 12105615d1e5SSatish Balay #define __FUNC__ "MatGetInfo_SeqAIJ" 12118f6be9afSLois Curfman McInnes int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 121217ab2063SBarry Smith { 1213416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 12144e220ebcSLois Curfman McInnes 12153a40ed3dSBarry Smith PetscFunctionBegin; 12164e220ebcSLois Curfman McInnes info->rows_global = (double)a->m; 12174e220ebcSLois Curfman McInnes info->columns_global = (double)a->n; 12184e220ebcSLois Curfman McInnes info->rows_local = (double)a->m; 12194e220ebcSLois Curfman McInnes info->columns_local = (double)a->n; 12204e220ebcSLois Curfman McInnes info->block_size = 1.0; 12214e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 12224e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 12234e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 12244e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 12254e220ebcSLois Curfman McInnes info->mallocs = (double)a->reallocs; 12264e220ebcSLois Curfman McInnes info->memory = A->mem; 12274e220ebcSLois Curfman McInnes if (A->factor) { 12284e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 12294e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 12304e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 12314e220ebcSLois Curfman McInnes } else { 12324e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 12334e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 12344e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 12354e220ebcSLois Curfman McInnes } 12363a40ed3dSBarry Smith PetscFunctionReturn(0); 123717ab2063SBarry Smith } 123817ab2063SBarry Smith 123917ab2063SBarry Smith extern int MatLUFactorSymbolic_SeqAIJ(Mat,IS,IS,double,Mat*); 124017ab2063SBarry Smith extern int MatLUFactorNumeric_SeqAIJ(Mat,Mat*); 124117ab2063SBarry Smith extern int MatLUFactor_SeqAIJ(Mat,IS,IS,double); 124217ab2063SBarry Smith extern int MatSolve_SeqAIJ(Mat,Vec,Vec); 124317ab2063SBarry Smith extern int MatSolveAdd_SeqAIJ(Mat,Vec,Vec,Vec); 124417ab2063SBarry Smith extern int MatSolveTrans_SeqAIJ(Mat,Vec,Vec); 124517ab2063SBarry Smith extern int MatSolveTransAdd_SeqAIJ(Mat,Vec,Vec,Vec); 124617ab2063SBarry Smith 12475615d1e5SSatish Balay #undef __FUNC__ 12485615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqAIJ" 12498f6be9afSLois Curfman McInnes int MatZeroRows_SeqAIJ(Mat A,IS is,Scalar *diag) 125017ab2063SBarry Smith { 1251416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1252416022c9SBarry Smith int i,ierr,N, *rows,m = a->m - 1,shift = a->indexshift; 125317ab2063SBarry Smith 12543a40ed3dSBarry Smith PetscFunctionBegin; 125577c4ece6SBarry Smith ierr = ISGetSize(is,&N);CHKERRQ(ierr); 125617ab2063SBarry Smith ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 125717ab2063SBarry Smith if (diag) { 125817ab2063SBarry Smith for ( i=0; i<N; i++ ) { 1259a8c6a408SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range"); 12607ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1261416022c9SBarry Smith a->ilen[rows[i]] = 1; 1262416022c9SBarry Smith a->a[a->i[rows[i]]+shift] = *diag; 1263416022c9SBarry Smith a->j[a->i[rows[i]]+shift] = rows[i]+shift; 12647ae801bdSBarry Smith } else { /* in case row was completely empty */ 1265d64ed03dSBarry Smith ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr); 126617ab2063SBarry Smith } 126717ab2063SBarry Smith } 12683a40ed3dSBarry Smith } else { 126917ab2063SBarry Smith for ( i=0; i<N; i++ ) { 1270a8c6a408SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range"); 1271416022c9SBarry Smith a->ilen[rows[i]] = 0; 127217ab2063SBarry Smith } 127317ab2063SBarry Smith } 12747ae801bdSBarry Smith ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 127543a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 12763a40ed3dSBarry Smith PetscFunctionReturn(0); 127717ab2063SBarry Smith } 127817ab2063SBarry Smith 12795615d1e5SSatish Balay #undef __FUNC__ 12805615d1e5SSatish Balay #define __FUNC__ "MatGetSize_SeqAIJ" 12818f6be9afSLois Curfman McInnes int MatGetSize_SeqAIJ(Mat A,int *m,int *n) 128217ab2063SBarry Smith { 1283416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 12843a40ed3dSBarry Smith 12853a40ed3dSBarry Smith PetscFunctionBegin; 12860752156aSBarry Smith if (m) *m = a->m; 12870752156aSBarry Smith if (n) *n = a->n; 12883a40ed3dSBarry Smith PetscFunctionReturn(0); 128917ab2063SBarry Smith } 129017ab2063SBarry Smith 12915615d1e5SSatish Balay #undef __FUNC__ 12925615d1e5SSatish Balay #define __FUNC__ "MatGetOwnershipRange_SeqAIJ" 12938f6be9afSLois Curfman McInnes int MatGetOwnershipRange_SeqAIJ(Mat A,int *m,int *n) 129417ab2063SBarry Smith { 1295416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 12963a40ed3dSBarry Smith 12973a40ed3dSBarry Smith PetscFunctionBegin; 1298416022c9SBarry Smith *m = 0; *n = a->m; 12993a40ed3dSBarry Smith PetscFunctionReturn(0); 130017ab2063SBarry Smith } 1301026e39d0SSatish Balay 13025615d1e5SSatish Balay #undef __FUNC__ 13035615d1e5SSatish Balay #define __FUNC__ "MatGetRow_SeqAIJ" 13044e093b46SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 130517ab2063SBarry Smith { 1306416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1307c456f294SBarry Smith int *itmp,i,shift = a->indexshift; 130817ab2063SBarry Smith 13093a40ed3dSBarry Smith PetscFunctionBegin; 1310a8c6a408SBarry Smith if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range"); 131117ab2063SBarry Smith 1312416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1313416022c9SBarry Smith if (v) *v = a->a + a->i[row] + shift; 131417ab2063SBarry Smith if (idx) { 1315416022c9SBarry Smith itmp = a->j + a->i[row] + shift; 13164e093b46SBarry Smith if (*nz && shift) { 13170452661fSBarry Smith *idx = (int *) PetscMalloc( (*nz)*sizeof(int) );CHKPTRQ(*idx); 131817ab2063SBarry Smith for ( i=0; i<(*nz); i++ ) {(*idx)[i] = itmp[i] + shift;} 13194e093b46SBarry Smith } else if (*nz) { 13204e093b46SBarry Smith *idx = itmp; 132117ab2063SBarry Smith } 132217ab2063SBarry Smith else *idx = 0; 132317ab2063SBarry Smith } 13243a40ed3dSBarry Smith PetscFunctionReturn(0); 132517ab2063SBarry Smith } 132617ab2063SBarry Smith 13275615d1e5SSatish Balay #undef __FUNC__ 13285615d1e5SSatish Balay #define __FUNC__ "MatRestoreRow_SeqAIJ" 13294e093b46SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 133017ab2063SBarry Smith { 13314e093b46SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1332606d414cSSatish Balay int ierr; 13333a40ed3dSBarry Smith 13343a40ed3dSBarry Smith PetscFunctionBegin; 1335606d414cSSatish Balay if (idx) {if (*idx && a->indexshift) {ierr = PetscFree(*idx);CHKERRQ(ierr);}} 13363a40ed3dSBarry Smith PetscFunctionReturn(0); 133717ab2063SBarry Smith } 133817ab2063SBarry Smith 13395615d1e5SSatish Balay #undef __FUNC__ 13405615d1e5SSatish Balay #define __FUNC__ "MatNorm_SeqAIJ" 13418f6be9afSLois Curfman McInnes int MatNorm_SeqAIJ(Mat A,NormType type,double *norm) 134217ab2063SBarry Smith { 1343416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1344416022c9SBarry Smith Scalar *v = a->a; 134517ab2063SBarry Smith double sum = 0.0; 1346549d3d68SSatish Balay int i, j,shift = a->indexshift,ierr; 134717ab2063SBarry Smith 13483a40ed3dSBarry Smith PetscFunctionBegin; 134917ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1350416022c9SBarry Smith for (i=0; i<a->nz; i++ ) { 1351aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 1352e20fef11SSatish Balay sum += PetscReal(PetscConj(*v)*(*v)); v++; 135317ab2063SBarry Smith #else 135417ab2063SBarry Smith sum += (*v)*(*v); v++; 135517ab2063SBarry Smith #endif 135617ab2063SBarry Smith } 135717ab2063SBarry Smith *norm = sqrt(sum); 13583a40ed3dSBarry Smith } else if (type == NORM_1) { 135917ab2063SBarry Smith double *tmp; 1360416022c9SBarry Smith int *jj = a->j; 136166963ce1SSatish Balay tmp = (double *) PetscMalloc( (a->n+1)*sizeof(double) );CHKPTRQ(tmp); 1362549d3d68SSatish Balay ierr = PetscMemzero(tmp,a->n*sizeof(double));CHKERRQ(ierr); 136317ab2063SBarry Smith *norm = 0.0; 1364416022c9SBarry Smith for ( j=0; j<a->nz; j++ ) { 1365a2744918SBarry Smith tmp[*jj++ + shift] += PetscAbsScalar(*v); v++; 136617ab2063SBarry Smith } 1367416022c9SBarry Smith for ( j=0; j<a->n; j++ ) { 136817ab2063SBarry Smith if (tmp[j] > *norm) *norm = tmp[j]; 136917ab2063SBarry Smith } 1370606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 13713a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 137217ab2063SBarry Smith *norm = 0.0; 1373416022c9SBarry Smith for ( j=0; j<a->m; j++ ) { 1374416022c9SBarry Smith v = a->a + a->i[j] + shift; 137517ab2063SBarry Smith sum = 0.0; 1376416022c9SBarry Smith for ( i=0; i<a->i[j+1]-a->i[j]; i++ ) { 1377cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 137817ab2063SBarry Smith } 137917ab2063SBarry Smith if (sum > *norm) *norm = sum; 138017ab2063SBarry Smith } 13813a40ed3dSBarry Smith } else { 1382a8c6a408SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"No support for two norm"); 138317ab2063SBarry Smith } 13843a40ed3dSBarry Smith PetscFunctionReturn(0); 138517ab2063SBarry Smith } 138617ab2063SBarry Smith 13875615d1e5SSatish Balay #undef __FUNC__ 13885615d1e5SSatish Balay #define __FUNC__ "MatTranspose_SeqAIJ" 13898f6be9afSLois Curfman McInnes int MatTranspose_SeqAIJ(Mat A,Mat *B) 139017ab2063SBarry Smith { 1391416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1392416022c9SBarry Smith Mat C; 1393416022c9SBarry Smith int i, ierr, *aj = a->j, *ai = a->i, m = a->m, len, *col; 1394416022c9SBarry Smith int shift = a->indexshift; 1395d5d45c9bSBarry Smith Scalar *array = a->a; 139617ab2063SBarry Smith 13973a40ed3dSBarry Smith PetscFunctionBegin; 1398a8c6a408SBarry Smith if (B == PETSC_NULL && m != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Square matrix only for in-place"); 13990452661fSBarry Smith col = (int *) PetscMalloc((1+a->n)*sizeof(int));CHKPTRQ(col); 1400549d3d68SSatish Balay ierr = PetscMemzero(col,(1+a->n)*sizeof(int));CHKERRQ(ierr); 140117ab2063SBarry Smith if (shift) { 140217ab2063SBarry Smith for ( i=0; i<ai[m]-1; i++ ) aj[i] -= 1; 140317ab2063SBarry Smith } 140417ab2063SBarry Smith for ( i=0; i<ai[m]+shift; i++ ) col[aj[i]] += 1; 1405416022c9SBarry Smith ierr = MatCreateSeqAIJ(A->comm,a->n,m,0,col,&C);CHKERRQ(ierr); 1406606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 140717ab2063SBarry Smith for ( i=0; i<m; i++ ) { 140817ab2063SBarry Smith len = ai[i+1]-ai[i]; 1409416022c9SBarry Smith ierr = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 141017ab2063SBarry Smith array += len; aj += len; 141117ab2063SBarry Smith } 141217ab2063SBarry Smith if (shift) { 141317ab2063SBarry Smith for ( i=0; i<ai[m]-1; i++ ) aj[i] += 1; 141417ab2063SBarry Smith } 141517ab2063SBarry Smith 14166d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14176d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 141817ab2063SBarry Smith 14193638b69dSLois Curfman McInnes if (B != PETSC_NULL) { 1420416022c9SBarry Smith *B = C; 142117ab2063SBarry Smith } else { 1422f830108cSBarry Smith PetscOps *Abops; 14230a6ffc59SBarry Smith MatOps Aops; 1424f830108cSBarry Smith 1425416022c9SBarry Smith /* This isn't really an in-place transpose */ 1426606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 1427606d414cSSatish Balay if (!a->singlemalloc) { 1428606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 1429606d414cSSatish Balay ierr = PetscFree(a->j); 1430606d414cSSatish Balay } 1431606d414cSSatish Balay if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);} 1432606d414cSSatish Balay if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);} 1433606d414cSSatish Balay if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);} 1434606d414cSSatish Balay if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);} 1435606d414cSSatish Balay if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);} 1436606d414cSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 1437f830108cSBarry Smith 1438488ecbafSBarry Smith 1439488ecbafSBarry Smith ierr = MapDestroy(A->rmap);CHKERRQ(ierr); 1440488ecbafSBarry Smith ierr = MapDestroy(A->cmap);CHKERRQ(ierr); 1441488ecbafSBarry Smith 1442f830108cSBarry Smith /* 1443f830108cSBarry Smith This is horrible, horrible code. We need to keep the 14448f0f457cSSatish Balay the bops and ops Structures, copy everything from C 14458f0f457cSSatish Balay including the function pointers.. 1446f830108cSBarry Smith */ 1447549d3d68SSatish Balay ierr = PetscMemcpy(A->ops,C->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 1448549d3d68SSatish Balay ierr = PetscMemcpy(A->bops,C->bops,sizeof(PetscOps));CHKERRQ(ierr); 1449f830108cSBarry Smith Abops = A->bops; 1450f830108cSBarry Smith Aops = A->ops; 1451549d3d68SSatish Balay ierr = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr); 1452f830108cSBarry Smith A->bops = Abops; 1453f830108cSBarry Smith A->ops = Aops; 145427a8da17SBarry Smith A->qlist = 0; 1455f830108cSBarry Smith 14560452661fSBarry Smith PetscHeaderDestroy(C); 145717ab2063SBarry Smith } 14583a40ed3dSBarry Smith PetscFunctionReturn(0); 145917ab2063SBarry Smith } 146017ab2063SBarry Smith 14615615d1e5SSatish Balay #undef __FUNC__ 14625615d1e5SSatish Balay #define __FUNC__ "MatDiagonalScale_SeqAIJ" 14638f6be9afSLois Curfman McInnes int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 146417ab2063SBarry Smith { 1465416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 146617ab2063SBarry Smith Scalar *l,*r,x,*v; 1467e1311b90SBarry Smith int ierr,i,j,m = a->m, n = a->n, M, nz = a->nz, *jj,shift = a->indexshift; 146817ab2063SBarry Smith 14693a40ed3dSBarry Smith PetscFunctionBegin; 147017ab2063SBarry Smith if (ll) { 14713ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 14723ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 1473e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 1474a8c6a408SBarry Smith if (m != a->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Left scaling vector wrong length"); 1475e1311b90SBarry Smith ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 1476416022c9SBarry Smith v = a->a; 147717ab2063SBarry Smith for ( i=0; i<m; i++ ) { 147817ab2063SBarry Smith x = l[i]; 1479416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 148017ab2063SBarry Smith for ( j=0; j<M; j++ ) { (*v++) *= x;} 148117ab2063SBarry Smith } 1482e1311b90SBarry Smith ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 148344cd7ae7SLois Curfman McInnes PLogFlops(nz); 148417ab2063SBarry Smith } 148517ab2063SBarry Smith if (rr) { 1486e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 1487a8c6a408SBarry Smith if (n != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Right scaling vector wrong length"); 1488e1311b90SBarry Smith ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 1489416022c9SBarry Smith v = a->a; jj = a->j; 149017ab2063SBarry Smith for ( i=0; i<nz; i++ ) { 149117ab2063SBarry Smith (*v++) *= r[*jj++ + shift]; 149217ab2063SBarry Smith } 1493e1311b90SBarry Smith ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 149444cd7ae7SLois Curfman McInnes PLogFlops(nz); 149517ab2063SBarry Smith } 14963a40ed3dSBarry Smith PetscFunctionReturn(0); 149717ab2063SBarry Smith } 149817ab2063SBarry Smith 14995615d1e5SSatish Balay #undef __FUNC__ 15005615d1e5SSatish Balay #define __FUNC__ "MatGetSubMatrix_SeqAIJ" 15017b2a1423SBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatReuse scall,Mat *B) 150217ab2063SBarry Smith { 1503db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data,*c; 1504d5db1b72SBarry Smith int *smap, i, k, kstart, kend, ierr, oldcols = a->n,*lens; 150599141d43SSatish Balay int row,mat_i,*mat_j,tcol,first,step,*mat_ilen; 1506a2744918SBarry Smith register int sum,lensi; 150799141d43SSatish Balay int *irow, *icol, nrows, ncols, shift = a->indexshift,*ssmap; 150899141d43SSatish Balay int *starts,*j_new,*i_new,*aj = a->j, *ai = a->i,ii,*ailen = a->ilen; 150999141d43SSatish Balay Scalar *a_new,*mat_a; 1510416022c9SBarry Smith Mat C; 1511fee21e36SBarry Smith PetscTruth stride; 151217ab2063SBarry Smith 15133a40ed3dSBarry Smith PetscFunctionBegin; 1514d64ed03dSBarry Smith ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr); 1515a8c6a408SBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"ISrow is not sorted"); 1516d64ed03dSBarry Smith ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr); 1517a8c6a408SBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"IScol is not sorted"); 151899141d43SSatish Balay 151917ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 152017ab2063SBarry Smith ierr = ISGetSize(isrow,&nrows);CHKERRQ(ierr); 152117ab2063SBarry Smith ierr = ISGetSize(iscol,&ncols);CHKERRQ(ierr); 152217ab2063SBarry Smith 1523fee21e36SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 1524fee21e36SBarry Smith ierr = ISStride(iscol,&stride);CHKERRQ(ierr); 1525fee21e36SBarry Smith if (stride && step == 1) { 152602834360SBarry Smith /* special case of contiguous rows */ 152757faeb66SBarry Smith lens = (int *) PetscMalloc((ncols+nrows+1)*sizeof(int));CHKPTRQ(lens); 152802834360SBarry Smith starts = lens + ncols; 152902834360SBarry Smith /* loop over new rows determining lens and starting points */ 153002834360SBarry Smith for (i=0; i<nrows; i++) { 1531a2744918SBarry Smith kstart = ai[irow[i]]+shift; 1532a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 153302834360SBarry Smith for ( k=kstart; k<kend; k++ ) { 1534d8ced48eSBarry Smith if (aj[k]+shift >= first) { 153502834360SBarry Smith starts[i] = k; 153602834360SBarry Smith break; 153702834360SBarry Smith } 153802834360SBarry Smith } 1539a2744918SBarry Smith sum = 0; 154002834360SBarry Smith while (k < kend) { 1541d8ced48eSBarry Smith if (aj[k++]+shift >= first+ncols) break; 1542a2744918SBarry Smith sum++; 154302834360SBarry Smith } 1544a2744918SBarry Smith lens[i] = sum; 154502834360SBarry Smith } 154602834360SBarry Smith /* create submatrix */ 1547cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 154808480c60SBarry Smith int n_cols,n_rows; 154908480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 1550a8c6a408SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Reused submatrix wrong size"); 1551d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 155208480c60SBarry Smith C = *B; 15533a40ed3dSBarry Smith } else { 155402834360SBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 155508480c60SBarry Smith } 1556db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*) C->data; 1557db02288aSLois Curfman McInnes 155802834360SBarry Smith /* loop over rows inserting into submatrix */ 1559db02288aSLois Curfman McInnes a_new = c->a; 1560db02288aSLois Curfman McInnes j_new = c->j; 1561db02288aSLois Curfman McInnes i_new = c->i; 1562db02288aSLois Curfman McInnes i_new[0] = -shift; 156302834360SBarry Smith for (i=0; i<nrows; i++) { 1564a2744918SBarry Smith ii = starts[i]; 1565a2744918SBarry Smith lensi = lens[i]; 1566a2744918SBarry Smith for ( k=0; k<lensi; k++ ) { 1567a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 156802834360SBarry Smith } 1569549d3d68SSatish Balay ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(Scalar));CHKERRQ(ierr); 1570a2744918SBarry Smith a_new += lensi; 1571a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 1572a2744918SBarry Smith c->ilen[i] = lensi; 157302834360SBarry Smith } 1574606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 15753a40ed3dSBarry Smith } else { 157602834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 15770452661fSBarry Smith smap = (int *) PetscMalloc((1+oldcols)*sizeof(int));CHKPTRQ(smap); 157802834360SBarry Smith ssmap = smap + shift; 157999141d43SSatish Balay lens = (int *) PetscMalloc((1+nrows)*sizeof(int));CHKPTRQ(lens); 1580549d3d68SSatish Balay ierr = PetscMemzero(smap,oldcols*sizeof(int));CHKERRQ(ierr); 158117ab2063SBarry Smith for ( i=0; i<ncols; i++ ) smap[icol[i]] = i+1; 158202834360SBarry Smith /* determine lens of each row */ 158302834360SBarry Smith for (i=0; i<nrows; i++) { 1584d8ced48eSBarry Smith kstart = ai[irow[i]]+shift; 158502834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 158602834360SBarry Smith lens[i] = 0; 158702834360SBarry Smith for ( k=kstart; k<kend; k++ ) { 1588d8ced48eSBarry Smith if (ssmap[aj[k]]) { 158902834360SBarry Smith lens[i]++; 159002834360SBarry Smith } 159102834360SBarry Smith } 159202834360SBarry Smith } 159317ab2063SBarry Smith /* Create and fill new matrix */ 1594a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 15950f5bd95cSBarry Smith PetscTruth equal; 15960f5bd95cSBarry Smith 159799141d43SSatish Balay c = (Mat_SeqAIJ *)((*B)->data); 1598a8c6a408SBarry Smith if (c->m != nrows || c->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong size"); 15990f5bd95cSBarry Smith ierr = PetscMemcmp(c->ilen,lens, c->m*sizeof(int),&equal);CHKERRQ(ierr); 16000f5bd95cSBarry Smith if (!equal) { 1601a8c6a408SBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong no of nonzeros"); 160299141d43SSatish Balay } 1603549d3d68SSatish Balay ierr = PetscMemzero(c->ilen,c->m*sizeof(int));CHKERRQ(ierr); 160408480c60SBarry Smith C = *B; 16053a40ed3dSBarry Smith } else { 160602834360SBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 160708480c60SBarry Smith } 160899141d43SSatish Balay c = (Mat_SeqAIJ *)(C->data); 160917ab2063SBarry Smith for (i=0; i<nrows; i++) { 161099141d43SSatish Balay row = irow[i]; 161199141d43SSatish Balay kstart = ai[row]+shift; 161299141d43SSatish Balay kend = kstart + a->ilen[row]; 161399141d43SSatish Balay mat_i = c->i[i]+shift; 161499141d43SSatish Balay mat_j = c->j + mat_i; 161599141d43SSatish Balay mat_a = c->a + mat_i; 161699141d43SSatish Balay mat_ilen = c->ilen + i; 161717ab2063SBarry Smith for ( k=kstart; k<kend; k++ ) { 161899141d43SSatish Balay if ((tcol=ssmap[a->j[k]])) { 161999141d43SSatish Balay *mat_j++ = tcol - (!shift); 162099141d43SSatish Balay *mat_a++ = a->a[k]; 162199141d43SSatish Balay (*mat_ilen)++; 162299141d43SSatish Balay 162317ab2063SBarry Smith } 162417ab2063SBarry Smith } 162517ab2063SBarry Smith } 162602834360SBarry Smith /* Free work space */ 162702834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 1628606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 1629606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 163002834360SBarry Smith } 16316d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16326d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 163317ab2063SBarry Smith 163417ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 1635416022c9SBarry Smith *B = C; 16363a40ed3dSBarry Smith PetscFunctionReturn(0); 163717ab2063SBarry Smith } 163817ab2063SBarry Smith 1639a871dcd8SBarry Smith /* 1640a871dcd8SBarry Smith */ 16415615d1e5SSatish Balay #undef __FUNC__ 16425615d1e5SSatish Balay #define __FUNC__ "MatILUFactor_SeqAIJ" 16435ef9f2a5SBarry Smith int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatILUInfo *info) 1644a871dcd8SBarry Smith { 164563b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) inA->data; 164608480c60SBarry Smith int ierr; 164763b91edcSBarry Smith Mat outA; 1648b8a78c4aSBarry Smith PetscTruth row_identity, col_identity; 164963b91edcSBarry Smith 16503a40ed3dSBarry Smith PetscFunctionBegin; 1651b8a78c4aSBarry Smith if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,0,"Only levels=0 supported for in-place ilu"); 1652b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 1653b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 1654b8a78c4aSBarry Smith if (!row_identity || !col_identity) { 1655b8a78c4aSBarry Smith SETERRQ(1,1,"Row and column permutations must be identity for in-place ILU"); 1656b8a78c4aSBarry Smith } 1657a871dcd8SBarry Smith 165863b91edcSBarry Smith outA = inA; 165963b91edcSBarry Smith inA->factor = FACTOR_LU; 166063b91edcSBarry Smith a->row = row; 166163b91edcSBarry Smith a->col = col; 1662*c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1663*c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 166463b91edcSBarry Smith 1665f0ec6fceSSatish Balay /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */ 1666*c38d4ed2SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* if this came from a previous factored; need to remove old one */ 1667f0ec6fceSSatish Balay ierr = ISInvertPermutation(col,&(a->icol));CHKERRQ(ierr); 16681e4dd532SSatish Balay PLogObjectParent(inA,a->icol); 1669f0ec6fceSSatish Balay 167094a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 16710452661fSBarry Smith a->solve_work = (Scalar *) PetscMalloc( (a->m+1)*sizeof(Scalar));CHKPTRQ(a->solve_work); 167294a9d846SBarry Smith } 167363b91edcSBarry Smith 167408480c60SBarry Smith if (!a->diag) { 167508480c60SBarry Smith ierr = MatMarkDiag_SeqAIJ(inA);CHKERRQ(ierr); 167663b91edcSBarry Smith } 167763b91edcSBarry Smith ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA);CHKERRQ(ierr); 16783a40ed3dSBarry Smith PetscFunctionReturn(0); 1679a871dcd8SBarry Smith } 1680a871dcd8SBarry Smith 168174cdf0dfSBarry Smith #include "pinclude/blaslapack.h" 16825615d1e5SSatish Balay #undef __FUNC__ 16835615d1e5SSatish Balay #define __FUNC__ "MatScale_SeqAIJ" 16848f6be9afSLois Curfman McInnes int MatScale_SeqAIJ(Scalar *alpha,Mat inA) 1685f0b747eeSBarry Smith { 1686f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) inA->data; 1687f0b747eeSBarry Smith int one = 1; 16883a40ed3dSBarry Smith 16893a40ed3dSBarry Smith PetscFunctionBegin; 1690f0b747eeSBarry Smith BLscal_( &a->nz, alpha, a->a, &one ); 1691f0b747eeSBarry Smith PLogFlops(a->nz); 16923a40ed3dSBarry Smith PetscFunctionReturn(0); 1693f0b747eeSBarry Smith } 1694f0b747eeSBarry Smith 16955615d1e5SSatish Balay #undef __FUNC__ 16965615d1e5SSatish Balay #define __FUNC__ "MatGetSubMatrices_SeqAIJ" 16977b2a1423SBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n, IS *irow,IS *icol,MatReuse scall,Mat **B) 1698cddf8d76SBarry Smith { 1699cddf8d76SBarry Smith int ierr,i; 1700cddf8d76SBarry Smith 17013a40ed3dSBarry Smith PetscFunctionBegin; 1702cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 17030452661fSBarry Smith *B = (Mat *) PetscMalloc( (n+1)*sizeof(Mat) );CHKPTRQ(*B); 1704cddf8d76SBarry Smith } 1705cddf8d76SBarry Smith 1706cddf8d76SBarry Smith for ( i=0; i<n; i++ ) { 17076a6a5d1dSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 1708cddf8d76SBarry Smith } 17093a40ed3dSBarry Smith PetscFunctionReturn(0); 1710cddf8d76SBarry Smith } 1711cddf8d76SBarry Smith 17125615d1e5SSatish Balay #undef __FUNC__ 17135615d1e5SSatish Balay #define __FUNC__ "MatGetBlockSize_SeqAIJ" 17148f6be9afSLois Curfman McInnes int MatGetBlockSize_SeqAIJ(Mat A, int *bs) 17155a838052SSatish Balay { 1716f830108cSBarry Smith PetscFunctionBegin; 17175a838052SSatish Balay *bs = 1; 17183a40ed3dSBarry Smith PetscFunctionReturn(0); 17195a838052SSatish Balay } 17205a838052SSatish Balay 17215615d1e5SSatish Balay #undef __FUNC__ 17225615d1e5SSatish Balay #define __FUNC__ "MatIncreaseOverlap_SeqAIJ" 17238f6be9afSLois Curfman McInnes int MatIncreaseOverlap_SeqAIJ(Mat A, int is_max, IS *is, int ov) 17244dcbc457SBarry Smith { 1725e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 172606763907SSatish Balay int shift, row, i,j,k,l,m,n, *idx,ierr, *nidx, isz, val; 17278a047759SSatish Balay int start, end, *ai, *aj; 1728f1af5d2fSBarry Smith PetscBT table; 1729bbd702dbSSatish Balay 17303a40ed3dSBarry Smith PetscFunctionBegin; 17318a047759SSatish Balay shift = a->indexshift; 1732e4d965acSSatish Balay m = a->m; 1733e4d965acSSatish Balay ai = a->i; 17348a047759SSatish Balay aj = a->j+shift; 17358a047759SSatish Balay 1736a8c6a408SBarry Smith if (ov < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"illegal overlap value used"); 173706763907SSatish Balay 173806763907SSatish Balay nidx = (int *) PetscMalloc((m+1)*sizeof(int));CHKPTRQ(nidx); 17396831982aSBarry Smith ierr = PetscBTCreate(m,table);CHKERRQ(ierr); 174006763907SSatish Balay 1741e4d965acSSatish Balay for ( i=0; i<is_max; i++ ) { 1742b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 1743e4d965acSSatish Balay isz = 0; 17446831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 1745e4d965acSSatish Balay 1746e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 17474dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 174877c4ece6SBarry Smith ierr = ISGetSize(is[i],&n);CHKERRQ(ierr); 1749e4d965acSSatish Balay 1750dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 1751e4d965acSSatish Balay for ( j=0; j<n ; ++j){ 1752f1af5d2fSBarry Smith if(!PetscBTLookupSet(table, idx[j])) { nidx[isz++] = idx[j];} 17534dcbc457SBarry Smith } 175406763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 175506763907SSatish Balay ierr = ISDestroy(is[i]);CHKERRQ(ierr); 1756e4d965acSSatish Balay 175704a348a9SBarry Smith k = 0; 175804a348a9SBarry Smith for ( j=0; j<ov; j++){ /* for each overlap */ 175904a348a9SBarry Smith n = isz; 176006763907SSatish Balay for ( ; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */ 1761e4d965acSSatish Balay row = nidx[k]; 1762e4d965acSSatish Balay start = ai[row]; 1763e4d965acSSatish Balay end = ai[row+1]; 176404a348a9SBarry Smith for ( l = start; l<end ; l++){ 17658a047759SSatish Balay val = aj[l] + shift; 1766f1af5d2fSBarry Smith if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;} 1767e4d965acSSatish Balay } 1768e4d965acSSatish Balay } 1769e4d965acSSatish Balay } 1770029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF, isz, nidx, (is+i));CHKERRQ(ierr); 1771e4d965acSSatish Balay } 17726831982aSBarry Smith ierr = PetscBTDestroy(table);CHKERRQ(ierr); 1773606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 17743a40ed3dSBarry Smith PetscFunctionReturn(0); 17754dcbc457SBarry Smith } 177617ab2063SBarry Smith 17770513a670SBarry Smith /* -------------------------------------------------------------- */ 17780513a670SBarry Smith #undef __FUNC__ 17790513a670SBarry Smith #define __FUNC__ "MatPermute_SeqAIJ" 17800513a670SBarry Smith int MatPermute_SeqAIJ(Mat A, IS rowp, IS colp, Mat *B) 17810513a670SBarry Smith { 17820513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 17830513a670SBarry Smith Scalar *vwork; 17840513a670SBarry Smith int i, ierr, nz, m = a->m, n = a->n, *cwork; 17850513a670SBarry Smith int *row,*col,*cnew,j,*lens; 178656cd22aeSBarry Smith IS icolp,irowp; 17870513a670SBarry Smith 17883a40ed3dSBarry Smith PetscFunctionBegin; 178956cd22aeSBarry Smith ierr = ISInvertPermutation(rowp,&irowp);CHKERRQ(ierr); 179056cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 179156cd22aeSBarry Smith ierr = ISInvertPermutation(colp,&icolp);CHKERRQ(ierr); 179256cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 17930513a670SBarry Smith 17940513a670SBarry Smith /* determine lengths of permuted rows */ 17950513a670SBarry Smith lens = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(lens); 17960513a670SBarry Smith for (i=0; i<m; i++ ) { 17970513a670SBarry Smith lens[row[i]] = a->i[i+1] - a->i[i]; 17980513a670SBarry Smith } 17990513a670SBarry Smith ierr = MatCreateSeqAIJ(A->comm,m,n,0,lens,B);CHKERRQ(ierr); 1800606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 18010513a670SBarry Smith 18020513a670SBarry Smith cnew = (int *) PetscMalloc( n*sizeof(int) );CHKPTRQ(cnew); 18030513a670SBarry Smith for (i=0; i<m; i++) { 18040513a670SBarry Smith ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 18050513a670SBarry Smith for (j=0; j<nz; j++ ) { cnew[j] = col[cwork[j]];} 18060513a670SBarry Smith ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 18070513a670SBarry Smith ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 18080513a670SBarry Smith } 1809606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 18100513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18110513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 181256cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 181356cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 181456cd22aeSBarry Smith ierr = ISDestroy(irowp);CHKERRQ(ierr); 181556cd22aeSBarry Smith ierr = ISDestroy(icolp);CHKERRQ(ierr); 18163a40ed3dSBarry Smith PetscFunctionReturn(0); 18170513a670SBarry Smith } 18180513a670SBarry Smith 18195615d1e5SSatish Balay #undef __FUNC__ 18205615d1e5SSatish Balay #define __FUNC__ "MatPrintHelp_SeqAIJ" 1821682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A) 1822682d7d0cSBarry Smith { 1823*c38d4ed2SBarry Smith static PetscTruth called = PETSC_FALSE; 1824682d7d0cSBarry Smith MPI_Comm comm = A->comm; 1825d132466eSBarry Smith int ierr; 1826682d7d0cSBarry Smith 18273a40ed3dSBarry Smith PetscFunctionBegin; 1828*c38d4ed2SBarry Smith if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE; 1829d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr); 1830d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr); 1831d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr); 1832d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_no_inode: Do not use inodes\n");CHKERRQ(ierr); 1833d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");CHKERRQ(ierr); 1834aa482453SBarry Smith #if defined(PETSC_HAVE_ESSL) 1835d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_essl: Use IBM sparse LU factorization and solve.\n");CHKERRQ(ierr); 1836682d7d0cSBarry Smith #endif 18373a40ed3dSBarry Smith PetscFunctionReturn(0); 1838682d7d0cSBarry Smith } 18398f6be9afSLois Curfman McInnes extern int MatEqual_SeqAIJ(Mat A,Mat B, PetscTruth* flg); 1840a93ec695SBarry Smith extern int MatFDColoringCreate_SeqAIJ(Mat,ISColoring,MatFDColoring); 1841a93ec695SBarry Smith extern int MatColoringPatch_SeqAIJ(Mat,int,int *,ISColoring *); 1842a93ec695SBarry Smith 1843cb5b572fSBarry Smith #undef __FUNC__ 1844cb5b572fSBarry Smith #define __FUNC__ "MatCopy_SeqAIJ" 1845cb5b572fSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 1846cb5b572fSBarry Smith { 1847be6bf707SBarry Smith int ierr; 1848cb5b572fSBarry Smith 1849cb5b572fSBarry Smith PetscFunctionBegin; 1850be6bf707SBarry Smith if (str == SAME_NONZERO_PATTERN && B->type == MATSEQAIJ) { 1851be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1852be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ *) B->data; 1853be6bf707SBarry Smith 1854be6bf707SBarry Smith if (a->i[a->m]+a->indexshift != b->i[b->m]+a->indexshift) { 1855be6bf707SBarry Smith SETERRQ(1,1,"Number of nonzeros in two matrices are different"); 1856cb5b572fSBarry Smith } 1857549d3d68SSatish Balay ierr = PetscMemcpy(b->a,a->a,(a->i[a->m]+a->indexshift)*sizeof(Scalar));CHKERRQ(ierr); 1858cb5b572fSBarry Smith } else { 1859cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1860cb5b572fSBarry Smith } 1861cb5b572fSBarry Smith PetscFunctionReturn(0); 1862cb5b572fSBarry Smith } 1863cb5b572fSBarry Smith 1864682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 18650a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ, 1866cb5b572fSBarry Smith MatGetRow_SeqAIJ, 1867cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 1868cb5b572fSBarry Smith MatMult_SeqAIJ, 1869cb5b572fSBarry Smith MatMultAdd_SeqAIJ, 1870cb5b572fSBarry Smith MatMultTrans_SeqAIJ, 1871cb5b572fSBarry Smith MatMultTransAdd_SeqAIJ, 1872cb5b572fSBarry Smith MatSolve_SeqAIJ, 1873cb5b572fSBarry Smith MatSolveAdd_SeqAIJ, 1874cb5b572fSBarry Smith MatSolveTrans_SeqAIJ, 1875cb5b572fSBarry Smith MatSolveTransAdd_SeqAIJ, 1876cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 1877cb5b572fSBarry Smith 0, 187817ab2063SBarry Smith MatRelax_SeqAIJ, 187917ab2063SBarry Smith MatTranspose_SeqAIJ, 1880cb5b572fSBarry Smith MatGetInfo_SeqAIJ, 1881cb5b572fSBarry Smith MatEqual_SeqAIJ, 1882cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 1883cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 1884cb5b572fSBarry Smith MatNorm_SeqAIJ, 1885cb5b572fSBarry Smith 0, 1886cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 188717ab2063SBarry Smith MatCompress_SeqAIJ, 1888cb5b572fSBarry Smith MatSetOption_SeqAIJ, 1889cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 1890cb5b572fSBarry Smith MatZeroRows_SeqAIJ, 1891cb5b572fSBarry Smith MatLUFactorSymbolic_SeqAIJ, 1892cb5b572fSBarry Smith MatLUFactorNumeric_SeqAIJ, 1893cb5b572fSBarry Smith 0, 1894cb5b572fSBarry Smith 0, 1895cb5b572fSBarry Smith MatGetSize_SeqAIJ, 1896cb5b572fSBarry Smith MatGetSize_SeqAIJ, 1897cb5b572fSBarry Smith MatGetOwnershipRange_SeqAIJ, 1898cb5b572fSBarry Smith MatILUFactorSymbolic_SeqAIJ, 1899cb5b572fSBarry Smith 0, 1900cb5b572fSBarry Smith 0, 1901cb5b572fSBarry Smith 0, 1902be6bf707SBarry Smith MatDuplicate_SeqAIJ, 1903cb5b572fSBarry Smith 0, 1904cb5b572fSBarry Smith 0, 1905cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 1906cb5b572fSBarry Smith 0, 1907cb5b572fSBarry Smith 0, 1908cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 1909cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 1910cb5b572fSBarry Smith MatGetValues_SeqAIJ, 1911cb5b572fSBarry Smith MatCopy_SeqAIJ, 1912f0b747eeSBarry Smith MatPrintHelp_SeqAIJ, 1913cb5b572fSBarry Smith MatScale_SeqAIJ, 1914cb5b572fSBarry Smith 0, 1915cb5b572fSBarry Smith 0, 19166945ee14SBarry Smith MatILUDTFactor_SeqAIJ, 19176945ee14SBarry Smith MatGetBlockSize_SeqAIJ, 19183b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 19193b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 19203b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 1921a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 1922a93ec695SBarry Smith MatFDColoringCreate_SeqAIJ, 19230513a670SBarry Smith MatColoringPatch_SeqAIJ, 19240513a670SBarry Smith 0, 1925cda55fadSBarry Smith MatPermute_SeqAIJ, 1926cda55fadSBarry Smith 0, 1927cda55fadSBarry Smith 0, 1928cda55fadSBarry Smith 0, 1929cda55fadSBarry Smith 0, 1930cda55fadSBarry Smith MatGetMaps_Petsc}; 193117ab2063SBarry Smith 193217ab2063SBarry Smith extern int MatUseSuperLU_SeqAIJ(Mat); 193317ab2063SBarry Smith extern int MatUseEssl_SeqAIJ(Mat); 193417ab2063SBarry Smith extern int MatUseDXML_SeqAIJ(Mat); 193517ab2063SBarry Smith 1936fb2e594dSBarry Smith EXTERN_C_BEGIN 19375615d1e5SSatish Balay #undef __FUNC__ 1938bef8e0ddSBarry Smith #define __FUNC__ "MatSeqAIJSetColumnIndices_SeqAIJ" 193915091d37SBarry Smith 1940bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices) 1941bef8e0ddSBarry Smith { 1942bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 1943bef8e0ddSBarry Smith int i,nz,n; 1944bef8e0ddSBarry Smith 1945bef8e0ddSBarry Smith PetscFunctionBegin; 1946bef8e0ddSBarry Smith if (aij->indexshift) SETERRQ(1,1,"No support with 1 based indexing"); 1947bef8e0ddSBarry Smith 1948bef8e0ddSBarry Smith nz = aij->maxnz; 1949bef8e0ddSBarry Smith n = aij->n; 1950bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 1951bef8e0ddSBarry Smith aij->j[i] = indices[i]; 1952bef8e0ddSBarry Smith } 1953bef8e0ddSBarry Smith aij->nz = nz; 1954bef8e0ddSBarry Smith for ( i=0; i<n; i++ ) { 1955bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 1956bef8e0ddSBarry Smith } 1957bef8e0ddSBarry Smith 1958bef8e0ddSBarry Smith PetscFunctionReturn(0); 1959bef8e0ddSBarry Smith } 1960fb2e594dSBarry Smith EXTERN_C_END 1961bef8e0ddSBarry Smith 1962bef8e0ddSBarry Smith #undef __FUNC__ 1963bef8e0ddSBarry Smith #define __FUNC__ "MatSeqAIJSetColumnIndices" 1964bef8e0ddSBarry Smith /*@ 1965bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 1966bef8e0ddSBarry Smith in the matrix. 1967bef8e0ddSBarry Smith 1968bef8e0ddSBarry Smith Input Parameters: 1969bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 1970bef8e0ddSBarry Smith - indices - the column indices 1971bef8e0ddSBarry Smith 197215091d37SBarry Smith Level: advanced 197315091d37SBarry Smith 1974bef8e0ddSBarry Smith Notes: 1975bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 1976bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 1977bef8e0ddSBarry Smith of the MatSetValues() operation. 1978bef8e0ddSBarry Smith 1979bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 1980bef8e0ddSBarry Smith MatCreateSeqAIJ(). 1981bef8e0ddSBarry Smith 1982bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 1983bef8e0ddSBarry Smith 1984bef8e0ddSBarry Smith @*/ 1985bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices) 1986bef8e0ddSBarry Smith { 1987bef8e0ddSBarry Smith int ierr,(*f)(Mat,int *); 1988bef8e0ddSBarry Smith 1989bef8e0ddSBarry Smith PetscFunctionBegin; 1990bef8e0ddSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 1991549d3d68SSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void **)&f);CHKERRQ(ierr); 1992bef8e0ddSBarry Smith if (f) { 1993bef8e0ddSBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 1994bef8e0ddSBarry Smith } else { 1995bef8e0ddSBarry Smith SETERRQ(1,1,"Wrong type of matrix to set column indices"); 1996bef8e0ddSBarry Smith } 1997bef8e0ddSBarry Smith PetscFunctionReturn(0); 1998bef8e0ddSBarry Smith } 1999bef8e0ddSBarry Smith 2000be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 2001be6bf707SBarry Smith 2002fb2e594dSBarry Smith EXTERN_C_BEGIN 2003be6bf707SBarry Smith #undef __FUNC__ 2004be6bf707SBarry Smith #define __FUNC__ "MatStoreValues_SeqAIJ" 2005be6bf707SBarry Smith int MatStoreValues_SeqAIJ(Mat mat) 2006be6bf707SBarry Smith { 2007be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2008549d3d68SSatish Balay int nz = aij->i[aij->m]+aij->indexshift,ierr; 2009be6bf707SBarry Smith 2010be6bf707SBarry Smith PetscFunctionBegin; 2011be6bf707SBarry Smith if (aij->nonew != 1) { 2012be6bf707SBarry Smith SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2013be6bf707SBarry Smith } 2014be6bf707SBarry Smith 2015be6bf707SBarry Smith /* allocate space for values if not already there */ 2016be6bf707SBarry Smith if (!aij->saved_values) { 2017be6bf707SBarry Smith aij->saved_values = (Scalar *) PetscMalloc(nz*sizeof(Scalar));CHKPTRQ(aij->saved_values); 2018be6bf707SBarry Smith } 2019be6bf707SBarry Smith 2020be6bf707SBarry Smith /* copy values over */ 2021549d3d68SSatish Balay ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr); 2022be6bf707SBarry Smith PetscFunctionReturn(0); 2023be6bf707SBarry Smith } 2024fb2e594dSBarry Smith EXTERN_C_END 2025be6bf707SBarry Smith 2026be6bf707SBarry Smith #undef __FUNC__ 2027be6bf707SBarry Smith #define __FUNC__ "MatStoreValues" 2028be6bf707SBarry Smith /*@ 2029be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 2030be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2031be6bf707SBarry Smith nonlinear portion. 2032be6bf707SBarry Smith 2033be6bf707SBarry Smith Collect on Mat 2034be6bf707SBarry Smith 2035be6bf707SBarry Smith Input Parameters: 2036be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2037be6bf707SBarry Smith 203815091d37SBarry Smith Level: advanced 203915091d37SBarry Smith 2040be6bf707SBarry Smith Common Usage, with SNESSolve(): 2041be6bf707SBarry Smith $ Create Jacobian matrix 2042be6bf707SBarry Smith $ Set linear terms into matrix 2043be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 2044be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 2045be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 2046be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2047be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2048be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 2049be6bf707SBarry Smith $ In your Jacobian routine 2050be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2051be6bf707SBarry Smith $ Set nonlinear terms in matrix 2052be6bf707SBarry Smith 2053be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 2054be6bf707SBarry Smith $ // build linear portion of Jacobian 2055be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2056be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2057be6bf707SBarry Smith $ loop over nonlinear iterations 2058be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2059be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 2060be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 2061be6bf707SBarry Smith $ Solve linear system with Jacobian 2062be6bf707SBarry Smith $ endloop 2063be6bf707SBarry Smith 2064be6bf707SBarry Smith Notes: 2065be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 2066be6bf707SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before 2067be6bf707SBarry Smith calling this routine. 2068be6bf707SBarry Smith 2069be6bf707SBarry Smith .seealso: MatRetrieveValues() 2070be6bf707SBarry Smith 2071be6bf707SBarry Smith @*/ 2072be6bf707SBarry Smith int MatStoreValues(Mat mat) 2073be6bf707SBarry Smith { 2074be6bf707SBarry Smith int ierr,(*f)(Mat); 2075be6bf707SBarry Smith 2076be6bf707SBarry Smith PetscFunctionBegin; 2077be6bf707SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 2078be6bf707SBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix"); 2079be6bf707SBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix"); 2080be6bf707SBarry Smith 2081c5d6004cSBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void **)&f);CHKERRQ(ierr); 2082be6bf707SBarry Smith if (f) { 2083be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2084be6bf707SBarry Smith } else { 2085be6bf707SBarry Smith SETERRQ(1,1,"Wrong type of matrix to store values"); 2086be6bf707SBarry Smith } 2087be6bf707SBarry Smith PetscFunctionReturn(0); 2088be6bf707SBarry Smith } 2089be6bf707SBarry Smith 2090fb2e594dSBarry Smith EXTERN_C_BEGIN 2091be6bf707SBarry Smith #undef __FUNC__ 2092be6bf707SBarry Smith #define __FUNC__ "MatRetrieveValues_SeqAIJ" 2093be6bf707SBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat) 2094be6bf707SBarry Smith { 2095be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2096549d3d68SSatish Balay int nz = aij->i[aij->m]+aij->indexshift,ierr; 2097be6bf707SBarry Smith 2098be6bf707SBarry Smith PetscFunctionBegin; 2099be6bf707SBarry Smith if (aij->nonew != 1) { 2100be6bf707SBarry Smith SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2101be6bf707SBarry Smith } 2102be6bf707SBarry Smith if (!aij->saved_values) { 2103be6bf707SBarry Smith SETERRQ(1,1,"Must call MatStoreValues(A);first"); 2104be6bf707SBarry Smith } 2105be6bf707SBarry Smith 2106be6bf707SBarry Smith /* copy values over */ 2107549d3d68SSatish Balay ierr = PetscMemcpy(aij->a, aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr); 2108be6bf707SBarry Smith PetscFunctionReturn(0); 2109be6bf707SBarry Smith } 2110fb2e594dSBarry Smith EXTERN_C_END 2111be6bf707SBarry Smith 2112be6bf707SBarry Smith #undef __FUNC__ 2113be6bf707SBarry Smith #define __FUNC__ "MatRetrieveValues" 2114be6bf707SBarry Smith /*@ 2115be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 2116be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2117be6bf707SBarry Smith nonlinear portion. 2118be6bf707SBarry Smith 2119be6bf707SBarry Smith Collect on Mat 2120be6bf707SBarry Smith 2121be6bf707SBarry Smith Input Parameters: 2122be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2123be6bf707SBarry Smith 212415091d37SBarry Smith Level: advanced 212515091d37SBarry Smith 2126be6bf707SBarry Smith .seealso: MatStoreValues() 2127be6bf707SBarry Smith 2128be6bf707SBarry Smith @*/ 2129be6bf707SBarry Smith int MatRetrieveValues(Mat mat) 2130be6bf707SBarry Smith { 2131be6bf707SBarry Smith int ierr,(*f)(Mat); 2132be6bf707SBarry Smith 2133be6bf707SBarry Smith PetscFunctionBegin; 2134be6bf707SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 2135be6bf707SBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix"); 2136be6bf707SBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix"); 2137be6bf707SBarry Smith 2138c5d6004cSBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void **)&f);CHKERRQ(ierr); 2139be6bf707SBarry Smith if (f) { 2140be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2141be6bf707SBarry Smith } else { 2142be6bf707SBarry Smith SETERRQ(1,1,"Wrong type of matrix to retrieve values"); 2143be6bf707SBarry Smith } 2144be6bf707SBarry Smith PetscFunctionReturn(0); 2145be6bf707SBarry Smith } 2146be6bf707SBarry Smith 2147be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 2148cb5b572fSBarry Smith 2149bef8e0ddSBarry Smith #undef __FUNC__ 21505615d1e5SSatish Balay #define __FUNC__ "MatCreateSeqAIJ" 215117ab2063SBarry Smith /*@C 2152682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 21530d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 21546e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 215551c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 21562bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 215717ab2063SBarry Smith 2158db81eaa0SLois Curfman McInnes Collective on MPI_Comm 2159db81eaa0SLois Curfman McInnes 216017ab2063SBarry Smith Input Parameters: 2161db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 216217ab2063SBarry Smith . m - number of rows 216317ab2063SBarry Smith . n - number of columns 216417ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 216551c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 21662bd5e0b2SLois Curfman McInnes (possibly different for each row) or PETSC_NULL 216717ab2063SBarry Smith 216817ab2063SBarry Smith Output Parameter: 2169416022c9SBarry Smith . A - the matrix 217017ab2063SBarry Smith 2171b259b22eSLois Curfman McInnes Notes: 217217ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 217317ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 21740002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 217544cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 217617ab2063SBarry Smith 217717ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2178a40aa06bSLois Curfman McInnes Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 21793d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 21806da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 218117ab2063SBarry Smith 2182682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 21834fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 2184682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 21856c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 21866c7ebb05SLois Curfman McInnes 21876c7ebb05SLois Curfman McInnes Options Database Keys: 2188db81eaa0SLois Curfman McInnes + -mat_aij_no_inode - Do not use inodes 2189db81eaa0SLois Curfman McInnes . -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5) 2190db81eaa0SLois Curfman McInnes - -mat_aij_oneindex - Internally use indexing starting at 1 2191db81eaa0SLois Curfman McInnes rather than 0. Note that when calling MatSetValues(), 2192db81eaa0SLois Curfman McInnes the user still MUST index entries starting at 0! 219317ab2063SBarry Smith 2194027ccd11SLois Curfman McInnes Level: intermediate 2195027ccd11SLois Curfman McInnes 2196bef8e0ddSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices() 219717ab2063SBarry Smith @*/ 2198416022c9SBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,int *nnz, Mat *A) 219917ab2063SBarry Smith { 2200416022c9SBarry Smith Mat B; 2201416022c9SBarry Smith Mat_SeqAIJ *b; 2202f1af5d2fSBarry Smith int i, len, ierr, size; 2203f1af5d2fSBarry Smith PetscTruth flg; 22046945ee14SBarry Smith 22053a40ed3dSBarry Smith PetscFunctionBegin; 2206d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 2207a8c6a408SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Comm must be of size 1"); 2208d5d45c9bSBarry Smith 2209b73539f3SBarry Smith if (nz < -2) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"nz cannot be less than -2: value %d",nz); 2210b73539f3SBarry Smith if (nnz) { 2211b73539f3SBarry Smith for (i=0; i<m; i++) { 2212b73539f3SBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 2213b73539f3SBarry Smith } 2214b73539f3SBarry Smith } 2215b73539f3SBarry Smith 2216416022c9SBarry Smith *A = 0; 22173f1db9ecSBarry Smith PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,"Mat",comm,MatDestroy,MatView); 2218416022c9SBarry Smith PLogObjectCreate(B); 22190452661fSBarry Smith B->data = (void *) (b = PetscNew(Mat_SeqAIJ));CHKPTRQ(b); 2220549d3d68SSatish Balay ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr); 2221549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 2222e1311b90SBarry Smith B->ops->destroy = MatDestroy_SeqAIJ; 2223e1311b90SBarry Smith B->ops->view = MatView_SeqAIJ; 2224416022c9SBarry Smith B->factor = 0; 2225416022c9SBarry Smith B->lupivotthreshold = 1.0; 222690f02eecSBarry Smith B->mapping = 0; 2227f1af5d2fSBarry Smith ierr = OptionsGetDouble(PETSC_NULL,"-mat_lu_pivotthreshold",&B->lupivotthreshold,PETSC_NULL);CHKERRQ(ierr); 2228f1af5d2fSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-pc_ilu_preserve_row_sums",&b->ilu_preserve_row_sums);CHKERRQ(ierr); 2229416022c9SBarry Smith b->row = 0; 2230416022c9SBarry Smith b->col = 0; 223182bf6240SBarry Smith b->icol = 0; 2232416022c9SBarry Smith b->indexshift = 0; 2233b810aeb4SBarry Smith b->reallocs = 0; 223469957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_oneindex", &flg);CHKERRQ(ierr); 223569957df2SSatish Balay if (flg) b->indexshift = -1; 223617ab2063SBarry Smith 223744cd7ae7SLois Curfman McInnes b->m = m; B->m = m; B->M = m; 223844cd7ae7SLois Curfman McInnes b->n = n; B->n = n; B->N = n; 2239a5ae1ecdSBarry Smith 22404d197716SBarry Smith ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr); 22414d197716SBarry Smith ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr); 2242a5ae1ecdSBarry Smith 22430452661fSBarry Smith b->imax = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(b->imax); 2244b4fd4287SBarry Smith if (nnz == PETSC_NULL) { 22457b8455f0SLois Curfman McInnes if (nz == PETSC_DEFAULT) nz = 10; 22467b8455f0SLois Curfman McInnes else if (nz <= 0) nz = 1; 2247416022c9SBarry Smith for ( i=0; i<m; i++ ) b->imax[i] = nz; 224817ab2063SBarry Smith nz = nz*m; 22493a40ed3dSBarry Smith } else { 225017ab2063SBarry Smith nz = 0; 2251416022c9SBarry Smith for ( i=0; i<m; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];} 225217ab2063SBarry Smith } 225317ab2063SBarry Smith 225417ab2063SBarry Smith /* allocate the matrix space */ 2255416022c9SBarry Smith len = nz*(sizeof(int) + sizeof(Scalar)) + (b->m+1)*sizeof(int); 22560452661fSBarry Smith b->a = (Scalar *) PetscMalloc( len );CHKPTRQ(b->a); 2257416022c9SBarry Smith b->j = (int *) (b->a + nz); 2258549d3d68SSatish Balay ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr); 2259416022c9SBarry Smith b->i = b->j + nz; 2260416022c9SBarry Smith b->singlemalloc = 1; 226117ab2063SBarry Smith 2262416022c9SBarry Smith b->i[0] = -b->indexshift; 226317ab2063SBarry Smith for (i=1; i<m+1; i++) { 2264416022c9SBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 226517ab2063SBarry Smith } 226617ab2063SBarry Smith 2267416022c9SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 22680452661fSBarry Smith b->ilen = (int *) PetscMalloc((m+1)*sizeof(int)); 2269f09e8eb9SSatish Balay PLogObjectMemory(B,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2270416022c9SBarry Smith for ( i=0; i<b->m; i++ ) { b->ilen[i] = 0;} 227117ab2063SBarry Smith 2272416022c9SBarry Smith b->nz = 0; 2273416022c9SBarry Smith b->maxnz = nz; 2274416022c9SBarry Smith b->sorted = 0; 2275416022c9SBarry Smith b->roworiented = 1; 2276416022c9SBarry Smith b->nonew = 0; 2277416022c9SBarry Smith b->diag = 0; 2278416022c9SBarry Smith b->solve_work = 0; 227971bd300dSLois Curfman McInnes b->spptr = 0; 2280754ec7b1SSatish Balay b->inode.node_count = 0; 2281754ec7b1SSatish Balay b->inode.size = 0; 22826c7ebb05SLois Curfman McInnes b->inode.limit = 5; 22836c7ebb05SLois Curfman McInnes b->inode.max_limit = 5; 2284be6bf707SBarry Smith b->saved_values = 0; 22854e220ebcSLois Curfman McInnes B->info.nz_unneeded = (double)b->maxnz; 2286d7f994e1SBarry Smith b->idiag = 0; 2287d7f994e1SBarry Smith b->ssor = 0; 228817ab2063SBarry Smith 2289416022c9SBarry Smith *A = B; 22904e220ebcSLois Curfman McInnes 22914b14c69eSBarry Smith /* SuperLU is not currently supported through PETSc */ 2292aa482453SBarry Smith #if defined(PETSC_HAVE_SUPERLU) 229369957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_superlu", &flg);CHKERRQ(ierr); 229469957df2SSatish Balay if (flg) { ierr = MatUseSuperLU_SeqAIJ(B);CHKERRQ(ierr); } 22954b14c69eSBarry Smith #endif 229669957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_essl", &flg);CHKERRQ(ierr); 229769957df2SSatish Balay if (flg) { ierr = MatUseEssl_SeqAIJ(B);CHKERRQ(ierr); } 229869957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_dxml", &flg);CHKERRQ(ierr); 229969957df2SSatish Balay if (flg) { 2300a8c6a408SBarry Smith if (!b->indexshift) SETERRQ( PETSC_ERR_LIB,0,"need -mat_aij_oneindex with -mat_aij_dxml"); 2301416022c9SBarry Smith ierr = MatUseDXML_SeqAIJ(B);CHKERRQ(ierr); 230217ab2063SBarry Smith } 230369957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-help", &flg);CHKERRQ(ierr); 230469957df2SSatish Balay if (flg) {ierr = MatPrintHelp(B);CHKERRQ(ierr); } 2305bef8e0ddSBarry Smith 2306f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C", 2307bef8e0ddSBarry Smith "MatSeqAIJSetColumnIndices_SeqAIJ", 2308bef8e0ddSBarry Smith (void*)MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 2309f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 2310be6bf707SBarry Smith "MatStoreValues_SeqAIJ", 2311be6bf707SBarry Smith (void*)MatStoreValues_SeqAIJ);CHKERRQ(ierr); 2312f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 2313be6bf707SBarry Smith "MatRetrieveValues_SeqAIJ", 2314be6bf707SBarry Smith (void*)MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 23153a40ed3dSBarry Smith PetscFunctionReturn(0); 231617ab2063SBarry Smith } 231717ab2063SBarry Smith 23185615d1e5SSatish Balay #undef __FUNC__ 2319be6bf707SBarry Smith #define __FUNC__ "MatDuplicate_SeqAIJ" 2320be6bf707SBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 232117ab2063SBarry Smith { 2322416022c9SBarry Smith Mat C; 2323416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ *) A->data; 2324bef8e0ddSBarry Smith int i,len, m = a->m,shift = a->indexshift,ierr; 232517ab2063SBarry Smith 23263a40ed3dSBarry Smith PetscFunctionBegin; 23274043dd9cSLois Curfman McInnes *B = 0; 23283f1db9ecSBarry Smith PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,"Mat",A->comm,MatDestroy,MatView); 2329416022c9SBarry Smith PLogObjectCreate(C); 23300452661fSBarry Smith C->data = (void *) (c = PetscNew(Mat_SeqAIJ));CHKPTRQ(c); 2331549d3d68SSatish Balay ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 2332e1311b90SBarry Smith C->ops->destroy = MatDestroy_SeqAIJ; 2333e1311b90SBarry Smith C->ops->view = MatView_SeqAIJ; 2334416022c9SBarry Smith C->factor = A->factor; 2335416022c9SBarry Smith c->row = 0; 2336416022c9SBarry Smith c->col = 0; 233782bf6240SBarry Smith c->icol = 0; 2338416022c9SBarry Smith c->indexshift = shift; 2339c456f294SBarry Smith C->assembled = PETSC_TRUE; 234017ab2063SBarry Smith 234144cd7ae7SLois Curfman McInnes c->m = C->m = a->m; 234244cd7ae7SLois Curfman McInnes c->n = C->n = a->n; 234344cd7ae7SLois Curfman McInnes C->M = a->m; 234444cd7ae7SLois Curfman McInnes C->N = a->n; 234517ab2063SBarry Smith 23460452661fSBarry Smith c->imax = (int *) PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->imax); 23470452661fSBarry Smith c->ilen = (int *) PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->ilen); 234817ab2063SBarry Smith for ( i=0; i<m; i++ ) { 2349416022c9SBarry Smith c->imax[i] = a->imax[i]; 2350416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 235117ab2063SBarry Smith } 235217ab2063SBarry Smith 235317ab2063SBarry Smith /* allocate the matrix space */ 2354416022c9SBarry Smith c->singlemalloc = 1; 2355416022c9SBarry Smith len = (m+1)*sizeof(int)+(a->i[m])*(sizeof(Scalar)+sizeof(int)); 23560452661fSBarry Smith c->a = (Scalar *) PetscMalloc( len );CHKPTRQ(c->a); 2357416022c9SBarry Smith c->j = (int *) (c->a + a->i[m] + shift); 2358416022c9SBarry Smith c->i = c->j + a->i[m] + shift; 2359549d3d68SSatish Balay ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));CHKERRQ(ierr); 236017ab2063SBarry Smith if (m > 0) { 2361549d3d68SSatish Balay ierr = PetscMemcpy(c->j,a->j,(a->i[m]+shift)*sizeof(int));CHKERRQ(ierr); 2362be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 2363549d3d68SSatish Balay ierr = PetscMemcpy(c->a,a->a,(a->i[m]+shift)*sizeof(Scalar));CHKERRQ(ierr); 2364be6bf707SBarry Smith } else { 2365549d3d68SSatish Balay ierr = PetscMemzero(c->a,(a->i[m]+shift)*sizeof(Scalar));CHKERRQ(ierr); 236617ab2063SBarry Smith } 236708480c60SBarry Smith } 236817ab2063SBarry Smith 2369f09e8eb9SSatish Balay PLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2370416022c9SBarry Smith c->sorted = a->sorted; 2371416022c9SBarry Smith c->roworiented = a->roworiented; 2372416022c9SBarry Smith c->nonew = a->nonew; 23737a743949SBarry Smith c->ilu_preserve_row_sums = a->ilu_preserve_row_sums; 2374be6bf707SBarry Smith c->saved_values = 0; 2375d7f994e1SBarry Smith c->idiag = 0; 2376d7f994e1SBarry Smith c->ssor = 0; 237717ab2063SBarry Smith 2378416022c9SBarry Smith if (a->diag) { 23790452661fSBarry Smith c->diag = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(c->diag); 2380416022c9SBarry Smith PLogObjectMemory(C,(m+1)*sizeof(int)); 238117ab2063SBarry Smith for ( i=0; i<m; i++ ) { 2382416022c9SBarry Smith c->diag[i] = a->diag[i]; 238317ab2063SBarry Smith } 23843a40ed3dSBarry Smith } else c->diag = 0; 23856c7ebb05SLois Curfman McInnes c->inode.limit = a->inode.limit; 23866c7ebb05SLois Curfman McInnes c->inode.max_limit = a->inode.max_limit; 2387754ec7b1SSatish Balay if (a->inode.size){ 2388daed632aSSatish Balay c->inode.size = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(c->inode.size); 2389754ec7b1SSatish Balay c->inode.node_count = a->inode.node_count; 2390549d3d68SSatish Balay ierr = PetscMemcpy( c->inode.size, a->inode.size, (m+1)*sizeof(int));CHKERRQ(ierr); 2391754ec7b1SSatish Balay } else { 2392754ec7b1SSatish Balay c->inode.size = 0; 2393754ec7b1SSatish Balay c->inode.node_count = 0; 2394754ec7b1SSatish Balay } 2395416022c9SBarry Smith c->nz = a->nz; 2396416022c9SBarry Smith c->maxnz = a->maxnz; 2397416022c9SBarry Smith c->solve_work = 0; 239876dd722bSSatish Balay c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 2399754ec7b1SSatish Balay 2400416022c9SBarry Smith *B = C; 24017b2a1423SBarry Smith ierr = FListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 24023a40ed3dSBarry Smith PetscFunctionReturn(0); 240317ab2063SBarry Smith } 240417ab2063SBarry Smith 24055615d1e5SSatish Balay #undef __FUNC__ 24065615d1e5SSatish Balay #define __FUNC__ "MatLoad_SeqAIJ" 240719bcc07fSBarry Smith int MatLoad_SeqAIJ(Viewer viewer,MatType type,Mat *A) 240817ab2063SBarry Smith { 2409416022c9SBarry Smith Mat_SeqAIJ *a; 2410416022c9SBarry Smith Mat B; 241117699dbbSLois Curfman McInnes int i, nz, ierr, fd, header[4],size,*rowlengths = 0,M,N,shift; 2412bcd2baecSBarry Smith MPI_Comm comm; 241317ab2063SBarry Smith 24143a40ed3dSBarry Smith PetscFunctionBegin; 2415e864ced6SBarry Smith ierr = PetscObjectGetComm((PetscObject) viewer,&comm);CHKERRQ(ierr); 2416d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 2417a8c6a408SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,0,"view must have one processor"); 241890ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 24190752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 2420a8c6a408SBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not matrix object in file"); 242117ab2063SBarry Smith M = header[1]; N = header[2]; nz = header[3]; 242217ab2063SBarry Smith 2423d64ed03dSBarry Smith if (nz < 0) { 2424a8c6a408SBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format on disk, cannot load as SeqAIJ"); 2425d64ed03dSBarry Smith } 2426d64ed03dSBarry Smith 242717ab2063SBarry Smith /* read in row lengths */ 24280452661fSBarry Smith rowlengths = (int*) PetscMalloc( M*sizeof(int) );CHKPTRQ(rowlengths); 24290752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 243017ab2063SBarry Smith 243117ab2063SBarry Smith /* create our matrix */ 2432416022c9SBarry Smith ierr = MatCreateSeqAIJ(comm,M,N,0,rowlengths,A);CHKERRQ(ierr); 2433416022c9SBarry Smith B = *A; 2434416022c9SBarry Smith a = (Mat_SeqAIJ *) B->data; 2435416022c9SBarry Smith shift = a->indexshift; 243617ab2063SBarry Smith 243717ab2063SBarry Smith /* read in column indices and adjust for Fortran indexing*/ 24380752156aSBarry Smith ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 243917ab2063SBarry Smith if (shift) { 244017ab2063SBarry Smith for ( i=0; i<nz; i++ ) { 2441416022c9SBarry Smith a->j[i] += 1; 244217ab2063SBarry Smith } 244317ab2063SBarry Smith } 244417ab2063SBarry Smith 244517ab2063SBarry Smith /* read in nonzero values */ 24460752156aSBarry Smith ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 244717ab2063SBarry Smith 244817ab2063SBarry Smith /* set matrix "i" values */ 2449416022c9SBarry Smith a->i[0] = -shift; 245017ab2063SBarry Smith for ( i=1; i<= M; i++ ) { 2451416022c9SBarry Smith a->i[i] = a->i[i-1] + rowlengths[i-1]; 2452416022c9SBarry Smith a->ilen[i-1] = rowlengths[i-1]; 245317ab2063SBarry Smith } 2454606d414cSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 245517ab2063SBarry Smith 24566d4a8577SBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24576d4a8577SBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24583a40ed3dSBarry Smith PetscFunctionReturn(0); 245917ab2063SBarry Smith } 246017ab2063SBarry Smith 24615615d1e5SSatish Balay #undef __FUNC__ 24625615d1e5SSatish Balay #define __FUNC__ "MatEqual_SeqAIJ" 24638f6be9afSLois Curfman McInnes int MatEqual_SeqAIJ(Mat A,Mat B, PetscTruth* flg) 24647264ac53SSatish Balay { 24657264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data, *b = (Mat_SeqAIJ *)B->data; 24660f5bd95cSBarry Smith int ierr; 24677264ac53SSatish Balay 24683a40ed3dSBarry Smith PetscFunctionBegin; 2469a8c6a408SBarry Smith if (B->type !=MATSEQAIJ)SETERRQ(PETSC_ERR_ARG_INCOMP,0,"Matrices must be same type"); 24707264ac53SSatish Balay 24717264ac53SSatish Balay /* If the matrix dimensions are not equal, or no of nonzeros or shift */ 24727264ac53SSatish Balay if ((a->m != b->m ) || (a->n !=b->n) ||( a->nz != b->nz)|| 2473bcd2baecSBarry Smith (a->indexshift != b->indexshift)) { 24743a40ed3dSBarry Smith *flg = PETSC_FALSE; PetscFunctionReturn(0); 2475bcd2baecSBarry Smith } 24767264ac53SSatish Balay 24777264ac53SSatish Balay /* if the a->i are the same */ 24780f5bd95cSBarry Smith ierr = PetscMemcmp(a->i,b->i,(a->m+1)*sizeof(int),flg);CHKERRQ(ierr); 24790f5bd95cSBarry Smith if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 24807264ac53SSatish Balay 24817264ac53SSatish Balay /* if a->j are the same */ 24820f5bd95cSBarry Smith ierr = PetscMemcmp(a->j, b->j, (a->nz)*sizeof(int),flg);CHKERRQ(ierr); 24830f5bd95cSBarry Smith if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 2484bcd2baecSBarry Smith 2485bcd2baecSBarry Smith /* if a->a are the same */ 24860f5bd95cSBarry Smith ierr = PetscMemcmp(a->a, b->a, (a->nz)*sizeof(Scalar),flg);CHKERRQ(ierr); 24870f5bd95cSBarry Smith 24883a40ed3dSBarry Smith PetscFunctionReturn(0); 24897264ac53SSatish Balay 24907264ac53SSatish Balay } 2491