173f4d377SMatthew Knepley /*$Id: aij.c,v 1.385 2001/09/07 20:09:22 bsmith Exp $*/ 2d5d45c9bSBarry Smith /* 33369ce9aSBarry Smith Defines the basic matrix operations for the AIJ (compressed row) 4d5d45c9bSBarry Smith matrix storage format. 5d5d45c9bSBarry Smith */ 63369ce9aSBarry Smith 79e070d67SMatthew Knepley #include "src/mat/impls/aij/seq/aij.h" /*I "petscmat.h" I*/ 8f5eb4b81SSatish Balay #include "src/vec/vecimpl.h" 9f5eb4b81SSatish Balay #include "src/inline/spops.h" 108d195f9aSBarry Smith #include "src/inline/dot.h" 110a835dfdSSatish Balay #include "petscbt.h" 1217ab2063SBarry Smith 13a2ce50c7SBarry Smith 14ca44d042SBarry Smith EXTERN int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**); 1517ab2063SBarry Smith 164a2ae208SSatish Balay #undef __FUNCT__ 174a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ" 1836db0b34SBarry Smith int MatGetRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *m,int **ia,int **ja,PetscTruth *done) 1917ab2063SBarry Smith { 20416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 216945ee14SBarry Smith int ierr,i,ishift; 2217ab2063SBarry Smith 233a40ed3dSBarry Smith PetscFunctionBegin; 2431625ec5SSatish Balay *m = A->m; 253a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 266945ee14SBarry Smith ishift = a->indexshift; 2753e63a63SBarry Smith if (symmetric && !A->structurally_symmetric) { 28273d9f13SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr); 296945ee14SBarry Smith } else if (oshift == 0 && ishift == -1) { 30435da068SBarry Smith int nz = a->i[A->m] - 1; 313b2fbd54SBarry Smith /* malloc space and subtract 1 from i and j indices */ 32b0a32e0cSBarry Smith ierr = PetscMalloc((A->m+1)*sizeof(int),ia);CHKERRQ(ierr); 33b0a32e0cSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(int),ja);CHKERRQ(ierr); 343b2fbd54SBarry Smith for (i=0; i<nz; i++) (*ja)[i] = a->j[i] - 1; 35273d9f13SBarry Smith for (i=0; i<A->m+1; i++) (*ia)[i] = a->i[i] - 1; 366945ee14SBarry Smith } else if (oshift == 1 && ishift == 0) { 37435da068SBarry Smith int nz = a->i[A->m]; 383b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 391bc30dd5SBarry Smith ierr = PetscMalloc((A->m+1)*sizeof(int),ia);CHKERRQ(ierr); 40b0a32e0cSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(int),ja);CHKERRQ(ierr); 413b2fbd54SBarry Smith for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1; 42273d9f13SBarry Smith for (i=0; i<A->m+1; i++) (*ia)[i] = a->i[i] + 1; 436945ee14SBarry Smith } else { 446945ee14SBarry Smith *ia = a->i; *ja = a->j; 45a2ce50c7SBarry Smith } 463a40ed3dSBarry Smith PetscFunctionReturn(0); 47a2744918SBarry Smith } 48a2744918SBarry Smith 494a2ae208SSatish Balay #undef __FUNCT__ 504a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ" 5136db0b34SBarry Smith int MatRestoreRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja,PetscTruth *done) 526945ee14SBarry Smith { 536945ee14SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 54606d414cSSatish Balay int ishift = a->indexshift,ierr; 556945ee14SBarry Smith 563a40ed3dSBarry Smith PetscFunctionBegin; 573a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 5853e63a63SBarry Smith if ((symmetric && !A->structurally_symmetric) || (oshift == 0 && ishift == -1) || (oshift == 1 && ishift == 0)) { 59606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 60606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 61bcd2baecSBarry Smith } 623a40ed3dSBarry Smith PetscFunctionReturn(0); 6317ab2063SBarry Smith } 6417ab2063SBarry Smith 654a2ae208SSatish Balay #undef __FUNCT__ 664a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ" 6736db0b34SBarry Smith int MatGetColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done) 683b2fbd54SBarry Smith { 693b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 70a93ec695SBarry Smith int ierr,i,ishift = a->indexshift,*collengths,*cia,*cja,n = A->n,m = A->m; 71a93ec695SBarry Smith int nz = a->i[m]+ishift,row,*jj,mr,col; 723b2fbd54SBarry Smith 733a40ed3dSBarry Smith PetscFunctionBegin; 743b2fbd54SBarry Smith *nn = A->n; 753a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 763b2fbd54SBarry Smith if (symmetric) { 77273d9f13SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr); 783b2fbd54SBarry Smith } else { 79b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&collengths);CHKERRQ(ierr); 80549d3d68SSatish Balay ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr); 81b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&cia);CHKERRQ(ierr); 82b0a32e0cSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(int),&cja);CHKERRQ(ierr); 833b2fbd54SBarry Smith jj = a->j; 843b2fbd54SBarry Smith for (i=0; i<nz; i++) { 853b2fbd54SBarry Smith collengths[jj[i] + ishift]++; 863b2fbd54SBarry Smith } 873b2fbd54SBarry Smith cia[0] = oshift; 883b2fbd54SBarry Smith for (i=0; i<n; i++) { 893b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 903b2fbd54SBarry Smith } 91549d3d68SSatish Balay ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr); 923b2fbd54SBarry Smith jj = a->j; 93a93ec695SBarry Smith for (row=0; row<m; row++) { 94a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 95a93ec695SBarry Smith for (i=0; i<mr; i++) { 963b2fbd54SBarry Smith col = *jj++ + ishift; 973b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 983b2fbd54SBarry Smith } 993b2fbd54SBarry Smith } 100606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 1013b2fbd54SBarry Smith *ia = cia; *ja = cja; 1023b2fbd54SBarry Smith } 1033a40ed3dSBarry Smith PetscFunctionReturn(0); 1043b2fbd54SBarry Smith } 1053b2fbd54SBarry Smith 1064a2ae208SSatish Balay #undef __FUNCT__ 1074a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ" 10836db0b34SBarry Smith int MatRestoreColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja,PetscTruth *done) 1093b2fbd54SBarry Smith { 110606d414cSSatish Balay int ierr; 111606d414cSSatish Balay 1123a40ed3dSBarry Smith PetscFunctionBegin; 1133a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 1143b2fbd54SBarry Smith 115606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 116606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 1173b2fbd54SBarry Smith 1183a40ed3dSBarry Smith PetscFunctionReturn(0); 1193b2fbd54SBarry Smith } 1203b2fbd54SBarry Smith 121227d817aSBarry Smith #define CHUNKSIZE 15 12217ab2063SBarry Smith 1234a2ae208SSatish Balay #undef __FUNCT__ 1244a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ" 12587828ca2SBarry Smith int MatSetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,PetscScalar *v,InsertMode is) 12617ab2063SBarry Smith { 127416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 128416022c9SBarry Smith int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted = a->sorted; 129273d9f13SBarry Smith int *imax = a->imax,*ai = a->i,*ailen = a->ilen; 130549d3d68SSatish Balay int *aj = a->j,nonew = a->nonew,shift = a->indexshift,ierr; 13187828ca2SBarry Smith PetscScalar *ap,value,*aa = a->a; 13236db0b34SBarry Smith PetscTruth ignorezeroentries = ((a->ignorezeroentries && is == ADD_VALUES) ? PETSC_TRUE:PETSC_FALSE); 133273d9f13SBarry Smith PetscTruth roworiented = a->roworiented; 13417ab2063SBarry Smith 1353a40ed3dSBarry Smith PetscFunctionBegin; 13617ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 137416022c9SBarry Smith row = im[k]; 1385ef9f2a5SBarry Smith if (row < 0) continue; 139aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 140273d9f13SBarry Smith if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m); 1413b2fbd54SBarry Smith #endif 14217ab2063SBarry Smith rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 14317ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 144416022c9SBarry Smith low = 0; 14517ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 1465ef9f2a5SBarry Smith if (in[l] < 0) continue; 147aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 148273d9f13SBarry Smith if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n); 1493b2fbd54SBarry Smith #endif 1504b0e389bSBarry Smith col = in[l] - shift; 1514b0e389bSBarry Smith if (roworiented) { 1525ef9f2a5SBarry Smith value = v[l + k*n]; 153bef8e0ddSBarry Smith } else { 1544b0e389bSBarry Smith value = v[k + l*m]; 1554b0e389bSBarry Smith } 15636db0b34SBarry Smith if (value == 0.0 && ignorezeroentries) continue; 15736db0b34SBarry Smith 158416022c9SBarry Smith if (!sorted) low = 0; high = nrow; 159416022c9SBarry Smith while (high-low > 5) { 160416022c9SBarry Smith t = (low+high)/2; 161416022c9SBarry Smith if (rp[t] > col) high = t; 162416022c9SBarry Smith else low = t; 16317ab2063SBarry Smith } 164416022c9SBarry Smith for (i=low; i<high; i++) { 16517ab2063SBarry Smith if (rp[i] > col) break; 16617ab2063SBarry Smith if (rp[i] == col) { 167416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 16817ab2063SBarry Smith else ap[i] = value; 16917ab2063SBarry Smith goto noinsert; 17017ab2063SBarry Smith } 17117ab2063SBarry Smith } 172c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 17329bbc08cSBarry Smith else if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%d,%d) in the matrix",row,col); 17417ab2063SBarry Smith if (nrow >= rmax) { 17517ab2063SBarry Smith /* there is no extra room in row, therefore enlarge */ 176a7ed9263SMatthew Knepley int new_nz = ai[A->m] + CHUNKSIZE,*new_i,*new_j; 177a7ed9263SMatthew Knepley size_t len; 17887828ca2SBarry Smith PetscScalar *new_a; 17917ab2063SBarry Smith 18029bbc08cSBarry Smith if (nonew == -2) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%d,%d) in the matrix requiring new malloc()",row,col); 18196854ed6SLois Curfman McInnes 18217ab2063SBarry Smith /* malloc new storage space */ 183a7ed9263SMatthew Knepley len = ((size_t) new_nz)*(sizeof(int)+sizeof(PetscScalar))+(A->m+1)*sizeof(int); 184b0a32e0cSBarry Smith ierr = PetscMalloc(len,&new_a);CHKERRQ(ierr); 18517ab2063SBarry Smith new_j = (int*)(new_a + new_nz); 18617ab2063SBarry Smith new_i = new_j + new_nz; 18717ab2063SBarry Smith 18817ab2063SBarry Smith /* copy over old data into new slots */ 18917ab2063SBarry Smith for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];} 190273d9f13SBarry Smith for (ii=row+1; ii<A->m+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;} 191549d3d68SSatish Balay ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow+shift)*sizeof(int));CHKERRQ(ierr); 192a7ed9263SMatthew Knepley len = (((size_t) new_nz) - CHUNKSIZE - ai[row] - nrow - shift); 193549d3d68SSatish Balay ierr = PetscMemcpy(new_j+ai[row]+shift+nrow+CHUNKSIZE,aj+ai[row]+shift+nrow,len*sizeof(int));CHKERRQ(ierr); 194a7ed9263SMatthew Knepley ierr = PetscMemcpy(new_a,aa,(((size_t) ai[row])+nrow+shift)*sizeof(PetscScalar));CHKERRQ(ierr); 19587828ca2SBarry Smith ierr = PetscMemcpy(new_a+ai[row]+shift+nrow+CHUNKSIZE,aa+ai[row]+shift+nrow,len*sizeof(PetscScalar));CHKERRQ(ierr); 19617ab2063SBarry Smith /* free up old matrix storage */ 197606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 198606d414cSSatish Balay if (!a->singlemalloc) { 199606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 200606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 201606d414cSSatish Balay } 202416022c9SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 203f1e2ffcdSBarry Smith a->singlemalloc = PETSC_TRUE; 20417ab2063SBarry Smith 20517ab2063SBarry Smith rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 206416022c9SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 20787828ca2SBarry Smith PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + sizeof(PetscScalar))); 208416022c9SBarry Smith a->maxnz += CHUNKSIZE; 209b810aeb4SBarry Smith a->reallocs++; 21017ab2063SBarry Smith } 211416022c9SBarry Smith N = nrow++ - 1; a->nz++; 212416022c9SBarry Smith /* shift up all the later entries in this row */ 213416022c9SBarry Smith for (ii=N; ii>=i; ii--) { 21417ab2063SBarry Smith rp[ii+1] = rp[ii]; 21517ab2063SBarry Smith ap[ii+1] = ap[ii]; 21617ab2063SBarry Smith } 21717ab2063SBarry Smith rp[i] = col; 21817ab2063SBarry Smith ap[i] = value; 21917ab2063SBarry Smith noinsert:; 220416022c9SBarry Smith low = i + 1; 22117ab2063SBarry Smith } 22217ab2063SBarry Smith ailen[row] = nrow; 22317ab2063SBarry Smith } 2243a40ed3dSBarry Smith PetscFunctionReturn(0); 22517ab2063SBarry Smith } 22617ab2063SBarry Smith 2274a2ae208SSatish Balay #undef __FUNCT__ 2284a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ" 22987828ca2SBarry Smith int MatGetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,PetscScalar *v) 2307eb43aa7SLois Curfman McInnes { 2317eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 232b49de8d1SLois Curfman McInnes int *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 2337eb43aa7SLois Curfman McInnes int *ai = a->i,*ailen = a->ilen,shift = a->indexshift; 23487828ca2SBarry Smith PetscScalar *ap,*aa = a->a,zero = 0.0; 2357eb43aa7SLois Curfman McInnes 2363a40ed3dSBarry Smith PetscFunctionBegin; 2377eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 2387eb43aa7SLois Curfman McInnes row = im[k]; 23929bbc08cSBarry Smith if (row < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %d",row); 240273d9f13SBarry Smith if (row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: %d",row); 2417eb43aa7SLois Curfman McInnes rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 2427eb43aa7SLois Curfman McInnes nrow = ailen[row]; 2437eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 24429bbc08cSBarry Smith if (in[l] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %d",in[l]); 245273d9f13SBarry Smith if (in[l] >= A->n) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: %d",in[l]); 2467eb43aa7SLois Curfman McInnes col = in[l] - shift; 2477eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 2487eb43aa7SLois Curfman McInnes while (high-low > 5) { 2497eb43aa7SLois Curfman McInnes t = (low+high)/2; 2507eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 2517eb43aa7SLois Curfman McInnes else low = t; 2527eb43aa7SLois Curfman McInnes } 2537eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 2547eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 2557eb43aa7SLois Curfman McInnes if (rp[i] == col) { 256b49de8d1SLois Curfman McInnes *v++ = ap[i]; 2577eb43aa7SLois Curfman McInnes goto finished; 2587eb43aa7SLois Curfman McInnes } 2597eb43aa7SLois Curfman McInnes } 260b49de8d1SLois Curfman McInnes *v++ = zero; 2617eb43aa7SLois Curfman McInnes finished:; 2627eb43aa7SLois Curfman McInnes } 2637eb43aa7SLois Curfman McInnes } 2643a40ed3dSBarry Smith PetscFunctionReturn(0); 2657eb43aa7SLois Curfman McInnes } 2667eb43aa7SLois Curfman McInnes 26717ab2063SBarry Smith 2684a2ae208SSatish Balay #undef __FUNCT__ 2694a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary" 270b0a32e0cSBarry Smith int MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer) 27117ab2063SBarry Smith { 272416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 273416022c9SBarry Smith int i,fd,*col_lens,ierr; 27417ab2063SBarry Smith 2753a40ed3dSBarry Smith PetscFunctionBegin; 276b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 277b0a32e0cSBarry Smith ierr = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr); 278552e946dSBarry Smith col_lens[0] = MAT_FILE_COOKIE; 279273d9f13SBarry Smith col_lens[1] = A->m; 280273d9f13SBarry Smith col_lens[2] = A->n; 281416022c9SBarry Smith col_lens[3] = a->nz; 282416022c9SBarry Smith 283416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 284273d9f13SBarry Smith for (i=0; i<A->m; i++) { 285416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 28617ab2063SBarry Smith } 287273d9f13SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr); 288606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 289416022c9SBarry Smith 290416022c9SBarry Smith /* store column indices (zero start index) */ 291416022c9SBarry Smith if (a->indexshift) { 292416022c9SBarry Smith for (i=0; i<a->nz; i++) a->j[i]--; 29317ab2063SBarry Smith } 2940752156aSBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,0);CHKERRQ(ierr); 295416022c9SBarry Smith if (a->indexshift) { 296416022c9SBarry Smith for (i=0; i<a->nz; i++) a->j[i]++; 29717ab2063SBarry Smith } 298416022c9SBarry Smith 299416022c9SBarry Smith /* store nonzero values */ 3000752156aSBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,0);CHKERRQ(ierr); 3013a40ed3dSBarry Smith PetscFunctionReturn(0); 30217ab2063SBarry Smith } 303416022c9SBarry Smith 3047f43a090SHong Zhang extern int MatSeqAIJFactorInfo_SuperLU(Mat,PetscViewer); 305cd155464SBarry Smith extern int MatMPIAIJFactorInfo_SuperLu(Mat,PetscViewer); 306a072f7f7SHong Zhang extern int MatFactorInfo_Spooles(Mat,PetscViewer); 307e7420845SHong Zhang extern int MatSeqAIJFactorInfo_UMFPACK(Mat,PetscViewer); 3084ffef66eSHong Zhang extern int MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 309*1dfdf1d9SHong Zhang extern int MatFactorInfo_MUMPS(Mat,PetscViewer); 310cd155464SBarry Smith 3114a2ae208SSatish Balay #undef __FUNCT__ 3124a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII" 313b0a32e0cSBarry Smith int MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 314416022c9SBarry Smith { 315416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 316fb9695e5SSatish Balay int ierr,i,j,m = A->m,shift = a->indexshift; 317fb9695e5SSatish Balay char *name; 318f3ef73ceSBarry Smith PetscViewerFormat format; 31917ab2063SBarry Smith 3203a40ed3dSBarry Smith PetscFunctionBegin; 321435da068SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 322b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 323456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO_DETAIL || format == PETSC_VIEWER_ASCII_INFO) { 3246831982aSBarry Smith if (a->inode.size) { 325b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"using I-node routines: found %d nodes, limit used is %d\n",a->inode.node_count,a->inode.limit);CHKERRQ(ierr); 3266831982aSBarry Smith } else { 327b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"not using I-node routines\n");CHKERRQ(ierr); 3286831982aSBarry Smith } 329fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_MATLAB) { 330d00d2cf4SBarry Smith int nofinalvalue = 0; 331273d9f13SBarry Smith if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->n-!shift)) { 332d00d2cf4SBarry Smith nofinalvalue = 1; 333d00d2cf4SBarry Smith } 334b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 335b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %d %d \n",m,A->n);CHKERRQ(ierr); 336b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %d \n",a->nz);CHKERRQ(ierr); 337b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%d,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 338b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 33917ab2063SBarry Smith 34017ab2063SBarry Smith for (i=0; i<m; i++) { 341416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 342aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 343b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%d %d %18.16e + %18.16ei \n",i+1,a->j[j]+!shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 34417ab2063SBarry Smith #else 345b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%d %d %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr); 34617ab2063SBarry Smith #endif 34717ab2063SBarry Smith } 34817ab2063SBarry Smith } 349d00d2cf4SBarry Smith if (nofinalvalue) { 350b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%d %d %18.16e\n",m,A->n,0.0);CHKERRQ(ierr); 351d00d2cf4SBarry Smith } 352fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 353b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 354cd155464SBarry Smith } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 3556ea74821SHong Zhang #if defined(PETSC_HAVE_SUPERLU) && !defined(PETSC_USE_SINGLE) 3567f43a090SHong Zhang ierr = MatSeqAIJFactorInfo_SuperLU(A,viewer);CHKERRQ(ierr); 3577f43a090SHong Zhang #endif 3586ea74821SHong Zhang #if defined(PETSC_HAVE_SUPERLUDIST) && !defined(PETSC_USE_SINGLE) 359cd155464SBarry Smith ierr = MatMPIAIJFactorInfo_SuperLu(A,viewer);CHKERRQ(ierr); 360cd155464SBarry Smith #endif 3616ea74821SHong Zhang #if defined(PETSC_HAVE_SPOOLES) && !defined(PETSC_USE_SINGLE) 362a072f7f7SHong Zhang ierr = MatFactorInfo_Spooles(A,viewer);CHKERRQ(ierr); 363174d842dSHong Zhang #endif 364e7420845SHong Zhang #if defined(PETSC_HAVE_UMFPACK) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_COMPLEX) 365e7420845SHong Zhang ierr = MatSeqAIJFactorInfo_UMFPACK(A,viewer);CHKERRQ(ierr); 366e7420845SHong Zhang #endif 3674ffef66eSHong Zhang #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_COMPLEX) 3684ffef66eSHong Zhang ierr = MatSeqAIJFactorInfo_Matlab(A,viewer);CHKERRQ(ierr); 3694ffef66eSHong Zhang #endif 370*1dfdf1d9SHong Zhang #if defined(PETSC_HAVE_MUMPS) && !defined(PETSC_USE_SINGLE) 371*1dfdf1d9SHong Zhang ierr = MatFactorInfo_MUMPS(A,viewer);CHKERRQ(ierr); 372*1dfdf1d9SHong Zhang #endif 373cd155464SBarry Smith PetscFunctionReturn(0); 374fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 375b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 37644cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 377b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr); 37844cd7ae7SLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 379aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 38036db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 38162b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 38236db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 38362b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 38436db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 38562b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 3866831982aSBarry Smith } 38744cd7ae7SLois Curfman McInnes #else 38862b941d6SBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);} 38944cd7ae7SLois Curfman McInnes #endif 39044cd7ae7SLois Curfman McInnes } 391b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 39244cd7ae7SLois Curfman McInnes } 393b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 394fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 395496be53dSLois Curfman McInnes int nzd=0,fshift=1,*sptr; 396b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 397b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&sptr);CHKERRQ(ierr); 398496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 399496be53dSLois Curfman McInnes sptr[i] = nzd+1; 400496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 401496be53dSLois Curfman McInnes if (a->j[j] >= i) { 402aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 40336db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 404496be53dSLois Curfman McInnes #else 405496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 406496be53dSLois Curfman McInnes #endif 407496be53dSLois Curfman McInnes } 408496be53dSLois Curfman McInnes } 409496be53dSLois Curfman McInnes } 4102e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 411b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %d\n\n",m,nzd);CHKERRQ(ierr); 4122e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 413b0a32e0cSBarry Smith if (i+4<m) {ierr = PetscViewerASCIIPrintf(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);} 414b0a32e0cSBarry Smith else if (i+3<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4]);CHKERRQ(ierr);} 415b0a32e0cSBarry Smith else if (i+2<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);} 416b0a32e0cSBarry Smith else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);} 417b0a32e0cSBarry Smith else if (i<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);} 418b0a32e0cSBarry Smith else {ierr = PetscViewerASCIIPrintf(viewer," %d\n",sptr[i]);CHKERRQ(ierr);} 419496be53dSLois Curfman McInnes } 420b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 421606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 422496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 423496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 424b0a32e0cSBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %d ",a->j[j]+fshift);CHKERRQ(ierr);} 425496be53dSLois Curfman McInnes } 426b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 427496be53dSLois Curfman McInnes } 428b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 429496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 430496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 431496be53dSLois Curfman McInnes if (a->j[j] >= i) { 432aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 43336db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 434b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 4356831982aSBarry Smith } 436496be53dSLois Curfman McInnes #else 437b0a32e0cSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);} 438496be53dSLois Curfman McInnes #endif 439496be53dSLois Curfman McInnes } 440496be53dSLois Curfman McInnes } 441b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 442496be53dSLois Curfman McInnes } 443b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 444fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 44502594712SBarry Smith int cnt = 0,jcnt; 44687828ca2SBarry Smith PetscScalar value; 44702594712SBarry Smith 448b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 44902594712SBarry Smith for (i=0; i<m; i++) { 45002594712SBarry Smith jcnt = 0; 451273d9f13SBarry Smith for (j=0; j<A->n; j++) { 452e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 45302594712SBarry Smith value = a->a[cnt++]; 454e24b481bSBarry Smith jcnt++; 45502594712SBarry Smith } else { 45602594712SBarry Smith value = 0.0; 45702594712SBarry Smith } 458aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 459b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr); 46002594712SBarry Smith #else 461b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr); 46202594712SBarry Smith #endif 46302594712SBarry Smith } 464b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 46502594712SBarry Smith } 466b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 4673a40ed3dSBarry Smith } else { 468b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 46917ab2063SBarry Smith for (i=0; i<m; i++) { 470b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr); 471416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 472aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 47336db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 47462b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 47536db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 47662b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 4773a40ed3dSBarry Smith } else { 47862b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 47917ab2063SBarry Smith } 48017ab2063SBarry Smith #else 48162b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 48217ab2063SBarry Smith #endif 48317ab2063SBarry Smith } 484b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 48517ab2063SBarry Smith } 486b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 48717ab2063SBarry Smith } 488b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 4893a40ed3dSBarry Smith PetscFunctionReturn(0); 490416022c9SBarry Smith } 491416022c9SBarry Smith 4924a2ae208SSatish Balay #undef __FUNCT__ 4934a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom" 494b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 495416022c9SBarry Smith { 496480ef9eaSBarry Smith Mat A = (Mat) Aa; 497416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 498273d9f13SBarry Smith int ierr,i,j,m = A->m,shift = a->indexshift,color; 49936db0b34SBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0; 500b0a32e0cSBarry Smith PetscViewer viewer; 501f3ef73ceSBarry Smith PetscViewerFormat format; 502cddf8d76SBarry Smith 5033a40ed3dSBarry Smith PetscFunctionBegin; 504480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 505b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 50619bcc07fSBarry Smith 507b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 508416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 5090513a670SBarry Smith 510fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 5110513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 512b0a32e0cSBarry Smith color = PETSC_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) 51836db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 519cddf8d76SBarry Smith #else 520cddf8d76SBarry Smith if (a->a[j] >= 0.) continue; 521cddf8d76SBarry Smith #endif 522b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 523cddf8d76SBarry Smith } 524cddf8d76SBarry Smith } 525b0a32e0cSBarry Smith color = PETSC_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; 531b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 532cddf8d76SBarry Smith } 533cddf8d76SBarry Smith } 534b0a32e0cSBarry Smith color = PETSC_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) 54036db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 541cddf8d76SBarry Smith #else 542cddf8d76SBarry Smith if (a->a[j] <= 0.) continue; 543cddf8d76SBarry Smith #endif 544b0a32e0cSBarry Smith ierr = PetscDrawRectangle(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; 551b0a32e0cSBarry Smith PetscDraw popup; 55236db0b34SBarry Smith PetscReal 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 } 557b0a32e0cSBarry Smith scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv; 558b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 559b0a32e0cSBarry Smith if (popup) {ierr = PetscDrawScalePopup(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; 565b0a32e0cSBarry Smith color = PETSC_DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(a->a[count])); 566b0a32e0cSBarry Smith ierr = PetscDrawRectangle(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 5744a2ae208SSatish Balay #undef __FUNCT__ 5754a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw" 576b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 577480ef9eaSBarry Smith { 578480ef9eaSBarry Smith int ierr; 579b0a32e0cSBarry Smith PetscDraw draw; 58036db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 581480ef9eaSBarry Smith PetscTruth isnull; 582480ef9eaSBarry Smith 583480ef9eaSBarry Smith PetscFunctionBegin; 584b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 585b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 586480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 587480ef9eaSBarry Smith 588480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 589273d9f13SBarry Smith xr = A->n; yr = A->m; h = yr/10.0; w = xr/10.0; 590480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 591b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 592b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 593480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 5943a40ed3dSBarry Smith PetscFunctionReturn(0); 595416022c9SBarry Smith } 596416022c9SBarry Smith 5974a2ae208SSatish Balay #undef __FUNCT__ 5984a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ" 599b0a32e0cSBarry Smith int MatView_SeqAIJ(Mat A,PetscViewer viewer) 600416022c9SBarry Smith { 601416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 602bcd2baecSBarry Smith int ierr; 6036831982aSBarry Smith PetscTruth issocket,isascii,isbinary,isdraw; 604416022c9SBarry Smith 6053a40ed3dSBarry Smith PetscFunctionBegin; 606b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr); 607b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr); 608fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr); 609fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr); 6100f5bd95cSBarry Smith if (issocket) { 61101820c62SBarry Smith if (a->indexshift) { 61229bbc08cSBarry Smith SETERRQ(1,"Can only socket send sparse matrix with 0 based indexing"); 61301820c62SBarry Smith } 614b0a32e0cSBarry Smith ierr = PetscViewerSocketPutSparse_Private(viewer,A->m,A->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr); 6150f5bd95cSBarry Smith } else if (isascii) { 6163a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 6170f5bd95cSBarry Smith } else if (isbinary) { 6183a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 6190f5bd95cSBarry Smith } else if (isdraw) { 6203a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 6215cd90555SBarry Smith } else { 62229bbc08cSBarry Smith SETERRQ1(1,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name); 62317ab2063SBarry Smith } 6243a40ed3dSBarry Smith PetscFunctionReturn(0); 62517ab2063SBarry Smith } 62619bcc07fSBarry Smith 6273a7fca6bSBarry Smith EXTERN int Mat_AIJ_CheckInode(Mat,PetscTruth); 6284a2ae208SSatish Balay #undef __FUNCT__ 6294a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ" 6308f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 63117ab2063SBarry Smith { 632416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 63341c01911SSatish Balay int fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax,ierr; 634273d9f13SBarry Smith int m = A->m,*ip,N,*ailen = a->ilen,shift = a->indexshift,rmax = 0; 63587828ca2SBarry Smith PetscScalar *aa = a->a,*ap; 636eee76cafSHong Zhang #if defined(PETSC_HAVE_SUPERLUDIST) || defined(PETSC_HAVE_SPOOLES) || defined(PETSC_HAVE_UMFPACK) || defined(PETSC_HAVE_MUMPS) 6379b9367d5SHong Zhang PetscTruth flag; 6389e070d67SMatthew Knepley #endif 63917ab2063SBarry Smith 6403a40ed3dSBarry Smith PetscFunctionBegin; 6413a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 64217ab2063SBarry Smith 64343ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 64417ab2063SBarry Smith for (i=1; i<m; i++) { 645416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 64617ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 64794a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 64817ab2063SBarry Smith if (fshift) { 6490f5bd95cSBarry Smith ip = aj + ai[i] + shift; 6500f5bd95cSBarry Smith ap = aa + ai[i] + shift; 65117ab2063SBarry Smith N = ailen[i]; 65217ab2063SBarry Smith for (j=0; j<N; j++) { 65317ab2063SBarry Smith ip[j-fshift] = ip[j]; 65417ab2063SBarry Smith ap[j-fshift] = ap[j]; 65517ab2063SBarry Smith } 65617ab2063SBarry Smith } 65717ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 65817ab2063SBarry Smith } 65917ab2063SBarry Smith if (m) { 66017ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 66117ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 66217ab2063SBarry Smith } 66317ab2063SBarry Smith /* reset ilen and imax for each row */ 66417ab2063SBarry Smith for (i=0; i<m; i++) { 66517ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 66617ab2063SBarry Smith } 667416022c9SBarry Smith a->nz = ai[m] + shift; 66817ab2063SBarry Smith 66917ab2063SBarry Smith /* diagonals may have moved, so kill the diagonal pointers */ 670416022c9SBarry Smith if (fshift && a->diag) { 671606d414cSSatish Balay ierr = PetscFree(a->diag);CHKERRQ(ierr); 672b0a32e0cSBarry Smith PetscLogObjectMemory(A,-(m+1)*sizeof(int)); 673416022c9SBarry Smith a->diag = 0; 67417ab2063SBarry Smith } 675b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded,%d used\n",m,A->n,fshift,a->nz); 676b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues() is %d\n",a->reallocs); 677b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Most nonzeros in any row is %d\n",rmax); 678dd5f02e7SSatish Balay a->reallocs = 0; 6794e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift; 68036db0b34SBarry Smith a->rmax = rmax; 6814e220ebcSLois Curfman McInnes 68276dd722bSSatish Balay /* check out for identical nodes. If found, use inode functions */ 6833a7fca6bSBarry Smith ierr = Mat_AIJ_CheckInode(A,(PetscTruth)(!fshift));CHKERRQ(ierr); 684cfef3cccSHong Zhang 6859b9367d5SHong Zhang #if defined(PETSC_HAVE_SUPERLUDIST) 686e82a3eeeSBarry Smith ierr = PetscOptionsHasName(A->prefix,"-mat_aij_superlu_dist",&flag);CHKERRQ(ierr); 6879b9367d5SHong Zhang if (flag) { ierr = MatUseSuperLU_DIST_MPIAIJ(A);CHKERRQ(ierr); } 6889b9367d5SHong Zhang #endif 6899b9367d5SHong Zhang 690cfef3cccSHong Zhang #if defined(PETSC_HAVE_SPOOLES) 691e82a3eeeSBarry Smith ierr = PetscOptionsHasName(A->prefix,"-mat_aij_spooles",&flag);CHKERRQ(ierr); 692cfef3cccSHong Zhang if (flag) { ierr = MatUseSpooles_SeqAIJ(A);CHKERRQ(ierr); } 693cfef3cccSHong Zhang #endif 694cfef3cccSHong Zhang 695564e58d6SHong Zhang #if defined(PETSC_HAVE_UMFPACK) 696e82a3eeeSBarry Smith ierr = PetscOptionsHasName(A->prefix,"-mat_aij_umfpack",&flag);CHKERRQ(ierr); 697564e58d6SHong Zhang if (flag) { ierr = MatUseUMFPACK_SeqAIJ(A);CHKERRQ(ierr); } 698564e58d6SHong Zhang #endif 699564e58d6SHong Zhang 700eee76cafSHong Zhang #if defined(PETSC_HAVE_MUMPS) 701eee76cafSHong Zhang ierr = PetscOptionsHasName(A->prefix,"-mat_aij_mumps",&flag);CHKERRQ(ierr); 702eee76cafSHong Zhang if (flag) { ierr = MatUseMUMPS_MPIAIJ(A);CHKERRQ(ierr); } 703eee76cafSHong Zhang #endif 704eee76cafSHong Zhang 7053a40ed3dSBarry Smith PetscFunctionReturn(0); 70617ab2063SBarry Smith } 70717ab2063SBarry Smith 7084a2ae208SSatish Balay #undef __FUNCT__ 7094a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ" 7108f6be9afSLois Curfman McInnes int MatZeroEntries_SeqAIJ(Mat A) 71117ab2063SBarry Smith { 712416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 713549d3d68SSatish Balay int ierr; 7143a40ed3dSBarry Smith 7153a40ed3dSBarry Smith PetscFunctionBegin; 71687828ca2SBarry Smith ierr = PetscMemzero(a->a,(a->i[A->m]+a->indexshift)*sizeof(PetscScalar));CHKERRQ(ierr); 7173a40ed3dSBarry Smith PetscFunctionReturn(0); 71817ab2063SBarry Smith } 719416022c9SBarry Smith 7204a2ae208SSatish Balay #undef __FUNCT__ 7214a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ" 722e1311b90SBarry Smith int MatDestroy_SeqAIJ(Mat A) 72317ab2063SBarry Smith { 724416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 72582bf6240SBarry Smith int ierr; 726d5d45c9bSBarry Smith 7273a40ed3dSBarry Smith PetscFunctionBegin; 728aa482453SBarry Smith #if defined(PETSC_USE_LOG) 729b0a32e0cSBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz); 73017ab2063SBarry Smith #endif 73136db0b34SBarry Smith if (a->freedata) { 732606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 733606d414cSSatish Balay if (!a->singlemalloc) { 734606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 735606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 736606d414cSSatish Balay } 73736db0b34SBarry Smith } 738c38d4ed2SBarry Smith if (a->row) { 739c38d4ed2SBarry Smith ierr = ISDestroy(a->row);CHKERRQ(ierr); 740c38d4ed2SBarry Smith } 741c38d4ed2SBarry Smith if (a->col) { 742c38d4ed2SBarry Smith ierr = ISDestroy(a->col);CHKERRQ(ierr); 743c38d4ed2SBarry Smith } 744606d414cSSatish Balay if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);} 745606d414cSSatish Balay if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);} 746606d414cSSatish Balay if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);} 747273d9f13SBarry Smith if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);} 748606d414cSSatish Balay if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);} 749606d414cSSatish Balay if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);} 75082bf6240SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 751606d414cSSatish Balay if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);} 752cc8ba8e1SBarry Smith if (a->coloring) {ierr = ISColoringDestroy(a->coloring);CHKERRQ(ierr);} 753a30b2313SHong Zhang if (a->xtoy) {ierr = PetscFree(a->xtoy);CHKERRQ(ierr);} 754a30b2313SHong Zhang 755606d414cSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 7563a40ed3dSBarry Smith PetscFunctionReturn(0); 75717ab2063SBarry Smith } 75817ab2063SBarry Smith 7594a2ae208SSatish Balay #undef __FUNCT__ 7604a2ae208SSatish Balay #define __FUNCT__ "MatCompress_SeqAIJ" 7618f6be9afSLois Curfman McInnes int MatCompress_SeqAIJ(Mat A) 76217ab2063SBarry Smith { 7633a40ed3dSBarry Smith PetscFunctionBegin; 7643a40ed3dSBarry Smith PetscFunctionReturn(0); 76517ab2063SBarry Smith } 76617ab2063SBarry Smith 7674a2ae208SSatish Balay #undef __FUNCT__ 7684a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ" 7698f6be9afSLois Curfman McInnes int MatSetOption_SeqAIJ(Mat A,MatOption op) 77017ab2063SBarry Smith { 771416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 7723a40ed3dSBarry Smith 7733a40ed3dSBarry Smith PetscFunctionBegin; 774a65d3064SKris Buschelman switch (op) { 775a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 776a65d3064SKris Buschelman a->roworiented = PETSC_TRUE; 777a65d3064SKris Buschelman break; 778a65d3064SKris Buschelman case MAT_KEEP_ZEROED_ROWS: 779a65d3064SKris Buschelman a->keepzeroedrows = PETSC_TRUE; 780a65d3064SKris Buschelman break; 781a65d3064SKris Buschelman case MAT_COLUMN_ORIENTED: 782a65d3064SKris Buschelman a->roworiented = PETSC_FALSE; 783a65d3064SKris Buschelman break; 784a65d3064SKris Buschelman case MAT_COLUMNS_SORTED: 785a65d3064SKris Buschelman a->sorted = PETSC_TRUE; 786a65d3064SKris Buschelman break; 787a65d3064SKris Buschelman case MAT_COLUMNS_UNSORTED: 788a65d3064SKris Buschelman a->sorted = PETSC_FALSE; 789a65d3064SKris Buschelman break; 790a65d3064SKris Buschelman case MAT_NO_NEW_NONZERO_LOCATIONS: 791a65d3064SKris Buschelman a->nonew = 1; 792a65d3064SKris Buschelman break; 793a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 794a65d3064SKris Buschelman a->nonew = -1; 795a65d3064SKris Buschelman break; 796a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 797a65d3064SKris Buschelman a->nonew = -2; 798a65d3064SKris Buschelman break; 799a65d3064SKris Buschelman case MAT_YES_NEW_NONZERO_LOCATIONS: 800a65d3064SKris Buschelman a->nonew = 0; 801a65d3064SKris Buschelman break; 802a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 803a65d3064SKris Buschelman a->ignorezeroentries = PETSC_TRUE; 804a65d3064SKris Buschelman break; 805a65d3064SKris Buschelman case MAT_USE_INODES: 806a65d3064SKris Buschelman a->inode.use = PETSC_TRUE; 807a65d3064SKris Buschelman break; 808a65d3064SKris Buschelman case MAT_DO_NOT_USE_INODES: 809a65d3064SKris Buschelman a->inode.use = PETSC_FALSE; 810a65d3064SKris Buschelman break; 811a65d3064SKris Buschelman case MAT_ROWS_SORTED: 812a65d3064SKris Buschelman case MAT_ROWS_UNSORTED: 813a65d3064SKris Buschelman case MAT_YES_NEW_DIAGONALS: 814a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 815a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 816b0a32e0cSBarry Smith PetscLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n"); 817a65d3064SKris Buschelman break; 818a65d3064SKris Buschelman case MAT_NO_NEW_DIAGONALS: 81929bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS"); 820a65d3064SKris Buschelman case MAT_INODE_LIMIT_1: 821a65d3064SKris Buschelman a->inode.limit = 1; 822a65d3064SKris Buschelman break; 823a65d3064SKris Buschelman case MAT_INODE_LIMIT_2: 824a65d3064SKris Buschelman a->inode.limit = 2; 825a65d3064SKris Buschelman break; 826a65d3064SKris Buschelman case MAT_INODE_LIMIT_3: 827a65d3064SKris Buschelman a->inode.limit = 3; 828a65d3064SKris Buschelman break; 829a65d3064SKris Buschelman case MAT_INODE_LIMIT_4: 830a65d3064SKris Buschelman a->inode.limit = 4; 831a65d3064SKris Buschelman break; 832a65d3064SKris Buschelman case MAT_INODE_LIMIT_5: 833a65d3064SKris Buschelman a->inode.limit = 5; 834a65d3064SKris Buschelman break; 835a65d3064SKris Buschelman default: 836a65d3064SKris Buschelman SETERRQ(PETSC_ERR_SUP,"unknown option"); 837a65d3064SKris Buschelman } 8383a40ed3dSBarry Smith PetscFunctionReturn(0); 83917ab2063SBarry Smith } 84017ab2063SBarry Smith 8414a2ae208SSatish Balay #undef __FUNCT__ 8424a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ" 8438f6be9afSLois Curfman McInnes int MatGetDiagonal_SeqAIJ(Mat A,Vec v) 84417ab2063SBarry Smith { 845416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 8463a40ed3dSBarry Smith int i,j,n,shift = a->indexshift,ierr; 84787828ca2SBarry Smith PetscScalar *x,zero = 0.0; 84817ab2063SBarry Smith 8493a40ed3dSBarry Smith PetscFunctionBegin; 8503a40ed3dSBarry Smith ierr = VecSet(&zero,v);CHKERRQ(ierr); 851ed480e8bSBarry Smith ierr = VecGetArrayFast(v,&x);CHKERRQ(ierr); 85236db0b34SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 853273d9f13SBarry Smith if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 854273d9f13SBarry Smith for (i=0; i<A->m; i++) { 855416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 856416022c9SBarry Smith if (a->j[j]+shift == i) { 857416022c9SBarry Smith x[i] = a->a[j]; 85817ab2063SBarry Smith break; 85917ab2063SBarry Smith } 86017ab2063SBarry Smith } 86117ab2063SBarry Smith } 862ed480e8bSBarry Smith ierr = VecRestoreArrayFast(v,&x);CHKERRQ(ierr); 8633a40ed3dSBarry Smith PetscFunctionReturn(0); 86417ab2063SBarry Smith } 86517ab2063SBarry Smith 866d5d45c9bSBarry Smith 8674a2ae208SSatish Balay #undef __FUNCT__ 8684a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ" 8697c922b88SBarry Smith int MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 87017ab2063SBarry Smith { 871416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 8725c897100SBarry Smith PetscScalar *x,*y; 8735c897100SBarry Smith int ierr,m = A->m,shift = a->indexshift; 8745c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 8755c897100SBarry Smith PetscScalar *v,alpha; 8765c897100SBarry Smith int n,i,*idx; 8775c897100SBarry Smith #endif 87817ab2063SBarry Smith 8793a40ed3dSBarry Smith PetscFunctionBegin; 8802e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 881ed480e8bSBarry Smith ierr = VecGetArrayFast(xx,&x);CHKERRQ(ierr); 882ed480e8bSBarry Smith ierr = VecGetArrayFast(yy,&y);CHKERRQ(ierr); 88317ab2063SBarry Smith y = y + shift; /* shift for Fortran start by 1 indexing */ 8845c897100SBarry Smith 8855c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 8865c897100SBarry Smith fortranmulttransposeaddaij_(&m,x,a->i,a->j+shift,a->a+shift,y); 8875c897100SBarry Smith #else 88817ab2063SBarry Smith for (i=0; i<m; i++) { 889416022c9SBarry Smith idx = a->j + a->i[i] + shift; 890416022c9SBarry Smith v = a->a + a->i[i] + shift; 891416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 89217ab2063SBarry Smith alpha = x[i]; 89317ab2063SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 89417ab2063SBarry Smith } 8955c897100SBarry Smith #endif 896b0a32e0cSBarry Smith PetscLogFlops(2*a->nz); 897ed480e8bSBarry Smith ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr); 898ed480e8bSBarry Smith ierr = VecRestoreArrayFast(yy,&y);CHKERRQ(ierr); 8993a40ed3dSBarry Smith PetscFunctionReturn(0); 90017ab2063SBarry Smith } 90117ab2063SBarry Smith 9024a2ae208SSatish Balay #undef __FUNCT__ 9035c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ" 9045c897100SBarry Smith int MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 9055c897100SBarry Smith { 9068d5b0100SBarry Smith PetscScalar zero = 0.0; 9075c897100SBarry Smith int ierr; 9085c897100SBarry Smith 9095c897100SBarry Smith PetscFunctionBegin; 9105c897100SBarry Smith ierr = VecSet(&zero,yy);CHKERRQ(ierr); 9115c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 9125c897100SBarry Smith PetscFunctionReturn(0); 9135c897100SBarry Smith } 9145c897100SBarry Smith 9155c897100SBarry Smith 9165c897100SBarry Smith #undef __FUNCT__ 9174a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ" 91844cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 91917ab2063SBarry Smith { 920416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 921362ced78SSatish Balay PetscScalar *x,*y,*v; 922273d9f13SBarry Smith int ierr,m = A->m,*idx,shift = a->indexshift,*ii; 923aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 924e36a17ebSSatish Balay int n,i,jrow,j; 925362ced78SSatish Balay PetscScalar sum; 926e36a17ebSSatish Balay #endif 92717ab2063SBarry Smith 928b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 929fee21e36SBarry Smith #pragma disjoint(*x,*y,*v) 930fee21e36SBarry Smith #endif 931fee21e36SBarry Smith 9323a40ed3dSBarry Smith PetscFunctionBegin; 933ed480e8bSBarry Smith ierr = VecGetArrayFast(xx,&x);CHKERRQ(ierr); 934ed480e8bSBarry Smith ierr = VecGetArrayFast(yy,&y);CHKERRQ(ierr); 93517ab2063SBarry Smith x = x + shift; /* shift for Fortran start by 1 indexing */ 936416022c9SBarry Smith idx = a->j; 937d64ed03dSBarry Smith v = a->a; 938416022c9SBarry Smith ii = a->i; 939aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 94029b5ca8aSSatish Balay fortranmultaij_(&m,x,ii,idx+shift,v+shift,y); 9418d195f9aSBarry Smith #else 942d64ed03dSBarry Smith v += shift; /* shift for Fortran start by 1 indexing */ 943d64ed03dSBarry Smith idx += shift; 94417ab2063SBarry Smith for (i=0; i<m; i++) { 9459ea0dfa2SSatish Balay jrow = ii[i]; 9469ea0dfa2SSatish Balay n = ii[i+1] - jrow; 94717ab2063SBarry Smith sum = 0.0; 9489ea0dfa2SSatish Balay for (j=0; j<n; j++) { 9499ea0dfa2SSatish Balay sum += v[jrow]*x[idx[jrow]]; jrow++; 9509ea0dfa2SSatish Balay } 95117ab2063SBarry Smith y[i] = sum; 95217ab2063SBarry Smith } 9538d195f9aSBarry Smith #endif 954b0a32e0cSBarry Smith PetscLogFlops(2*a->nz - m); 955ed480e8bSBarry Smith ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr); 956ed480e8bSBarry Smith ierr = VecRestoreArrayFast(yy,&y);CHKERRQ(ierr); 9573a40ed3dSBarry Smith PetscFunctionReturn(0); 95817ab2063SBarry Smith } 95917ab2063SBarry Smith 9604a2ae208SSatish Balay #undef __FUNCT__ 9614a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ" 96244cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 96317ab2063SBarry Smith { 964416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 965362ced78SSatish Balay PetscScalar *x,*y,*z,*v; 966273d9f13SBarry Smith int ierr,m = A->m,*idx,shift = a->indexshift,*ii; 967aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 968e36a17ebSSatish Balay int n,i,jrow,j; 969362ced78SSatish Balay PetscScalar sum; 970e36a17ebSSatish Balay #endif 9719ea0dfa2SSatish Balay 9723a40ed3dSBarry Smith PetscFunctionBegin; 973ed480e8bSBarry Smith ierr = VecGetArrayFast(xx,&x);CHKERRQ(ierr); 974ed480e8bSBarry Smith ierr = VecGetArrayFast(yy,&y);CHKERRQ(ierr); 9752e8a6d31SBarry Smith if (zz != yy) { 976ed480e8bSBarry Smith ierr = VecGetArrayFast(zz,&z);CHKERRQ(ierr); 9772e8a6d31SBarry Smith } else { 9782e8a6d31SBarry Smith z = y; 9792e8a6d31SBarry Smith } 98017ab2063SBarry Smith x = x + shift; /* shift for Fortran start by 1 indexing */ 981cddf8d76SBarry Smith idx = a->j; 982d64ed03dSBarry Smith v = a->a; 983cddf8d76SBarry Smith ii = a->i; 984aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 98529b5ca8aSSatish Balay fortranmultaddaij_(&m,x,ii,idx+shift,v+shift,y,z); 98602ab625aSSatish Balay #else 987d64ed03dSBarry Smith v += shift; /* shift for Fortran start by 1 indexing */ 988d64ed03dSBarry Smith idx += shift; 98917ab2063SBarry Smith for (i=0; i<m; i++) { 9909ea0dfa2SSatish Balay jrow = ii[i]; 9919ea0dfa2SSatish Balay n = ii[i+1] - jrow; 99217ab2063SBarry Smith sum = y[i]; 9939ea0dfa2SSatish Balay for (j=0; j<n; j++) { 9949ea0dfa2SSatish Balay sum += v[jrow]*x[idx[jrow]]; jrow++; 9959ea0dfa2SSatish Balay } 99617ab2063SBarry Smith z[i] = sum; 99717ab2063SBarry Smith } 99802ab625aSSatish Balay #endif 999b0a32e0cSBarry Smith PetscLogFlops(2*a->nz); 1000ed480e8bSBarry Smith ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr); 1001ed480e8bSBarry Smith ierr = VecRestoreArrayFast(yy,&y);CHKERRQ(ierr); 10022e8a6d31SBarry Smith if (zz != yy) { 1003ed480e8bSBarry Smith ierr = VecRestoreArrayFast(zz,&z);CHKERRQ(ierr); 10042e8a6d31SBarry Smith } 10053a40ed3dSBarry Smith PetscFunctionReturn(0); 100617ab2063SBarry Smith } 100717ab2063SBarry Smith 100817ab2063SBarry Smith /* 100917ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 101017ab2063SBarry Smith */ 10114a2ae208SSatish Balay #undef __FUNCT__ 10124a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ" 1013f1e2ffcdSBarry Smith int MatMarkDiagonal_SeqAIJ(Mat A) 101417ab2063SBarry Smith { 1015416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1016b0a32e0cSBarry Smith int i,j,*diag,m = A->m,shift = a->indexshift,ierr; 101717ab2063SBarry Smith 10183a40ed3dSBarry Smith PetscFunctionBegin; 1019f1e2ffcdSBarry Smith if (a->diag) PetscFunctionReturn(0); 1020f1e2ffcdSBarry Smith 1021b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&diag);CHKERRQ(ierr); 1022b0a32e0cSBarry Smith PetscLogObjectMemory(A,(m+1)*sizeof(int)); 1023273d9f13SBarry Smith for (i=0; i<A->m; i++) { 102435b0346bSBarry Smith diag[i] = a->i[i+1]; 1025416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 1026416022c9SBarry Smith if (a->j[j]+shift == i) { 102717ab2063SBarry Smith diag[i] = j - shift; 102817ab2063SBarry Smith break; 102917ab2063SBarry Smith } 103017ab2063SBarry Smith } 103117ab2063SBarry Smith } 1032416022c9SBarry Smith a->diag = diag; 10333a40ed3dSBarry Smith PetscFunctionReturn(0); 103417ab2063SBarry Smith } 103517ab2063SBarry Smith 1036be5855fcSBarry Smith /* 1037be5855fcSBarry Smith Checks for missing diagonals 1038be5855fcSBarry Smith */ 10394a2ae208SSatish Balay #undef __FUNCT__ 10404a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ" 1041f1e2ffcdSBarry Smith int MatMissingDiagonal_SeqAIJ(Mat A) 1042be5855fcSBarry Smith { 1043be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1044f1e2ffcdSBarry Smith int *diag,*jj = a->j,i,shift = a->indexshift,ierr; 1045be5855fcSBarry Smith 1046be5855fcSBarry Smith PetscFunctionBegin; 1047f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1048f1e2ffcdSBarry Smith diag = a->diag; 1049273d9f13SBarry Smith for (i=0; i<A->m; i++) { 1050be5855fcSBarry Smith if (jj[diag[i]+shift] != i-shift) { 105129bbc08cSBarry Smith SETERRQ1(1,"Matrix is missing diagonal number %d",i); 1052be5855fcSBarry Smith } 1053be5855fcSBarry Smith } 1054be5855fcSBarry Smith PetscFunctionReturn(0); 1055be5855fcSBarry Smith } 1056be5855fcSBarry Smith 10574a2ae208SSatish Balay #undef __FUNCT__ 10584a2ae208SSatish Balay #define __FUNCT__ "MatRelax_SeqAIJ" 1059c14dc6b6SHong Zhang int MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,int its,int lits,Vec xx) 106017ab2063SBarry Smith { 1061416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1062ed480e8bSBarry Smith PetscScalar *x,*b,*bs, d,*xs,sum,*v = a->a,*t=0,scale,*ts,*xb,*idiag=0,*mdiag; 1063ed480e8bSBarry Smith int ierr,*idx,*diag,n = A->n,m = A->m,i; 106417ab2063SBarry Smith 10653a40ed3dSBarry Smith PetscFunctionBegin; 1066b965ef7fSBarry Smith its = its*lits; 106791723122SBarry Smith if (its <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %d and local its %d both positive",its,lits); 106891723122SBarry Smith 1069ed480e8bSBarry Smith if (!a->diag) {ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);} 1070ed480e8bSBarry Smith diag = a->diag; 1071ed480e8bSBarry Smith if (!a->idiag) { 1072ed480e8bSBarry Smith ierr = PetscMalloc(3*m*sizeof(PetscScalar),&a->idiag);CHKERRQ(ierr); 1073ed480e8bSBarry Smith a->ssor = a->idiag + m; 1074ed480e8bSBarry Smith mdiag = a->ssor + m; 1075ed480e8bSBarry Smith 1076ed480e8bSBarry Smith v = a->a; 1077ed480e8bSBarry Smith 1078ed480e8bSBarry Smith /* this is wrong when fshift omega changes each iteration */ 1079ed480e8bSBarry Smith if (omega == 1.0 && fshift == 0.0) { 1080ed480e8bSBarry Smith for (i=0; i<m; i++) { 1081ed480e8bSBarry Smith mdiag[i] = v[diag[i]]; 1082ed480e8bSBarry Smith a->idiag[i] = 1.0/v[diag[i]]; 1083ed480e8bSBarry Smith } 1084ed480e8bSBarry Smith } else { 1085ed480e8bSBarry Smith for (i=0; i<m; i++) { 1086ed480e8bSBarry Smith mdiag[i] = v[diag[i]]; 1087ed480e8bSBarry Smith a->idiag[i] = omega/(fshift + v[diag[i]]);} 1088ed480e8bSBarry Smith } 1089ed480e8bSBarry Smith 1090ed480e8bSBarry Smith } 1091ed480e8bSBarry Smith t = a->ssor; 1092ed480e8bSBarry Smith idiag = a->idiag; 1093ed480e8bSBarry Smith mdiag = a->idiag + 2*m; 1094ed480e8bSBarry Smith 1095ed480e8bSBarry Smith ierr = VecGetArrayFast(xx,&x);CHKERRQ(ierr); 1096fb2e594dSBarry Smith if (xx != bb) { 1097ed480e8bSBarry Smith ierr = VecGetArrayFast(bb,&b);CHKERRQ(ierr); 1098fb2e594dSBarry Smith } else { 1099fb2e594dSBarry Smith b = x; 1100fb2e594dSBarry Smith } 1101fb2e594dSBarry Smith 1102ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 1103ed480e8bSBarry Smith xs = x; 110417ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 110517ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1106ed480e8bSBarry Smith bs = b; 110717ab2063SBarry Smith for (i=0; i<m; i++) { 1108ed480e8bSBarry Smith d = fshift + a->a[diag[i]]; 1109416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1110ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1111ed480e8bSBarry Smith v = a->a + diag[i] + 1; 111217ab2063SBarry Smith sum = b[i]*d/omega; 111317ab2063SBarry Smith SPARSEDENSEDOT(sum,bs,v,idx,n); 111417ab2063SBarry Smith x[i] = sum; 111517ab2063SBarry Smith } 1116ed480e8bSBarry Smith ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr); 1117ed480e8bSBarry Smith if (bb != xx) {ierr = VecRestoreArrayFast(bb,&b);CHKERRQ(ierr);} 1118ed480e8bSBarry Smith PetscLogFlops(a->nz); 11193a40ed3dSBarry Smith PetscFunctionReturn(0); 112017ab2063SBarry Smith } 1121c783ea89SBarry Smith 1122ed480e8bSBarry Smith 1123fc3d8934SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1124fc3d8934SBarry Smith U is upper triangular, E is diagonal; This routine applies 1125fc3d8934SBarry Smith 1126fc3d8934SBarry Smith (L + E)^{-1} A (U + E)^{-1} 1127fc3d8934SBarry Smith 1128fc3d8934SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 1129fc3d8934SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 113048af12d7SBarry Smith is the relaxation factor. 1131fc3d8934SBarry Smith */ 1132fc3d8934SBarry Smith 113348af12d7SBarry Smith if (flag == SOR_APPLY_LOWER) { 113429bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 11353a40ed3dSBarry Smith } else if (flag & SOR_EISENSTAT) { 113617ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 113717ab2063SBarry Smith U is upper triangular, E is diagonal; This routine applies 113817ab2063SBarry Smith 113917ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 114017ab2063SBarry Smith 114117ab2063SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 114217ab2063SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 114317ab2063SBarry Smith is the relaxation factor. 114417ab2063SBarry Smith */ 114517ab2063SBarry Smith scale = (2.0/omega) - 1.0; 114617ab2063SBarry Smith 114717ab2063SBarry Smith /* x = (E + U)^{-1} b */ 114817ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1149416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1150ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1151ed480e8bSBarry Smith v = a->a + diag[i] + 1; 115217ab2063SBarry Smith sum = b[i]; 115317ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1154ed480e8bSBarry Smith x[i] = sum*idiag[i]; 115517ab2063SBarry Smith } 115617ab2063SBarry Smith 115717ab2063SBarry Smith /* t = b - (2*E - D)x */ 1158416022c9SBarry Smith v = a->a; 1159ed480e8bSBarry Smith for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; } 116017ab2063SBarry Smith 116117ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1162ed480e8bSBarry Smith ts = t; 1163416022c9SBarry Smith diag = a->diag; 116417ab2063SBarry Smith for (i=0; i<m; i++) { 1165416022c9SBarry Smith n = diag[i] - a->i[i]; 1166ed480e8bSBarry Smith idx = a->j + a->i[i]; 1167ed480e8bSBarry Smith v = a->a + a->i[i]; 116817ab2063SBarry Smith sum = t[i]; 116917ab2063SBarry Smith SPARSEDENSEMDOT(sum,ts,v,idx,n); 1170ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1171733d66baSBarry Smith /* x = x + t */ 1172733d66baSBarry Smith x[i] += t[i]; 117317ab2063SBarry Smith } 117417ab2063SBarry Smith 1175b0a32e0cSBarry Smith PetscLogFlops(6*m-1 + 2*a->nz); 1176ed480e8bSBarry Smith ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr); 1177ed480e8bSBarry Smith if (bb != xx) {ierr = VecRestoreArrayFast(bb,&b);CHKERRQ(ierr);} 11783a40ed3dSBarry Smith PetscFunctionReturn(0); 117917ab2063SBarry Smith } 118017ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 118117ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 118277d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 118377d8c4bbSBarry Smith fortranrelaxaijforwardzero_(&m,&omega,x,a->i,a->j,diag,a->a,b); 118477d8c4bbSBarry Smith #else 118517ab2063SBarry Smith for (i=0; i<m; i++) { 1186416022c9SBarry Smith n = diag[i] - a->i[i]; 1187ed480e8bSBarry Smith idx = a->j + a->i[i]; 1188ed480e8bSBarry Smith v = a->a + a->i[i]; 118917ab2063SBarry Smith sum = b[i]; 119017ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1191ed480e8bSBarry Smith x[i] = sum*idiag[i]; 119217ab2063SBarry Smith } 119377d8c4bbSBarry Smith #endif 119417ab2063SBarry Smith xb = x; 1195ed480e8bSBarry Smith PetscLogFlops(a->nz); 11963a40ed3dSBarry Smith } else xb = b; 119717ab2063SBarry Smith if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) && 119817ab2063SBarry Smith (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) { 119917ab2063SBarry Smith for (i=0; i<m; i++) { 1200ed480e8bSBarry Smith x[i] *= mdiag[i]; 120117ab2063SBarry Smith } 1202b0a32e0cSBarry Smith PetscLogFlops(m); 120317ab2063SBarry Smith } 120417ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 120577d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 120677d8c4bbSBarry Smith fortranrelaxaijbackwardzero_(&m,&omega,x,a->i,a->j,diag,a->a,xb); 120777d8c4bbSBarry Smith #else 120817ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1209416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1210ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1211ed480e8bSBarry Smith v = a->a + diag[i] + 1; 121217ab2063SBarry Smith sum = xb[i]; 121317ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1214ed480e8bSBarry Smith x[i] = sum*idiag[i]; 121517ab2063SBarry Smith } 121677d8c4bbSBarry Smith #endif 1217ed480e8bSBarry Smith PetscLogFlops(a->nz); 121817ab2063SBarry Smith } 121917ab2063SBarry Smith its--; 122017ab2063SBarry Smith } 122117ab2063SBarry Smith while (its--) { 122217ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 122377d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 122477d8c4bbSBarry Smith fortranrelaxaijforward_(&m,&omega,x,a->i,a->j,diag,a->a,b); 122577d8c4bbSBarry Smith #else 122617ab2063SBarry Smith for (i=0; i<m; i++) { 1227ed480e8bSBarry Smith d = fshift + a->a[diag[i]]; 1228416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1229ed480e8bSBarry Smith idx = a->j + a->i[i]; 1230ed480e8bSBarry Smith v = a->a + a->i[i]; 123117ab2063SBarry Smith sum = b[i]; 123217ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1233ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 123417ab2063SBarry Smith } 123577d8c4bbSBarry Smith #endif 1236ed480e8bSBarry Smith PetscLogFlops(a->nz); 123717ab2063SBarry Smith } 123817ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 123977d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 124077d8c4bbSBarry Smith fortranrelaxaijbackward_(&m,&omega,x,a->i,a->j,diag,a->a,b); 124177d8c4bbSBarry Smith #else 124217ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1243ed480e8bSBarry Smith d = fshift + a->a[diag[i]]; 1244416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1245ed480e8bSBarry Smith idx = a->j + a->i[i]; 1246ed480e8bSBarry Smith v = a->a + a->i[i]; 124717ab2063SBarry Smith sum = b[i]; 124817ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1249ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 125017ab2063SBarry Smith } 125177d8c4bbSBarry Smith #endif 1252ed480e8bSBarry Smith PetscLogFlops(a->nz); 125317ab2063SBarry Smith } 125417ab2063SBarry Smith } 1255ed480e8bSBarry Smith ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr); 1256ed480e8bSBarry Smith if (bb != xx) {ierr = VecRestoreArrayFast(bb,&b);CHKERRQ(ierr);} 12573a40ed3dSBarry Smith PetscFunctionReturn(0); 125817ab2063SBarry Smith } 125917ab2063SBarry Smith 12604a2ae208SSatish Balay #undef __FUNCT__ 12614a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ" 12628f6be9afSLois Curfman McInnes int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 126317ab2063SBarry Smith { 1264416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 12654e220ebcSLois Curfman McInnes 12663a40ed3dSBarry Smith PetscFunctionBegin; 1267273d9f13SBarry Smith info->rows_global = (double)A->m; 1268273d9f13SBarry Smith info->columns_global = (double)A->n; 1269273d9f13SBarry Smith info->rows_local = (double)A->m; 1270273d9f13SBarry Smith info->columns_local = (double)A->n; 12714e220ebcSLois Curfman McInnes info->block_size = 1.0; 12724e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 12734e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 12744e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 12754e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 12764e220ebcSLois Curfman McInnes info->mallocs = (double)a->reallocs; 12774e220ebcSLois Curfman McInnes info->memory = A->mem; 12784e220ebcSLois Curfman McInnes if (A->factor) { 12794e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 12804e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 12814e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 12824e220ebcSLois Curfman McInnes } else { 12834e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 12844e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 12854e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 12864e220ebcSLois Curfman McInnes } 12873a40ed3dSBarry Smith PetscFunctionReturn(0); 128817ab2063SBarry Smith } 128917ab2063SBarry Smith 1290b380c88cSHong Zhang EXTERN int MatLUFactorSymbolic_SeqAIJ(Mat,IS,IS,MatFactorInfo*,Mat*); 1291ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqAIJ(Mat,Mat*); 1292b380c88cSHong Zhang EXTERN int MatLUFactor_SeqAIJ(Mat,IS,IS,MatFactorInfo*); 1293ca44d042SBarry Smith EXTERN int MatSolve_SeqAIJ(Mat,Vec,Vec); 1294ca44d042SBarry Smith EXTERN int MatSolveAdd_SeqAIJ(Mat,Vec,Vec,Vec); 1295ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqAIJ(Mat,Vec,Vec); 1296ca44d042SBarry Smith EXTERN int MatSolveTransposeAdd_SeqAIJ(Mat,Vec,Vec,Vec); 129717ab2063SBarry Smith 12984a2ae208SSatish Balay #undef __FUNCT__ 12994a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ" 130087828ca2SBarry Smith int MatZeroRows_SeqAIJ(Mat A,IS is,PetscScalar *diag) 130117ab2063SBarry Smith { 1302416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1303273d9f13SBarry Smith int i,ierr,N,*rows,m = A->m - 1,shift = a->indexshift; 130417ab2063SBarry Smith 13053a40ed3dSBarry Smith PetscFunctionBegin; 1306b9b97703SBarry Smith ierr = ISGetLocalSize(is,&N);CHKERRQ(ierr); 130717ab2063SBarry Smith ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 1308f1e2ffcdSBarry Smith if (a->keepzeroedrows) { 1309f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 131029bbc08cSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"row out of range"); 131187828ca2SBarry Smith ierr = PetscMemzero(&a->a[a->i[rows[i]]+shift],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 1312f1e2ffcdSBarry Smith } 1313f1e2ffcdSBarry Smith if (diag) { 1314f1e2ffcdSBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1315f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1316f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1317f1e2ffcdSBarry Smith a->a[a->diag[rows[i]]] = *diag; 1318f1e2ffcdSBarry Smith } 1319f1e2ffcdSBarry Smith } 1320f1e2ffcdSBarry Smith } else { 132117ab2063SBarry Smith if (diag) { 132217ab2063SBarry Smith for (i=0; i<N; i++) { 132329bbc08cSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"row out of range"); 13247ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1325416022c9SBarry Smith a->ilen[rows[i]] = 1; 1326416022c9SBarry Smith a->a[a->i[rows[i]]+shift] = *diag; 1327416022c9SBarry Smith a->j[a->i[rows[i]]+shift] = rows[i]+shift; 13287ae801bdSBarry Smith } else { /* in case row was completely empty */ 1329d64ed03dSBarry Smith ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr); 133017ab2063SBarry Smith } 133117ab2063SBarry Smith } 13323a40ed3dSBarry Smith } else { 133317ab2063SBarry Smith for (i=0; i<N; i++) { 133429bbc08cSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"row out of range"); 1335416022c9SBarry Smith a->ilen[rows[i]] = 0; 133617ab2063SBarry Smith } 133717ab2063SBarry Smith } 1338f1e2ffcdSBarry Smith } 13397ae801bdSBarry Smith ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 134043a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13413a40ed3dSBarry Smith PetscFunctionReturn(0); 134217ab2063SBarry Smith } 134317ab2063SBarry Smith 13444a2ae208SSatish Balay #undef __FUNCT__ 13454a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ" 134687828ca2SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v) 134717ab2063SBarry Smith { 1348416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1349b0a32e0cSBarry Smith int *itmp,i,shift = a->indexshift,ierr; 135017ab2063SBarry Smith 13513a40ed3dSBarry Smith PetscFunctionBegin; 1352273d9f13SBarry Smith if (row < 0 || row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %d out of range",row); 135317ab2063SBarry Smith 1354416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1355416022c9SBarry Smith if (v) *v = a->a + a->i[row] + shift; 135617ab2063SBarry Smith if (idx) { 1357416022c9SBarry Smith itmp = a->j + a->i[row] + shift; 13584e093b46SBarry Smith if (*nz && shift) { 1359b0a32e0cSBarry Smith ierr = PetscMalloc((*nz)*sizeof(int),idx);CHKERRQ(ierr); 136017ab2063SBarry Smith for (i=0; i<(*nz); i++) {(*idx)[i] = itmp[i] + shift;} 13614e093b46SBarry Smith } else if (*nz) { 13624e093b46SBarry Smith *idx = itmp; 136317ab2063SBarry Smith } 136417ab2063SBarry Smith else *idx = 0; 136517ab2063SBarry Smith } 13663a40ed3dSBarry Smith PetscFunctionReturn(0); 136717ab2063SBarry Smith } 136817ab2063SBarry Smith 13694a2ae208SSatish Balay #undef __FUNCT__ 13704a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ" 137187828ca2SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v) 137217ab2063SBarry Smith { 13734e093b46SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1374606d414cSSatish Balay int ierr; 13753a40ed3dSBarry Smith 13763a40ed3dSBarry Smith PetscFunctionBegin; 1377606d414cSSatish Balay if (idx) {if (*idx && a->indexshift) {ierr = PetscFree(*idx);CHKERRQ(ierr);}} 13783a40ed3dSBarry Smith PetscFunctionReturn(0); 137917ab2063SBarry Smith } 138017ab2063SBarry Smith 13814a2ae208SSatish Balay #undef __FUNCT__ 13824a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ" 1383064f8208SBarry Smith int MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 138417ab2063SBarry Smith { 1385416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 138687828ca2SBarry Smith PetscScalar *v = a->a; 138736db0b34SBarry Smith PetscReal sum = 0.0; 1388549d3d68SSatish Balay int i,j,shift = a->indexshift,ierr; 138917ab2063SBarry Smith 13903a40ed3dSBarry Smith PetscFunctionBegin; 139117ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1392416022c9SBarry Smith for (i=0; i<a->nz; i++) { 1393aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 139436db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 139517ab2063SBarry Smith #else 139617ab2063SBarry Smith sum += (*v)*(*v); v++; 139717ab2063SBarry Smith #endif 139817ab2063SBarry Smith } 1399064f8208SBarry Smith *nrm = sqrt(sum); 14003a40ed3dSBarry Smith } else if (type == NORM_1) { 140136db0b34SBarry Smith PetscReal *tmp; 1402416022c9SBarry Smith int *jj = a->j; 1403b0a32e0cSBarry Smith ierr = PetscMalloc((A->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr); 1404273d9f13SBarry Smith ierr = PetscMemzero(tmp,A->n*sizeof(PetscReal));CHKERRQ(ierr); 1405064f8208SBarry Smith *nrm = 0.0; 1406416022c9SBarry Smith for (j=0; j<a->nz; j++) { 1407a2744918SBarry Smith tmp[*jj++ + shift] += PetscAbsScalar(*v); v++; 140817ab2063SBarry Smith } 1409273d9f13SBarry Smith for (j=0; j<A->n; j++) { 1410064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 141117ab2063SBarry Smith } 1412606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 14133a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1414064f8208SBarry Smith *nrm = 0.0; 1415273d9f13SBarry Smith for (j=0; j<A->m; j++) { 1416416022c9SBarry Smith v = a->a + a->i[j] + shift; 141717ab2063SBarry Smith sum = 0.0; 1418416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 1419cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 142017ab2063SBarry Smith } 1421064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 142217ab2063SBarry Smith } 14233a40ed3dSBarry Smith } else { 142429bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"No support for two norm"); 142517ab2063SBarry Smith } 14263a40ed3dSBarry Smith PetscFunctionReturn(0); 142717ab2063SBarry Smith } 142817ab2063SBarry Smith 14294a2ae208SSatish Balay #undef __FUNCT__ 14304a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ" 14318f6be9afSLois Curfman McInnes int MatTranspose_SeqAIJ(Mat A,Mat *B) 143217ab2063SBarry Smith { 1433416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1434416022c9SBarry Smith Mat C; 1435273d9f13SBarry Smith int i,ierr,*aj = a->j,*ai = a->i,m = A->m,len,*col; 1436273d9f13SBarry Smith int shift = a->indexshift; 143787828ca2SBarry Smith PetscScalar *array = a->a; 143817ab2063SBarry Smith 14393a40ed3dSBarry Smith PetscFunctionBegin; 1440273d9f13SBarry Smith if (!B && m != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Square matrix only for in-place"); 1441b0a32e0cSBarry Smith ierr = PetscMalloc((1+A->n)*sizeof(int),&col);CHKERRQ(ierr); 1442273d9f13SBarry Smith ierr = PetscMemzero(col,(1+A->n)*sizeof(int));CHKERRQ(ierr); 144317ab2063SBarry Smith if (shift) { 144417ab2063SBarry Smith for (i=0; i<ai[m]-1; i++) aj[i] -= 1; 144517ab2063SBarry Smith } 144617ab2063SBarry Smith for (i=0; i<ai[m]+shift; i++) col[aj[i]] += 1; 1447273d9f13SBarry Smith ierr = MatCreateSeqAIJ(A->comm,A->n,m,0,col,&C);CHKERRQ(ierr); 1448606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 144917ab2063SBarry Smith for (i=0; i<m; i++) { 145017ab2063SBarry Smith len = ai[i+1]-ai[i]; 1451416022c9SBarry Smith ierr = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 1452b9b97703SBarry Smith array += len; 1453b9b97703SBarry Smith aj += len; 145417ab2063SBarry Smith } 145517ab2063SBarry Smith if (shift) { 145617ab2063SBarry Smith for (i=0; i<ai[m]-1; i++) aj[i] += 1; 145717ab2063SBarry Smith } 145817ab2063SBarry Smith 14596d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14606d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 146117ab2063SBarry Smith 1462f1e2ffcdSBarry Smith if (B) { 1463416022c9SBarry Smith *B = C; 146417ab2063SBarry Smith } else { 1465273d9f13SBarry Smith ierr = MatHeaderCopy(A,C);CHKERRQ(ierr); 146617ab2063SBarry Smith } 14673a40ed3dSBarry Smith PetscFunctionReturn(0); 146817ab2063SBarry Smith } 146917ab2063SBarry Smith 1470cd0d46ebSvictorle EXTERN_C_BEGIN 1471cd0d46ebSvictorle #undef __FUNCT__ 1472cd0d46ebSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ" 1473cd0d46ebSvictorle int MatIsSymmetric_SeqAIJ(Mat A,Mat B,PetscTruth *f) 1474cd0d46ebSvictorle { 1475cd0d46ebSvictorle Mat_SeqAIJ *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data; 1476cd0d46ebSvictorle MatType type; PetscTruth flg; 1477cd0d46ebSvictorle int *adx,*bdx,*aii,*bii,*aptr,*bptr; PetscScalar *va,*vb; 1478cd0d46ebSvictorle int ma,na,mb,nb, i,ierr; 1479cd0d46ebSvictorle 1480cd0d46ebSvictorle PetscFunctionBegin; 1481cd0d46ebSvictorle ierr = MatGetType(B,&type); CHKERRQ(ierr); 1482cd0d46ebSvictorle ierr = PetscStrcmp(type,MATSEQAIJ,&flg); CHKERRQ(ierr); 1483cd0d46ebSvictorle if (!flg) SETERRQ(1,"Second matrix needs to be SeqAIJ too"); 1484cd0d46ebSvictorle bij = (Mat_SeqAIJ *) B->data; 1485cd0d46ebSvictorle if (aij->indexshift || bij->indexshift) 1486cd0d46ebSvictorle SETERRQ(1,"Index shift not supported"); 1487cd0d46ebSvictorle 1488cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na); CHKERRQ(ierr); 1489cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb); CHKERRQ(ierr); 1490cd0d46ebSvictorle if (ma!=nb || na!=mb) 1491cd0d46ebSvictorle SETERRQ(1,"Incompatible A/B sizes for symmetry test"); 1492cd0d46ebSvictorle aii = aij->i; bii = bij->i; 1493cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 1494cd0d46ebSvictorle va = aij->a; vb = bij->a; 1495cd0d46ebSvictorle ierr = PetscMalloc(ma*sizeof(int),&aptr); CHKERRQ(ierr); 1496cd0d46ebSvictorle ierr = PetscMalloc(mb*sizeof(int),&bptr); CHKERRQ(ierr); 1497cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 1498cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 1499cd0d46ebSvictorle 1500cd0d46ebSvictorle *f = PETSC_TRUE; 1501cd0d46ebSvictorle for (i=0; i<ma; i++) { 1502cd0d46ebSvictorle /*printf("row %d spans %d--%d; we start @ %d\n", 1503cd0d46ebSvictorle i,idx[ii[i]],idx[ii[i+1]-1],idx[aptr[i]]);*/ 1504cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 1505cd0d46ebSvictorle int idc,idr; PetscScalar vc,vr; 1506cd0d46ebSvictorle /* column/row index/value */ 1507cd0d46ebSvictorle idc = adx[aptr[i]]; idr = bdx[bptr[idc]]; 1508cd0d46ebSvictorle vc = va[aptr[i]]; vr = vb[bptr[idc]]; 1509cd0d46ebSvictorle /*printf("comparing %d: (%d,%d)=%e to (%d,%d)=%e\n", 1510cd0d46ebSvictorle aptr[i],i,idc,vc,idc,idr,vr);*/ 1511cd0d46ebSvictorle if (i!=idr || vc!=vr) { 1512cd0d46ebSvictorle *f = PETSC_FALSE; goto done; 1513cd0d46ebSvictorle } else { 15143aeef889SHong Zhang aptr[i]++; if (B || i!=idc) bptr[idc]++; 1515cd0d46ebSvictorle } 1516cd0d46ebSvictorle } 1517cd0d46ebSvictorle } 1518cd0d46ebSvictorle done: 1519cd0d46ebSvictorle ierr = PetscFree(aptr); CHKERRQ(ierr); 15203aeef889SHong Zhang if (B) { 15213aeef889SHong Zhang ierr = PetscFree(bptr); CHKERRQ(ierr); 15223aeef889SHong Zhang } 1523cd0d46ebSvictorle 1524cd0d46ebSvictorle PetscFunctionReturn(0); 1525cd0d46ebSvictorle } 1526cd0d46ebSvictorle EXTERN_C_END 1527cd0d46ebSvictorle 15284a2ae208SSatish Balay #undef __FUNCT__ 15294a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ" 15308f6be9afSLois Curfman McInnes int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 153117ab2063SBarry Smith { 1532416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 153387828ca2SBarry Smith PetscScalar *l,*r,x,*v; 1534273d9f13SBarry Smith int ierr,i,j,m = A->m,n = A->n,M,nz = a->nz,*jj,shift = a->indexshift; 153517ab2063SBarry Smith 15363a40ed3dSBarry Smith PetscFunctionBegin; 153717ab2063SBarry Smith if (ll) { 15383ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 15393ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 1540e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 1541273d9f13SBarry Smith if (m != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 1542ed480e8bSBarry Smith ierr = VecGetArrayFast(ll,&l);CHKERRQ(ierr); 1543416022c9SBarry Smith v = a->a; 154417ab2063SBarry Smith for (i=0; i<m; i++) { 154517ab2063SBarry Smith x = l[i]; 1546416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 154717ab2063SBarry Smith for (j=0; j<M; j++) { (*v++) *= x;} 154817ab2063SBarry Smith } 1549ed480e8bSBarry Smith ierr = VecRestoreArrayFast(ll,&l);CHKERRQ(ierr); 1550b0a32e0cSBarry Smith PetscLogFlops(nz); 155117ab2063SBarry Smith } 155217ab2063SBarry Smith if (rr) { 1553e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 1554273d9f13SBarry Smith if (n != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 1555ed480e8bSBarry Smith ierr = VecGetArrayFast(rr,&r);CHKERRQ(ierr); 1556416022c9SBarry Smith v = a->a; jj = a->j; 155717ab2063SBarry Smith for (i=0; i<nz; i++) { 155817ab2063SBarry Smith (*v++) *= r[*jj++ + shift]; 155917ab2063SBarry Smith } 1560ed480e8bSBarry Smith ierr = VecRestoreArrayFast(rr,&r);CHKERRQ(ierr); 1561b0a32e0cSBarry Smith PetscLogFlops(nz); 156217ab2063SBarry Smith } 15633a40ed3dSBarry Smith PetscFunctionReturn(0); 156417ab2063SBarry Smith } 156517ab2063SBarry Smith 15664a2ae208SSatish Balay #undef __FUNCT__ 15674a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ" 15687b2a1423SBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatReuse scall,Mat *B) 156917ab2063SBarry Smith { 1570db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 1571273d9f13SBarry Smith int *smap,i,k,kstart,kend,ierr,oldcols = A->n,*lens; 157236db0b34SBarry Smith int row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 157399141d43SSatish Balay int *irow,*icol,nrows,ncols,shift = a->indexshift,*ssmap; 157499141d43SSatish Balay int *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 157587828ca2SBarry Smith PetscScalar *a_new,*mat_a; 1576416022c9SBarry Smith Mat C; 1577fee21e36SBarry Smith PetscTruth stride; 157817ab2063SBarry Smith 15793a40ed3dSBarry Smith PetscFunctionBegin; 1580d64ed03dSBarry Smith ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr); 158129bbc08cSBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted"); 1582d64ed03dSBarry Smith ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr); 158329bbc08cSBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted"); 158499141d43SSatish Balay 158517ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 1586b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 1587b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 158817ab2063SBarry Smith 1589fee21e36SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 1590fee21e36SBarry Smith ierr = ISStride(iscol,&stride);CHKERRQ(ierr); 1591fee21e36SBarry Smith if (stride && step == 1) { 159202834360SBarry Smith /* special case of contiguous rows */ 159331ebf83bSSatish Balay ierr = PetscMalloc((2*nrows+1)*sizeof(int),&lens);CHKERRQ(ierr); 159431ebf83bSSatish Balay starts = lens + nrows; 159502834360SBarry Smith /* loop over new rows determining lens and starting points */ 159602834360SBarry Smith for (i=0; i<nrows; i++) { 1597a2744918SBarry Smith kstart = ai[irow[i]]+shift; 1598a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 159902834360SBarry Smith for (k=kstart; k<kend; k++) { 1600d8ced48eSBarry Smith if (aj[k]+shift >= first) { 160102834360SBarry Smith starts[i] = k; 160202834360SBarry Smith break; 160302834360SBarry Smith } 160402834360SBarry Smith } 1605a2744918SBarry Smith sum = 0; 160602834360SBarry Smith while (k < kend) { 1607d8ced48eSBarry Smith if (aj[k++]+shift >= first+ncols) break; 1608a2744918SBarry Smith sum++; 160902834360SBarry Smith } 1610a2744918SBarry Smith lens[i] = sum; 161102834360SBarry Smith } 161202834360SBarry Smith /* create submatrix */ 1613cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 161408480c60SBarry Smith int n_cols,n_rows; 161508480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 161629bbc08cSBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 1617d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 161808480c60SBarry Smith C = *B; 16193a40ed3dSBarry Smith } else { 162002834360SBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 162108480c60SBarry Smith } 1622db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 1623db02288aSLois Curfman McInnes 162402834360SBarry Smith /* loop over rows inserting into submatrix */ 1625db02288aSLois Curfman McInnes a_new = c->a; 1626db02288aSLois Curfman McInnes j_new = c->j; 1627db02288aSLois Curfman McInnes i_new = c->i; 1628db02288aSLois Curfman McInnes i_new[0] = -shift; 162902834360SBarry Smith for (i=0; i<nrows; i++) { 1630a2744918SBarry Smith ii = starts[i]; 1631a2744918SBarry Smith lensi = lens[i]; 1632a2744918SBarry Smith for (k=0; k<lensi; k++) { 1633a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 163402834360SBarry Smith } 163587828ca2SBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr); 1636a2744918SBarry Smith a_new += lensi; 1637a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 1638a2744918SBarry Smith c->ilen[i] = lensi; 163902834360SBarry Smith } 1640606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 16413a40ed3dSBarry Smith } else { 164202834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 1643b0a32e0cSBarry Smith ierr = PetscMalloc((1+oldcols)*sizeof(int),&smap);CHKERRQ(ierr); 164402834360SBarry Smith ssmap = smap + shift; 1645b0a32e0cSBarry Smith ierr = PetscMalloc((1+nrows)*sizeof(int),&lens);CHKERRQ(ierr); 1646549d3d68SSatish Balay ierr = PetscMemzero(smap,oldcols*sizeof(int));CHKERRQ(ierr); 164717ab2063SBarry Smith for (i=0; i<ncols; i++) smap[icol[i]] = i+1; 164802834360SBarry Smith /* determine lens of each row */ 164902834360SBarry Smith for (i=0; i<nrows; i++) { 1650d8ced48eSBarry Smith kstart = ai[irow[i]]+shift; 165102834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 165202834360SBarry Smith lens[i] = 0; 165302834360SBarry Smith for (k=kstart; k<kend; k++) { 1654d8ced48eSBarry Smith if (ssmap[aj[k]]) { 165502834360SBarry Smith lens[i]++; 165602834360SBarry Smith } 165702834360SBarry Smith } 165802834360SBarry Smith } 165917ab2063SBarry Smith /* Create and fill new matrix */ 1660a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 16610f5bd95cSBarry Smith PetscTruth equal; 16620f5bd95cSBarry Smith 166399141d43SSatish Balay c = (Mat_SeqAIJ *)((*B)->data); 1664273d9f13SBarry Smith if ((*B)->m != nrows || (*B)->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 1665273d9f13SBarry Smith ierr = PetscMemcmp(c->ilen,lens,(*B)->m*sizeof(int),&equal);CHKERRQ(ierr); 16660f5bd95cSBarry Smith if (!equal) { 166729bbc08cSBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 166899141d43SSatish Balay } 1669273d9f13SBarry Smith ierr = PetscMemzero(c->ilen,(*B)->m*sizeof(int));CHKERRQ(ierr); 167008480c60SBarry Smith C = *B; 16713a40ed3dSBarry Smith } else { 167202834360SBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 167308480c60SBarry Smith } 167499141d43SSatish Balay c = (Mat_SeqAIJ *)(C->data); 167517ab2063SBarry Smith for (i=0; i<nrows; i++) { 167699141d43SSatish Balay row = irow[i]; 167799141d43SSatish Balay kstart = ai[row]+shift; 167899141d43SSatish Balay kend = kstart + a->ilen[row]; 167999141d43SSatish Balay mat_i = c->i[i]+shift; 168099141d43SSatish Balay mat_j = c->j + mat_i; 168199141d43SSatish Balay mat_a = c->a + mat_i; 168299141d43SSatish Balay mat_ilen = c->ilen + i; 168317ab2063SBarry Smith for (k=kstart; k<kend; k++) { 168499141d43SSatish Balay if ((tcol=ssmap[a->j[k]])) { 1685ed480e8bSBarry Smith *mat_j++ = tcol - 1; 168699141d43SSatish Balay *mat_a++ = a->a[k]; 168799141d43SSatish Balay (*mat_ilen)++; 168899141d43SSatish Balay 168917ab2063SBarry Smith } 169017ab2063SBarry Smith } 169117ab2063SBarry Smith } 169202834360SBarry Smith /* Free work space */ 169302834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 1694606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 1695606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 169602834360SBarry Smith } 16976d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16986d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 169917ab2063SBarry Smith 170017ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 1701416022c9SBarry Smith *B = C; 17023a40ed3dSBarry Smith PetscFunctionReturn(0); 170317ab2063SBarry Smith } 170417ab2063SBarry Smith 1705a871dcd8SBarry Smith /* 1706a871dcd8SBarry Smith */ 17074a2ae208SSatish Balay #undef __FUNCT__ 17084a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ" 1709b380c88cSHong Zhang int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatFactorInfo *info) 1710a871dcd8SBarry Smith { 171163b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 171208480c60SBarry Smith int ierr; 171363b91edcSBarry Smith Mat outA; 1714b8a78c4aSBarry Smith PetscTruth row_identity,col_identity; 171563b91edcSBarry Smith 17163a40ed3dSBarry Smith PetscFunctionBegin; 1717d3d32019SBarry Smith if (info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 1718b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 1719b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 1720b8a78c4aSBarry Smith if (!row_identity || !col_identity) { 172129bbc08cSBarry Smith SETERRQ(1,"Row and column permutations must be identity for in-place ILU"); 1722b8a78c4aSBarry Smith } 1723a871dcd8SBarry Smith 172463b91edcSBarry Smith outA = inA; 172563b91edcSBarry Smith inA->factor = FACTOR_LU; 172663b91edcSBarry Smith a->row = row; 172763b91edcSBarry Smith a->col = col; 1728c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1729c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 173063b91edcSBarry Smith 173136db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 1732b9b97703SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */ 17334c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 1734b0a32e0cSBarry Smith PetscLogObjectParent(inA,a->icol); 1735f0ec6fceSSatish Balay 173694a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 173787828ca2SBarry Smith ierr = PetscMalloc((inA->m+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr); 173894a9d846SBarry Smith } 173963b91edcSBarry Smith 174008480c60SBarry Smith if (!a->diag) { 1741f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 174263b91edcSBarry Smith } 174363b91edcSBarry Smith ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA);CHKERRQ(ierr); 17443a40ed3dSBarry Smith PetscFunctionReturn(0); 1745a871dcd8SBarry Smith } 1746a871dcd8SBarry Smith 1747d9eff348SSatish Balay #include "petscblaslapack.h" 17484a2ae208SSatish Balay #undef __FUNCT__ 17494a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ" 175087828ca2SBarry Smith int MatScale_SeqAIJ(PetscScalar *alpha,Mat inA) 1751f0b747eeSBarry Smith { 1752f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 1753f0b747eeSBarry Smith int one = 1; 17543a40ed3dSBarry Smith 17553a40ed3dSBarry Smith PetscFunctionBegin; 1756f0b747eeSBarry Smith BLscal_(&a->nz,alpha,a->a,&one); 1757b0a32e0cSBarry Smith PetscLogFlops(a->nz); 17583a40ed3dSBarry Smith PetscFunctionReturn(0); 1759f0b747eeSBarry Smith } 1760f0b747eeSBarry Smith 17614a2ae208SSatish Balay #undef __FUNCT__ 17624a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ" 17637b2a1423SBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n,IS *irow,IS *icol,MatReuse scall,Mat **B) 1764cddf8d76SBarry Smith { 1765cddf8d76SBarry Smith int ierr,i; 1766cddf8d76SBarry Smith 17673a40ed3dSBarry Smith PetscFunctionBegin; 1768cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 1769b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr); 1770cddf8d76SBarry Smith } 1771cddf8d76SBarry Smith 1772cddf8d76SBarry Smith for (i=0; i<n; i++) { 17736a6a5d1dSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 1774cddf8d76SBarry Smith } 17753a40ed3dSBarry Smith PetscFunctionReturn(0); 1776cddf8d76SBarry Smith } 1777cddf8d76SBarry Smith 17784a2ae208SSatish Balay #undef __FUNCT__ 17794a2ae208SSatish Balay #define __FUNCT__ "MatGetBlockSize_SeqAIJ" 17808f6be9afSLois Curfman McInnes int MatGetBlockSize_SeqAIJ(Mat A,int *bs) 17815a838052SSatish Balay { 1782f830108cSBarry Smith PetscFunctionBegin; 17835a838052SSatish Balay *bs = 1; 17843a40ed3dSBarry Smith PetscFunctionReturn(0); 17855a838052SSatish Balay } 17865a838052SSatish Balay 17874a2ae208SSatish Balay #undef __FUNCT__ 17884a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ" 17898f6be9afSLois Curfman McInnes int MatIncreaseOverlap_SeqAIJ(Mat A,int is_max,IS *is,int ov) 17904dcbc457SBarry Smith { 1791e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 179206763907SSatish Balay int shift,row,i,j,k,l,m,n,*idx,ierr,*nidx,isz,val; 17938a047759SSatish Balay int start,end,*ai,*aj; 1794f1af5d2fSBarry Smith PetscBT table; 1795bbd702dbSSatish Balay 17963a40ed3dSBarry Smith PetscFunctionBegin; 17978a047759SSatish Balay shift = a->indexshift; 1798273d9f13SBarry Smith m = A->m; 1799e4d965acSSatish Balay ai = a->i; 18008a047759SSatish Balay aj = a->j+shift; 18018a047759SSatish Balay 180229bbc08cSBarry Smith if (ov < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"illegal overlap value used"); 180306763907SSatish Balay 1804b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&nidx);CHKERRQ(ierr); 18056831982aSBarry Smith ierr = PetscBTCreate(m,table);CHKERRQ(ierr); 180606763907SSatish Balay 1807e4d965acSSatish Balay for (i=0; i<is_max; i++) { 1808b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 1809e4d965acSSatish Balay isz = 0; 18106831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 1811e4d965acSSatish Balay 1812e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 18134dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 1814b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 1815e4d965acSSatish Balay 1816dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 1817e4d965acSSatish Balay for (j=0; j<n ; ++j){ 1818f1af5d2fSBarry Smith if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];} 18194dcbc457SBarry Smith } 182006763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 182106763907SSatish Balay ierr = ISDestroy(is[i]);CHKERRQ(ierr); 1822e4d965acSSatish Balay 182304a348a9SBarry Smith k = 0; 182404a348a9SBarry Smith for (j=0; j<ov; j++){ /* for each overlap */ 182504a348a9SBarry Smith n = isz; 182606763907SSatish Balay for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */ 1827e4d965acSSatish Balay row = nidx[k]; 1828e4d965acSSatish Balay start = ai[row]; 1829e4d965acSSatish Balay end = ai[row+1]; 183004a348a9SBarry Smith for (l = start; l<end ; l++){ 18318a047759SSatish Balay val = aj[l] + shift; 1832f1af5d2fSBarry Smith if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;} 1833e4d965acSSatish Balay } 1834e4d965acSSatish Balay } 1835e4d965acSSatish Balay } 1836029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr); 1837e4d965acSSatish Balay } 18386831982aSBarry Smith ierr = PetscBTDestroy(table);CHKERRQ(ierr); 1839606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 18403a40ed3dSBarry Smith PetscFunctionReturn(0); 18414dcbc457SBarry Smith } 184217ab2063SBarry Smith 18430513a670SBarry Smith /* -------------------------------------------------------------- */ 18444a2ae208SSatish Balay #undef __FUNCT__ 18454a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ" 18460513a670SBarry Smith int MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 18470513a670SBarry Smith { 18480513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 184987828ca2SBarry Smith PetscScalar *vwork; 1850273d9f13SBarry Smith int i,ierr,nz,m = A->m,n = A->n,*cwork; 18510513a670SBarry Smith int *row,*col,*cnew,j,*lens; 185256cd22aeSBarry Smith IS icolp,irowp; 18530513a670SBarry Smith 18543a40ed3dSBarry Smith PetscFunctionBegin; 18554c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 185656cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 18574c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 185856cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 18590513a670SBarry Smith 18600513a670SBarry Smith /* determine lengths of permuted rows */ 1861b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&lens);CHKERRQ(ierr); 18620513a670SBarry Smith for (i=0; i<m; i++) { 18630513a670SBarry Smith lens[row[i]] = a->i[i+1] - a->i[i]; 18640513a670SBarry Smith } 18650513a670SBarry Smith ierr = MatCreateSeqAIJ(A->comm,m,n,0,lens,B);CHKERRQ(ierr); 1866606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 18670513a670SBarry Smith 1868b0a32e0cSBarry Smith ierr = PetscMalloc(n*sizeof(int),&cnew);CHKERRQ(ierr); 18690513a670SBarry Smith for (i=0; i<m; i++) { 18700513a670SBarry Smith ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 18710513a670SBarry Smith for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];} 18720513a670SBarry Smith ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 18730513a670SBarry Smith ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 18740513a670SBarry Smith } 1875606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 18760513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18770513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 187856cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 187956cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 188056cd22aeSBarry Smith ierr = ISDestroy(irowp);CHKERRQ(ierr); 188156cd22aeSBarry Smith ierr = ISDestroy(icolp);CHKERRQ(ierr); 18823a40ed3dSBarry Smith PetscFunctionReturn(0); 18830513a670SBarry Smith } 18840513a670SBarry Smith 18854a2ae208SSatish Balay #undef __FUNCT__ 18864a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqAIJ" 1887682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A) 1888682d7d0cSBarry Smith { 1889c38d4ed2SBarry Smith static PetscTruth called = PETSC_FALSE; 1890682d7d0cSBarry Smith MPI_Comm comm = A->comm; 1891d132466eSBarry Smith int ierr; 1892682d7d0cSBarry Smith 18933a40ed3dSBarry Smith PetscFunctionBegin; 1894c38d4ed2SBarry Smith if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE; 1895d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr); 1896d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr); 1897d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr); 1898d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_no_inode: Do not use inodes\n");CHKERRQ(ierr); 1899d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");CHKERRQ(ierr); 1900aa482453SBarry Smith #if defined(PETSC_HAVE_ESSL) 1901d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_essl: Use IBM sparse LU factorization and solve.\n");CHKERRQ(ierr); 1902682d7d0cSBarry Smith #endif 1903cd5578b5SBarry Smith #if defined(PETSC_HAVE_LUSOL) 1904cd5578b5SBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_lusol: Use the Stanford LUSOL sparse factorization and solve.\n");CHKERRQ(ierr); 1905cd5578b5SBarry Smith #endif 190687828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) 1907ca44d042SBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_matlab: Use Matlab engine sparse LU factorization and solve.\n");CHKERRQ(ierr); 1908ca44d042SBarry Smith #endif 19093a40ed3dSBarry Smith PetscFunctionReturn(0); 1910682d7d0cSBarry Smith } 1911ca44d042SBarry Smith EXTERN int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg); 1912ca44d042SBarry Smith EXTERN int MatFDColoringCreate_SeqAIJ(Mat,ISColoring,MatFDColoring); 1913b380c88cSHong Zhang EXTERN int MatILUDTFactor_SeqAIJ(Mat,MatFactorInfo*,IS,IS,Mat*); 19144a2ae208SSatish Balay #undef __FUNCT__ 19154a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ" 1916cb5b572fSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 1917cb5b572fSBarry Smith { 1918be6bf707SBarry Smith int ierr; 1919273d9f13SBarry Smith PetscTruth flg; 1920cb5b572fSBarry Smith 1921cb5b572fSBarry Smith PetscFunctionBegin; 1922273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)B,MATSEQAIJ,&flg);CHKERRQ(ierr); 1923273d9f13SBarry Smith if (str == SAME_NONZERO_PATTERN && flg) { 1924be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1925be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 1926be6bf707SBarry Smith 1927273d9f13SBarry Smith if (a->i[A->m]+a->indexshift != b->i[B->m]+a->indexshift) { 192829bbc08cSBarry Smith SETERRQ(1,"Number of nonzeros in two matrices are different"); 1929cb5b572fSBarry Smith } 193087828ca2SBarry Smith ierr = PetscMemcpy(b->a,a->a,(a->i[A->m]+a->indexshift)*sizeof(PetscScalar));CHKERRQ(ierr); 1931cb5b572fSBarry Smith } else { 1932cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1933cb5b572fSBarry Smith } 1934cb5b572fSBarry Smith PetscFunctionReturn(0); 1935cb5b572fSBarry Smith } 1936cb5b572fSBarry Smith 19374a2ae208SSatish Balay #undef __FUNCT__ 19384a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ" 1939273d9f13SBarry Smith int MatSetUpPreallocation_SeqAIJ(Mat A) 1940273d9f13SBarry Smith { 1941273d9f13SBarry Smith int ierr; 1942273d9f13SBarry Smith 1943273d9f13SBarry Smith PetscFunctionBegin; 1944273d9f13SBarry Smith ierr = MatSeqAIJSetPreallocation(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 1945273d9f13SBarry Smith PetscFunctionReturn(0); 1946273d9f13SBarry Smith } 1947273d9f13SBarry Smith 19484a2ae208SSatish Balay #undef __FUNCT__ 19494a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ" 195087828ca2SBarry Smith int MatGetArray_SeqAIJ(Mat A,PetscScalar **array) 19516c0721eeSBarry Smith { 19526c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 19536c0721eeSBarry Smith PetscFunctionBegin; 19546c0721eeSBarry Smith *array = a->a; 19556c0721eeSBarry Smith PetscFunctionReturn(0); 19566c0721eeSBarry Smith } 19576c0721eeSBarry Smith 19584a2ae208SSatish Balay #undef __FUNCT__ 19594a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ" 196087828ca2SBarry Smith int MatRestoreArray_SeqAIJ(Mat A,PetscScalar **array) 19616c0721eeSBarry Smith { 19626c0721eeSBarry Smith PetscFunctionBegin; 19636c0721eeSBarry Smith PetscFunctionReturn(0); 19646c0721eeSBarry Smith } 1965273d9f13SBarry Smith 1966ee4f033dSBarry Smith #undef __FUNCT__ 1967ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ" 1968ee4f033dSBarry Smith int MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 1969ee4f033dSBarry Smith { 1970ee4f033dSBarry Smith int (*f)(void *,Vec,Vec,void*) = (int (*)(void *,Vec,Vec,void *))coloring->f; 1971ee4f033dSBarry Smith int k,ierr,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2; 197287828ca2SBarry Smith PetscScalar dx,mone = -1.0,*y,*xx,*w3_array; 197387828ca2SBarry Smith PetscScalar *vscale_array; 1974ee4f033dSBarry Smith PetscReal epsilon = coloring->error_rel,umin = coloring->umin; 1975ee4f033dSBarry Smith Vec w1,w2,w3; 1976ee4f033dSBarry Smith void *fctx = coloring->fctx; 1977ee4f033dSBarry Smith PetscTruth flg; 1978ee4f033dSBarry Smith 1979ee4f033dSBarry Smith PetscFunctionBegin; 1980ee4f033dSBarry Smith if (!coloring->w1) { 1981ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr); 1982ee4f033dSBarry Smith PetscLogObjectParent(coloring,coloring->w1); 1983ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr); 1984ee4f033dSBarry Smith PetscLogObjectParent(coloring,coloring->w2); 1985ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr); 1986ee4f033dSBarry Smith PetscLogObjectParent(coloring,coloring->w3); 1987ee4f033dSBarry Smith } 1988ee4f033dSBarry Smith w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3; 1989ee4f033dSBarry Smith 1990ee4f033dSBarry Smith ierr = MatSetUnfactored(J);CHKERRQ(ierr); 1991e82a3eeeSBarry Smith ierr = PetscOptionsHasName(coloring->prefix,"-mat_fd_coloring_dont_rezero",&flg);CHKERRQ(ierr); 1992ee4f033dSBarry Smith if (flg) { 1993ee4f033dSBarry Smith PetscLogInfo(coloring,"MatFDColoringApply_SeqAIJ: Not calling MatZeroEntries()\n"); 1994ee4f033dSBarry Smith } else { 1995ee4f033dSBarry Smith ierr = MatZeroEntries(J);CHKERRQ(ierr); 1996ee4f033dSBarry Smith } 1997ee4f033dSBarry Smith 1998ee4f033dSBarry Smith ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr); 1999ee4f033dSBarry Smith ierr = VecGetSize(x1,&N);CHKERRQ(ierr); 2000ee4f033dSBarry Smith 2001ee4f033dSBarry Smith /* 2002ee4f033dSBarry Smith This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets 2003ee4f033dSBarry Smith coloring->F for the coarser grids from the finest 2004ee4f033dSBarry Smith */ 2005ee4f033dSBarry Smith if (coloring->F) { 2006ee4f033dSBarry Smith ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr); 2007ee4f033dSBarry Smith ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr); 2008ee4f033dSBarry Smith if (m1 != m2) { 2009ee4f033dSBarry Smith coloring->F = 0; 2010ee4f033dSBarry Smith } 2011ee4f033dSBarry Smith } 2012ee4f033dSBarry Smith 2013ee4f033dSBarry Smith if (coloring->F) { 2014ee4f033dSBarry Smith w1 = coloring->F; 2015ee4f033dSBarry Smith coloring->F = 0; 2016ee4f033dSBarry Smith } else { 201766f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2018ee4f033dSBarry Smith ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr); 201966f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2020ee4f033dSBarry Smith } 2021ee4f033dSBarry Smith 2022ee4f033dSBarry Smith /* 2023ee4f033dSBarry Smith Compute all the scale factors and share with other processors 2024ee4f033dSBarry Smith */ 2025ed480e8bSBarry Smith ierr = VecGetArrayFast(x1,&xx);CHKERRQ(ierr);xx = xx - start; 2026ed480e8bSBarry Smith ierr = VecGetArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start; 2027ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 2028ee4f033dSBarry Smith /* 2029ee4f033dSBarry Smith Loop over each column associated with color adding the 2030ee4f033dSBarry Smith perturbation to the vector w3. 2031ee4f033dSBarry Smith */ 2032ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 2033ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 2034ee4f033dSBarry Smith dx = xx[col]; 2035ee4f033dSBarry Smith if (dx == 0.0) dx = 1.0; 2036ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 2037ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 2038ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 2039ee4f033dSBarry Smith #else 2040ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2041ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2042ee4f033dSBarry Smith #endif 2043ee4f033dSBarry Smith dx *= epsilon; 2044ee4f033dSBarry Smith vscale_array[col] = 1.0/dx; 2045ee4f033dSBarry Smith } 2046ee4f033dSBarry Smith } 2047ed480e8bSBarry Smith vscale_array = vscale_array + start;ierr = VecRestoreArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2048ee4f033dSBarry Smith ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2049ee4f033dSBarry Smith ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2050ee4f033dSBarry Smith 2051ee4f033dSBarry Smith /* ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD); 2052ee4f033dSBarry Smith ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/ 2053ee4f033dSBarry Smith 2054ee4f033dSBarry Smith if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow; 2055ee4f033dSBarry Smith else vscaleforrow = coloring->columnsforrow; 2056ee4f033dSBarry Smith 2057ed480e8bSBarry Smith ierr = VecGetArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2058ee4f033dSBarry Smith /* 2059ee4f033dSBarry Smith Loop over each color 2060ee4f033dSBarry Smith */ 2061ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 206249b058dcSBarry Smith coloring->currentcolor = k; 2063ee4f033dSBarry Smith ierr = VecCopy(x1,w3);CHKERRQ(ierr); 2064ed480e8bSBarry Smith ierr = VecGetArrayFast(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start; 2065ee4f033dSBarry Smith /* 2066ee4f033dSBarry Smith Loop over each column associated with color adding the 2067ee4f033dSBarry Smith perturbation to the vector w3. 2068ee4f033dSBarry Smith */ 2069ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 2070ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 2071ee4f033dSBarry Smith dx = xx[col]; 2072ee4f033dSBarry Smith if (dx == 0.0) dx = 1.0; 2073ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 2074ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 2075ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 2076ee4f033dSBarry Smith #else 2077ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2078ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2079ee4f033dSBarry Smith #endif 2080ee4f033dSBarry Smith dx *= epsilon; 2081ee4f033dSBarry Smith if (!PetscAbsScalar(dx)) SETERRQ(1,"Computed 0 differencing parameter"); 2082ee4f033dSBarry Smith w3_array[col] += dx; 2083ee4f033dSBarry Smith } 2084ed480e8bSBarry Smith w3_array = w3_array + start; ierr = VecRestoreArrayFast(w3,&w3_array);CHKERRQ(ierr); 2085ee4f033dSBarry Smith 2086ee4f033dSBarry Smith /* 2087ee4f033dSBarry Smith Evaluate function at x1 + dx (here dx is a vector of perturbations) 2088ee4f033dSBarry Smith */ 2089ee4f033dSBarry Smith 209066f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2091ee4f033dSBarry Smith ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr); 209266f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2093ee4f033dSBarry Smith ierr = VecAXPY(&mone,w1,w2);CHKERRQ(ierr); 2094ee4f033dSBarry Smith 2095ee4f033dSBarry Smith /* 2096ee4f033dSBarry Smith Loop over rows of vector, putting results into Jacobian matrix 2097ee4f033dSBarry Smith */ 2098ed480e8bSBarry Smith ierr = VecGetArrayFast(w2,&y);CHKERRQ(ierr); 2099ee4f033dSBarry Smith for (l=0; l<coloring->nrows[k]; l++) { 2100ee4f033dSBarry Smith row = coloring->rows[k][l]; 2101ee4f033dSBarry Smith col = coloring->columnsforrow[k][l]; 2102ee4f033dSBarry Smith y[row] *= vscale_array[vscaleforrow[k][l]]; 2103ee4f033dSBarry Smith srow = row + start; 2104ee4f033dSBarry Smith ierr = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr); 2105ee4f033dSBarry Smith } 2106ed480e8bSBarry Smith ierr = VecRestoreArrayFast(w2,&y);CHKERRQ(ierr); 2107ee4f033dSBarry Smith } 210849b058dcSBarry Smith coloring->currentcolor = k; 2109ed480e8bSBarry Smith ierr = VecRestoreArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2110ed480e8bSBarry Smith xx = xx + start; ierr = VecRestoreArrayFast(x1,&xx);CHKERRQ(ierr); 2111ee4f033dSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2112ee4f033dSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2113ee4f033dSBarry Smith PetscFunctionReturn(0); 2114ee4f033dSBarry Smith } 2115ee4f033dSBarry Smith 2116ac90fabeSBarry Smith #include "petscblaslapack.h" 2117ac90fabeSBarry Smith #undef __FUNCT__ 2118ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ" 2119ac90fabeSBarry Smith int MatAXPY_SeqAIJ(PetscScalar *a,Mat X,Mat Y,MatStructure str) 2120ac90fabeSBarry Smith { 2121c537a176SHong Zhang int ierr,one=1,i; 2122ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data; 2123ac90fabeSBarry Smith 2124ac90fabeSBarry Smith PetscFunctionBegin; 2125ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 2126ac90fabeSBarry Smith BLaxpy_(&x->nz,a,x->a,&one,y->a,&one); 2127c537a176SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 2128a30b2313SHong Zhang if (y->xtoy && y->XtoY != X) { 2129a30b2313SHong Zhang ierr = PetscFree(y->xtoy);CHKERRQ(ierr); 2130a30b2313SHong Zhang ierr = MatDestroy(y->XtoY);CHKERRQ(ierr); 2131a30b2313SHong Zhang } 2132a30b2313SHong Zhang if (!y->xtoy) { /* get xtoy */ 213324f910e3SHong Zhang ierr = MatAXPYGetxtoy_Private(X->m,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr); 2134a30b2313SHong Zhang y->XtoY = X; 2135c537a176SHong Zhang } 2136a30b2313SHong Zhang for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += (*a)*(x->a[i]); 2137e2dd4fc4Svictorle PetscLogInfo(0,"MatAXPY_SeqAIJ: ratio of nnz(X)/nnz(Y): %d/%d = %g\n",x->nz,y->nz,(PetscReal)(x->nz)/y->nz); 2138ac90fabeSBarry Smith } else { 2139ac90fabeSBarry Smith ierr = MatAXPY_Basic(a,X,Y,str);CHKERRQ(ierr); 2140ac90fabeSBarry Smith } 2141ac90fabeSBarry Smith PetscFunctionReturn(0); 2142ac90fabeSBarry Smith } 2143ac90fabeSBarry Smith 2144682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 21450a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ, 2146cb5b572fSBarry Smith MatGetRow_SeqAIJ, 2147cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 2148cb5b572fSBarry Smith MatMult_SeqAIJ, 2149cb5b572fSBarry Smith MatMultAdd_SeqAIJ, 21507c922b88SBarry Smith MatMultTranspose_SeqAIJ, 21517c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 2152cb5b572fSBarry Smith MatSolve_SeqAIJ, 2153cb5b572fSBarry Smith MatSolveAdd_SeqAIJ, 21547c922b88SBarry Smith MatSolveTranspose_SeqAIJ, 21557c922b88SBarry Smith MatSolveTransposeAdd_SeqAIJ, 2156cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 2157cb5b572fSBarry Smith 0, 215817ab2063SBarry Smith MatRelax_SeqAIJ, 215917ab2063SBarry Smith MatTranspose_SeqAIJ, 2160cb5b572fSBarry Smith MatGetInfo_SeqAIJ, 2161cb5b572fSBarry Smith MatEqual_SeqAIJ, 2162cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 2163cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 2164cb5b572fSBarry Smith MatNorm_SeqAIJ, 2165cb5b572fSBarry Smith 0, 2166cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 216717ab2063SBarry Smith MatCompress_SeqAIJ, 2168cb5b572fSBarry Smith MatSetOption_SeqAIJ, 2169cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 2170cb5b572fSBarry Smith MatZeroRows_SeqAIJ, 2171cb5b572fSBarry Smith MatLUFactorSymbolic_SeqAIJ, 2172cb5b572fSBarry Smith MatLUFactorNumeric_SeqAIJ, 2173f76d2b81SHong Zhang MatCholeskyFactorSymbolic_SeqAIJ, 2174a6175056SHong Zhang MatCholeskyFactorNumeric_SeqAIJ, 2175273d9f13SBarry Smith MatSetUpPreallocation_SeqAIJ, 2176cb5b572fSBarry Smith MatILUFactorSymbolic_SeqAIJ, 2177861ba921SHong Zhang MatICCFactorSymbolic_SeqAIJ, 21786c0721eeSBarry Smith MatGetArray_SeqAIJ, 21796c0721eeSBarry Smith MatRestoreArray_SeqAIJ, 2180be6bf707SBarry Smith MatDuplicate_SeqAIJ, 2181cb5b572fSBarry Smith 0, 2182cb5b572fSBarry Smith 0, 2183cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 2184cb5b572fSBarry Smith 0, 2185ac90fabeSBarry Smith MatAXPY_SeqAIJ, 2186cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 2187cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 2188cb5b572fSBarry Smith MatGetValues_SeqAIJ, 2189cb5b572fSBarry Smith MatCopy_SeqAIJ, 2190f0b747eeSBarry Smith MatPrintHelp_SeqAIJ, 2191cb5b572fSBarry Smith MatScale_SeqAIJ, 2192cb5b572fSBarry Smith 0, 2193cb5b572fSBarry Smith 0, 21946945ee14SBarry Smith MatILUDTFactor_SeqAIJ, 21956945ee14SBarry Smith MatGetBlockSize_SeqAIJ, 21963b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 21973b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 21983b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 2199a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 2200a93ec695SBarry Smith MatFDColoringCreate_SeqAIJ, 2201b9617806SBarry Smith 0, 22020513a670SBarry Smith 0, 2203cda55fadSBarry Smith MatPermute_SeqAIJ, 2204cda55fadSBarry Smith 0, 2205cda55fadSBarry Smith 0, 2206b9b97703SBarry Smith MatDestroy_SeqAIJ, 2207b9b97703SBarry Smith MatView_SeqAIJ, 22088a124369SBarry Smith MatGetPetscMaps_Petsc, 2209ee4f033dSBarry Smith 0, 2210ee4f033dSBarry Smith 0, 2211ee4f033dSBarry Smith 0, 2212ee4f033dSBarry Smith 0, 2213ee4f033dSBarry Smith 0, 2214ee4f033dSBarry Smith 0, 2215ee4f033dSBarry Smith 0, 2216ee4f033dSBarry Smith 0, 2217ee4f033dSBarry Smith MatSetColoring_SeqAIJ, 2218ee4f033dSBarry Smith MatSetValuesAdic_SeqAIJ, 2219ee4f033dSBarry Smith MatSetValuesAdifor_SeqAIJ, 2220ee4f033dSBarry Smith MatFDColoringApply_SeqAIJ}; 222117ab2063SBarry Smith 2222fb2e594dSBarry Smith EXTERN_C_BEGIN 22234a2ae208SSatish Balay #undef __FUNCT__ 22244a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ" 222515091d37SBarry Smith 2226bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices) 2227bef8e0ddSBarry Smith { 2228bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2229bef8e0ddSBarry Smith int i,nz,n; 2230bef8e0ddSBarry Smith 2231bef8e0ddSBarry Smith PetscFunctionBegin; 2232bef8e0ddSBarry Smith 2233bef8e0ddSBarry Smith nz = aij->maxnz; 2234273d9f13SBarry Smith n = mat->n; 2235bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 2236bef8e0ddSBarry Smith aij->j[i] = indices[i]; 2237bef8e0ddSBarry Smith } 2238bef8e0ddSBarry Smith aij->nz = nz; 2239bef8e0ddSBarry Smith for (i=0; i<n; i++) { 2240bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 2241bef8e0ddSBarry Smith } 2242bef8e0ddSBarry Smith 2243bef8e0ddSBarry Smith PetscFunctionReturn(0); 2244bef8e0ddSBarry Smith } 2245fb2e594dSBarry Smith EXTERN_C_END 2246bef8e0ddSBarry Smith 22474a2ae208SSatish Balay #undef __FUNCT__ 22484a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices" 2249bef8e0ddSBarry Smith /*@ 2250bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 2251bef8e0ddSBarry Smith in the matrix. 2252bef8e0ddSBarry Smith 2253bef8e0ddSBarry Smith Input Parameters: 2254bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 2255bef8e0ddSBarry Smith - indices - the column indices 2256bef8e0ddSBarry Smith 225715091d37SBarry Smith Level: advanced 225815091d37SBarry Smith 2259bef8e0ddSBarry Smith Notes: 2260bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 2261bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 2262bef8e0ddSBarry Smith of the MatSetValues() operation. 2263bef8e0ddSBarry Smith 2264bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 2265bef8e0ddSBarry Smith MatCreateSeqAIJ(). 2266bef8e0ddSBarry Smith 2267bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 2268bef8e0ddSBarry Smith 2269b9617806SBarry Smith The indices should start with zero, not one. 2270b9617806SBarry Smith 2271bef8e0ddSBarry Smith @*/ 2272bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices) 2273bef8e0ddSBarry Smith { 2274bef8e0ddSBarry Smith int ierr,(*f)(Mat,int *); 2275bef8e0ddSBarry Smith 2276bef8e0ddSBarry Smith PetscFunctionBegin; 2277bef8e0ddSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 2278c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr); 2279bef8e0ddSBarry Smith if (f) { 2280bef8e0ddSBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 2281bef8e0ddSBarry Smith } else { 228229bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to set column indices"); 2283bef8e0ddSBarry Smith } 2284bef8e0ddSBarry Smith PetscFunctionReturn(0); 2285bef8e0ddSBarry Smith } 2286bef8e0ddSBarry Smith 2287be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 2288be6bf707SBarry Smith 2289fb2e594dSBarry Smith EXTERN_C_BEGIN 22904a2ae208SSatish Balay #undef __FUNCT__ 22914a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ" 2292be6bf707SBarry Smith int MatStoreValues_SeqAIJ(Mat mat) 2293be6bf707SBarry Smith { 2294be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2295a7ed9263SMatthew Knepley size_t nz = aij->i[mat->m]+aij->indexshift,ierr; 2296be6bf707SBarry Smith 2297be6bf707SBarry Smith PetscFunctionBegin; 2298be6bf707SBarry Smith if (aij->nonew != 1) { 229929bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2300be6bf707SBarry Smith } 2301be6bf707SBarry Smith 2302be6bf707SBarry Smith /* allocate space for values if not already there */ 2303be6bf707SBarry Smith if (!aij->saved_values) { 230487828ca2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr); 2305be6bf707SBarry Smith } 2306be6bf707SBarry Smith 2307be6bf707SBarry Smith /* copy values over */ 230887828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 2309be6bf707SBarry Smith PetscFunctionReturn(0); 2310be6bf707SBarry Smith } 2311fb2e594dSBarry Smith EXTERN_C_END 2312be6bf707SBarry Smith 23134a2ae208SSatish Balay #undef __FUNCT__ 2314b9617806SBarry Smith #define __FUNCT__ "MatStoreValues" 2315be6bf707SBarry Smith /*@ 2316be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 2317be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2318be6bf707SBarry Smith nonlinear portion. 2319be6bf707SBarry Smith 2320be6bf707SBarry Smith Collect on Mat 2321be6bf707SBarry Smith 2322be6bf707SBarry Smith Input Parameters: 2323be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2324be6bf707SBarry Smith 232515091d37SBarry Smith Level: advanced 232615091d37SBarry Smith 2327be6bf707SBarry Smith Common Usage, with SNESSolve(): 2328be6bf707SBarry Smith $ Create Jacobian matrix 2329be6bf707SBarry Smith $ Set linear terms into matrix 2330be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 2331be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 2332be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 2333be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2334be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2335be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 2336be6bf707SBarry Smith $ In your Jacobian routine 2337be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2338be6bf707SBarry Smith $ Set nonlinear terms in matrix 2339be6bf707SBarry Smith 2340be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 2341be6bf707SBarry Smith $ // build linear portion of Jacobian 2342be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2343be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2344be6bf707SBarry Smith $ loop over nonlinear iterations 2345be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2346be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 2347be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 2348be6bf707SBarry Smith $ Solve linear system with Jacobian 2349be6bf707SBarry Smith $ endloop 2350be6bf707SBarry Smith 2351be6bf707SBarry Smith Notes: 2352be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 2353be6bf707SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before 2354be6bf707SBarry Smith calling this routine. 2355be6bf707SBarry Smith 2356be6bf707SBarry Smith .seealso: MatRetrieveValues() 2357be6bf707SBarry Smith 2358be6bf707SBarry Smith @*/ 2359be6bf707SBarry Smith int MatStoreValues(Mat mat) 2360be6bf707SBarry Smith { 2361be6bf707SBarry Smith int ierr,(*f)(Mat); 2362be6bf707SBarry Smith 2363be6bf707SBarry Smith PetscFunctionBegin; 2364be6bf707SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 236529bbc08cSBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 236629bbc08cSBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2367be6bf707SBarry Smith 2368c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void (**)(void))&f);CHKERRQ(ierr); 2369be6bf707SBarry Smith if (f) { 2370be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2371be6bf707SBarry Smith } else { 237229bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to store values"); 2373be6bf707SBarry Smith } 2374be6bf707SBarry Smith PetscFunctionReturn(0); 2375be6bf707SBarry Smith } 2376be6bf707SBarry Smith 2377fb2e594dSBarry Smith EXTERN_C_BEGIN 23784a2ae208SSatish Balay #undef __FUNCT__ 23794a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ" 2380be6bf707SBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat) 2381be6bf707SBarry Smith { 2382be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2383273d9f13SBarry Smith int nz = aij->i[mat->m]+aij->indexshift,ierr; 2384be6bf707SBarry Smith 2385be6bf707SBarry Smith PetscFunctionBegin; 2386be6bf707SBarry Smith if (aij->nonew != 1) { 238729bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2388be6bf707SBarry Smith } 2389be6bf707SBarry Smith if (!aij->saved_values) { 239029bbc08cSBarry Smith SETERRQ(1,"Must call MatStoreValues(A);first"); 2391be6bf707SBarry Smith } 2392be6bf707SBarry Smith 2393be6bf707SBarry Smith /* copy values over */ 239487828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 2395be6bf707SBarry Smith PetscFunctionReturn(0); 2396be6bf707SBarry Smith } 2397fb2e594dSBarry Smith EXTERN_C_END 2398be6bf707SBarry Smith 23994a2ae208SSatish Balay #undef __FUNCT__ 24004a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues" 2401be6bf707SBarry Smith /*@ 2402be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 2403be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2404be6bf707SBarry Smith nonlinear portion. 2405be6bf707SBarry Smith 2406be6bf707SBarry Smith Collect on Mat 2407be6bf707SBarry Smith 2408be6bf707SBarry Smith Input Parameters: 2409be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2410be6bf707SBarry Smith 241115091d37SBarry Smith Level: advanced 241215091d37SBarry Smith 2413be6bf707SBarry Smith .seealso: MatStoreValues() 2414be6bf707SBarry Smith 2415be6bf707SBarry Smith @*/ 2416be6bf707SBarry Smith int MatRetrieveValues(Mat mat) 2417be6bf707SBarry Smith { 2418be6bf707SBarry Smith int ierr,(*f)(Mat); 2419be6bf707SBarry Smith 2420be6bf707SBarry Smith PetscFunctionBegin; 2421be6bf707SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 242229bbc08cSBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 242329bbc08cSBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2424be6bf707SBarry Smith 2425c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void (**)(void))&f);CHKERRQ(ierr); 2426be6bf707SBarry Smith if (f) { 2427be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2428be6bf707SBarry Smith } else { 242929bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to retrieve values"); 2430be6bf707SBarry Smith } 2431be6bf707SBarry Smith PetscFunctionReturn(0); 2432be6bf707SBarry Smith } 2433be6bf707SBarry Smith 2434f83d6046SBarry Smith /* 2435f83d6046SBarry Smith This allows SeqAIJ matrices to be passed to the matlab engine 2436f83d6046SBarry Smith */ 243787828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) 2438f83d6046SBarry Smith #include "engine.h" /* Matlab include file */ 2439f83d6046SBarry Smith #include "mex.h" /* Matlab include file */ 2440f83d6046SBarry Smith EXTERN_C_BEGIN 24414a2ae208SSatish Balay #undef __FUNCT__ 24424a2ae208SSatish Balay #define __FUNCT__ "MatMatlabEnginePut_SeqAIJ" 244362aa7f4eSBarry Smith int MatMatlabEnginePut_SeqAIJ(PetscObject obj,void *mengine) 2444f83d6046SBarry Smith { 24454a4478b9SSatish Balay int ierr,i,*ai,*aj; 2446f83d6046SBarry Smith Mat B = (Mat)obj; 2447f83d6046SBarry Smith mxArray *mat; 2448d79a51d8SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)B->data; 2449d79a51d8SBarry Smith 2450f83d6046SBarry Smith PetscFunctionBegin; 245101820c62SBarry Smith mat = mxCreateSparse(B->n,B->m,aij->nz,mxREAL); 245287828ca2SBarry Smith ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 2453d79a51d8SBarry Smith /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 245466826eb6SBarry Smith ierr = PetscMemcpy(mxGetIr(mat),aij->j,aij->nz*sizeof(int));CHKERRQ(ierr); 245566826eb6SBarry Smith ierr = PetscMemcpy(mxGetJc(mat),aij->i,(B->m+1)*sizeof(int));CHKERRQ(ierr); 2456f83d6046SBarry Smith 245701820c62SBarry Smith /* Matlab indices start at 0 for sparse (what a surprise) */ 245801820c62SBarry Smith if (aij->indexshift) { 2459a1c0a87aSBarry Smith ai = mxGetJc(mat); 246001820c62SBarry Smith for (i=0; i<B->m+1; i++) { 246101820c62SBarry Smith ai[i]--; 2462d79a51d8SBarry Smith } 2463a1c0a87aSBarry Smith aj = mxGetIr(mat); 2464d79a51d8SBarry Smith for (i=0; i<aij->nz; i++) { 246501820c62SBarry Smith aj[i]--; 2466d79a51d8SBarry Smith } 2467d79a51d8SBarry Smith } 2468ca44d042SBarry Smith ierr = PetscObjectName(obj);CHKERRQ(ierr); 2469f83d6046SBarry Smith mxSetName(mat,obj->name); 247062aa7f4eSBarry Smith engPutArray((Engine *)mengine,mat); 2471f83d6046SBarry Smith PetscFunctionReturn(0); 2472f83d6046SBarry Smith } 2473f83d6046SBarry Smith EXTERN_C_END 247466826eb6SBarry Smith 247566826eb6SBarry Smith EXTERN_C_BEGIN 24764a2ae208SSatish Balay #undef __FUNCT__ 24774a2ae208SSatish Balay #define __FUNCT__ "MatMatlabEngineGet_SeqAIJ" 247862aa7f4eSBarry Smith int MatMatlabEngineGet_SeqAIJ(PetscObject obj,void *mengine) 247966826eb6SBarry Smith { 248066826eb6SBarry Smith int ierr,ii; 248166826eb6SBarry Smith Mat mat = (Mat)obj; 248266826eb6SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 248366826eb6SBarry Smith mxArray *mmat; 248466826eb6SBarry Smith 24856c0721eeSBarry Smith PetscFunctionBegin; 248666826eb6SBarry Smith ierr = PetscFree(aij->a);CHKERRQ(ierr); 248766826eb6SBarry Smith aij->indexshift = 0; 248866826eb6SBarry Smith 248962aa7f4eSBarry Smith mmat = engGetArray((Engine *)mengine,obj->name); 249066826eb6SBarry Smith 2491a65776f3SBarry Smith aij->nz = (mxGetJc(mmat))[mat->m]; 2492a7ed9263SMatthew Knepley ierr = PetscMalloc(((size_t) aij->nz)*(sizeof(int)+sizeof(PetscScalar))+(mat->m+1)*sizeof(int),&aij->a);CHKERRQ(ierr); 249366826eb6SBarry Smith aij->j = (int*)(aij->a + aij->nz); 249466826eb6SBarry Smith aij->i = aij->j + aij->nz; 249566826eb6SBarry Smith aij->singlemalloc = PETSC_TRUE; 249666826eb6SBarry Smith aij->freedata = PETSC_TRUE; 249766826eb6SBarry Smith 249887828ca2SBarry Smith ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 249966826eb6SBarry Smith /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 250066826eb6SBarry Smith ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr); 250166826eb6SBarry Smith ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->m+1)*sizeof(int));CHKERRQ(ierr); 250266826eb6SBarry Smith 250366826eb6SBarry Smith for (ii=0; ii<mat->m; ii++) { 250466826eb6SBarry Smith aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii]; 250566826eb6SBarry Smith } 250666826eb6SBarry Smith 250766826eb6SBarry Smith ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 250866826eb6SBarry Smith ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 250966826eb6SBarry Smith 251066826eb6SBarry Smith PetscFunctionReturn(0); 251166826eb6SBarry Smith } 251266826eb6SBarry Smith EXTERN_C_END 2513f83d6046SBarry Smith #endif 2514f83d6046SBarry Smith 2515be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 25164a2ae208SSatish Balay #undef __FUNCT__ 25174a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ" 251817ab2063SBarry Smith /*@C 2519682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 25200d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 25216e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 252251c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 25232bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 252417ab2063SBarry Smith 2525db81eaa0SLois Curfman McInnes Collective on MPI_Comm 2526db81eaa0SLois Curfman McInnes 252717ab2063SBarry Smith Input Parameters: 2528db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 252917ab2063SBarry Smith . m - number of rows 253017ab2063SBarry Smith . n - number of columns 253117ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 253251c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 25332bd5e0b2SLois Curfman McInnes (possibly different for each row) or PETSC_NULL 253417ab2063SBarry Smith 253517ab2063SBarry Smith Output Parameter: 2536416022c9SBarry Smith . A - the matrix 253717ab2063SBarry Smith 2538b259b22eSLois Curfman McInnes Notes: 253917ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 254017ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 25410002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 254244cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 254317ab2063SBarry Smith 254417ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2545a40aa06bSLois Curfman McInnes Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 25463d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 25476da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 254817ab2063SBarry Smith 2549682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 25504fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 2551682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 25526c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 25536c7ebb05SLois Curfman McInnes 25546c7ebb05SLois Curfman McInnes Options Database Keys: 2555db81eaa0SLois Curfman McInnes + -mat_aij_no_inode - Do not use inodes 2556db81eaa0SLois Curfman McInnes . -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5) 2557db81eaa0SLois Curfman McInnes - -mat_aij_oneindex - Internally use indexing starting at 1 2558db81eaa0SLois Curfman McInnes rather than 0. Note that when calling MatSetValues(), 2559db81eaa0SLois Curfman McInnes the user still MUST index entries starting at 0! 256017ab2063SBarry Smith 2561027ccd11SLois Curfman McInnes Level: intermediate 2562027ccd11SLois Curfman McInnes 256336db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 256436db0b34SBarry Smith 256517ab2063SBarry Smith @*/ 2566416022c9SBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,int *nnz,Mat *A) 256717ab2063SBarry Smith { 2568273d9f13SBarry Smith int ierr; 25696945ee14SBarry Smith 25703a40ed3dSBarry Smith PetscFunctionBegin; 2571273d9f13SBarry Smith ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr); 2572273d9f13SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 2573273d9f13SBarry Smith ierr = MatSeqAIJSetPreallocation(*A,nz,nnz);CHKERRQ(ierr); 2574273d9f13SBarry Smith PetscFunctionReturn(0); 2575273d9f13SBarry Smith } 2576273d9f13SBarry Smith 25775da197adSKris Buschelman #define SKIP_ALLOCATION -4 25785da197adSKris Buschelman 25794a2ae208SSatish Balay #undef __FUNCT__ 25804a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation" 2581273d9f13SBarry Smith /*@C 2582273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 2583273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 2584273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 2585273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 2586273d9f13SBarry Smith 2587273d9f13SBarry Smith Collective on MPI_Comm 2588273d9f13SBarry Smith 2589273d9f13SBarry Smith Input Parameters: 2590273d9f13SBarry Smith + comm - MPI communicator, set to PETSC_COMM_SELF 2591273d9f13SBarry Smith . m - number of rows 2592273d9f13SBarry Smith . n - number of columns 2593273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 2594273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 2595273d9f13SBarry Smith (possibly different for each row) or PETSC_NULL 2596273d9f13SBarry Smith 2597273d9f13SBarry Smith Output Parameter: 2598273d9f13SBarry Smith . A - the matrix 2599273d9f13SBarry Smith 2600273d9f13SBarry Smith Notes: 2601273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 2602273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 2603273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 2604273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 2605273d9f13SBarry Smith 2606273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2607273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 2608273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 2609273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 2610273d9f13SBarry Smith 2611273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 2612273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 2613273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 2614273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 2615273d9f13SBarry Smith 2616273d9f13SBarry Smith Options Database Keys: 2617273d9f13SBarry Smith + -mat_aij_no_inode - Do not use inodes 2618273d9f13SBarry Smith . -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5) 2619273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 2620273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 2621273d9f13SBarry Smith the user still MUST index entries starting at 0! 2622273d9f13SBarry Smith 2623273d9f13SBarry Smith Level: intermediate 2624273d9f13SBarry Smith 2625273d9f13SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 2626273d9f13SBarry Smith 2627273d9f13SBarry Smith @*/ 2628273d9f13SBarry Smith int MatSeqAIJSetPreallocation(Mat B,int nz,int *nnz) 2629273d9f13SBarry Smith { 2630273d9f13SBarry Smith Mat_SeqAIJ *b; 2631a7ed9263SMatthew Knepley size_t len = 0; 2632c461c341SBarry Smith PetscTruth flg2,skipallocation = PETSC_FALSE; 2633a7ed9263SMatthew Knepley int i,ierr; 2634273d9f13SBarry Smith 2635273d9f13SBarry Smith PetscFunctionBegin; 2636273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)B,MATSEQAIJ,&flg2);CHKERRQ(ierr); 2637273d9f13SBarry Smith if (!flg2) PetscFunctionReturn(0); 2638d5d45c9bSBarry Smith 2639c461c341SBarry Smith if (nz == SKIP_ALLOCATION) { 2640c461c341SBarry Smith skipallocation = PETSC_TRUE; 2641c461c341SBarry Smith nz = 0; 2642c461c341SBarry Smith } 2643c461c341SBarry Smith 2644435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 2645435da068SBarry Smith if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 2646b73539f3SBarry Smith if (nnz) { 2647273d9f13SBarry Smith for (i=0; i<B->m; i++) { 264829bbc08cSBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 26493a7fca6bSBarry Smith if (nnz[i] > B->n) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than row length: local row %d value %d rowlength %d",i,nnz[i],B->n); 2650b73539f3SBarry Smith } 2651b73539f3SBarry Smith } 2652b73539f3SBarry Smith 2653273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 2654273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 2655273d9f13SBarry Smith 2656b0a32e0cSBarry Smith ierr = PetscMalloc((B->m+1)*sizeof(int),&b->imax);CHKERRQ(ierr); 2657273d9f13SBarry Smith if (!nnz) { 2658435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 2659273d9f13SBarry Smith else if (nz <= 0) nz = 1; 2660273d9f13SBarry Smith for (i=0; i<B->m; i++) b->imax[i] = nz; 2661273d9f13SBarry Smith nz = nz*B->m; 2662273d9f13SBarry Smith } else { 2663273d9f13SBarry Smith nz = 0; 2664273d9f13SBarry Smith for (i=0; i<B->m; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 2665273d9f13SBarry Smith } 2666273d9f13SBarry Smith 2667c461c341SBarry Smith if (!skipallocation) { 2668273d9f13SBarry Smith /* allocate the matrix space */ 2669a7ed9263SMatthew Knepley len = ((size_t) nz)*(sizeof(int) + sizeof(PetscScalar)) + (B->m+1)*sizeof(int); 2670b0a32e0cSBarry Smith ierr = PetscMalloc(len,&b->a);CHKERRQ(ierr); 2671273d9f13SBarry Smith b->j = (int*)(b->a + nz); 2672273d9f13SBarry Smith ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr); 2673273d9f13SBarry Smith b->i = b->j + nz; 26745da197adSKris Buschelman b->i[0] = -b->indexshift; 26755da197adSKris Buschelman for (i=1; i<B->m+1; i++) { 26765da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 26775da197adSKris Buschelman } 2678273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 2679273d9f13SBarry Smith b->freedata = PETSC_TRUE; 2680c461c341SBarry Smith } else { 2681c461c341SBarry Smith b->freedata = PETSC_FALSE; 2682c461c341SBarry Smith } 2683273d9f13SBarry Smith 2684273d9f13SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 2685b0a32e0cSBarry Smith ierr = PetscMalloc((B->m+1)*sizeof(int),&b->ilen);CHKERRQ(ierr); 2686b0a32e0cSBarry Smith PetscLogObjectMemory(B,len+2*(B->m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2687273d9f13SBarry Smith for (i=0; i<B->m; i++) { b->ilen[i] = 0;} 2688273d9f13SBarry Smith 2689273d9f13SBarry Smith b->nz = 0; 2690273d9f13SBarry Smith b->maxnz = nz; 2691273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 2692273d9f13SBarry Smith PetscFunctionReturn(0); 2693273d9f13SBarry Smith } 2694273d9f13SBarry Smith 2695eb9c0419SKris Buschelman EXTERN int RegisterApplyPtAPRoutines_Private(Mat); 2696eb9c0419SKris Buschelman 2697273d9f13SBarry Smith EXTERN_C_BEGIN 2698a6175056SHong Zhang extern int MatConvert_SeqAIJ_SeqSBAIJ(Mat,MatType,Mat*); 269985fc7724SBarry Smith extern int MatConvert_SeqAIJ_SeqBAIJ(Mat,MatType,Mat*); 2700a6175056SHong Zhang EXTERN_C_END 2701a6175056SHong Zhang 2702a6175056SHong Zhang EXTERN_C_BEGIN 27034a2ae208SSatish Balay #undef __FUNCT__ 27044a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ" 2705273d9f13SBarry Smith int MatCreate_SeqAIJ(Mat B) 2706273d9f13SBarry Smith { 2707273d9f13SBarry Smith Mat_SeqAIJ *b; 2708273d9f13SBarry Smith int ierr,size; 2709273d9f13SBarry Smith PetscTruth flg; 2710273d9f13SBarry Smith 2711273d9f13SBarry Smith PetscFunctionBegin; 2712273d9f13SBarry Smith ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr); 2713273d9f13SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 2714273d9f13SBarry Smith 2715273d9f13SBarry Smith B->m = B->M = PetscMax(B->m,B->M); 2716273d9f13SBarry Smith B->n = B->N = PetscMax(B->n,B->N); 2717273d9f13SBarry Smith 2718b0a32e0cSBarry Smith ierr = PetscNew(Mat_SeqAIJ,&b);CHKERRQ(ierr); 2719b0a32e0cSBarry Smith B->data = (void*)b; 2720549d3d68SSatish Balay ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr); 2721549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 2722416022c9SBarry Smith B->factor = 0; 2723416022c9SBarry Smith B->lupivotthreshold = 1.0; 272490f02eecSBarry Smith B->mapping = 0; 2725e82a3eeeSBarry Smith ierr = PetscOptionsGetReal(B->prefix,"-mat_lu_pivotthreshold",&B->lupivotthreshold,PETSC_NULL);CHKERRQ(ierr); 2726e82a3eeeSBarry Smith ierr = PetscOptionsHasName(B->prefix,"-pc_ilu_preserve_row_sums",&b->ilu_preserve_row_sums);CHKERRQ(ierr); 2727416022c9SBarry Smith b->row = 0; 2728416022c9SBarry Smith b->col = 0; 272982bf6240SBarry Smith b->icol = 0; 2730416022c9SBarry Smith b->indexshift = 0; 2731b810aeb4SBarry Smith b->reallocs = 0; 2732e82a3eeeSBarry Smith ierr = PetscOptionsHasName(B->prefix,"-mat_aij_oneindex",&flg);CHKERRQ(ierr); 273369957df2SSatish Balay if (flg) b->indexshift = -1; 273417ab2063SBarry Smith 27358a124369SBarry Smith ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr); 27368a124369SBarry Smith ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr); 2737a5ae1ecdSBarry Smith 2738f1e2ffcdSBarry Smith b->sorted = PETSC_FALSE; 273936db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 2740f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 2741416022c9SBarry Smith b->nonew = 0; 2742416022c9SBarry Smith b->diag = 0; 2743416022c9SBarry Smith b->solve_work = 0; 27442a1b7f2aSHong Zhang B->spptr = 0; 2745b65db4caSBarry Smith b->inode.use = PETSC_TRUE; 2746754ec7b1SSatish Balay b->inode.node_count = 0; 2747754ec7b1SSatish Balay b->inode.size = 0; 27486c7ebb05SLois Curfman McInnes b->inode.limit = 5; 27496c7ebb05SLois Curfman McInnes b->inode.max_limit = 5; 2750be6bf707SBarry Smith b->saved_values = 0; 2751d7f994e1SBarry Smith b->idiag = 0; 2752d7f994e1SBarry Smith b->ssor = 0; 2753f1e2ffcdSBarry Smith b->keepzeroedrows = PETSC_FALSE; 2754a30b2313SHong Zhang b->xtoy = 0; 2755a30b2313SHong Zhang b->XtoY = 0; 275617ab2063SBarry Smith 275735d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 275835d8aa7fSBarry Smith 2759aa482453SBarry Smith #if defined(PETSC_HAVE_SUPERLU) 2760e82a3eeeSBarry Smith ierr = PetscOptionsHasName(B->prefix,"-mat_aij_superlu",&flg);CHKERRQ(ierr); 276169957df2SSatish Balay if (flg) { ierr = MatUseSuperLU_SeqAIJ(B);CHKERRQ(ierr); } 27624b14c69eSBarry Smith #endif 2763564e58d6SHong Zhang 2764e82a3eeeSBarry Smith ierr = PetscOptionsHasName(B->prefix,"-mat_aij_essl",&flg);CHKERRQ(ierr); 276569957df2SSatish Balay if (flg) { ierr = MatUseEssl_SeqAIJ(B);CHKERRQ(ierr); } 2766e82a3eeeSBarry Smith ierr = PetscOptionsHasName(B->prefix,"-mat_aij_lusol",&flg);CHKERRQ(ierr); 2767cd5578b5SBarry Smith if (flg) { ierr = MatUseLUSOL_SeqAIJ(B);CHKERRQ(ierr); } 2768e82a3eeeSBarry Smith ierr = PetscOptionsHasName(B->prefix,"-mat_aij_matlab",&flg);CHKERRQ(ierr); 2769ca44d042SBarry Smith if (flg) {ierr = MatUseMatlab_SeqAIJ(B);CHKERRQ(ierr);} 2770e82a3eeeSBarry Smith ierr = PetscOptionsHasName(B->prefix,"-mat_aij_dxml",&flg);CHKERRQ(ierr); 277169957df2SSatish Balay if (flg) { 277229bbc08cSBarry Smith if (!b->indexshift) SETERRQ(PETSC_ERR_LIB,"need -mat_aij_oneindex with -mat_aij_dxml"); 2773416022c9SBarry Smith ierr = MatUseDXML_SeqAIJ(B);CHKERRQ(ierr); 277417ab2063SBarry Smith } 2775f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C", 2776bef8e0ddSBarry Smith "MatSeqAIJSetColumnIndices_SeqAIJ", 2777bc4b532fSSatish Balay MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 2778f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 2779be6bf707SBarry Smith "MatStoreValues_SeqAIJ", 2780bc4b532fSSatish Balay MatStoreValues_SeqAIJ);CHKERRQ(ierr); 2781f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 2782be6bf707SBarry Smith "MatRetrieveValues_SeqAIJ", 2783bc4b532fSSatish Balay MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 2784a6175056SHong Zhang ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C", 2785a6175056SHong Zhang "MatConvert_SeqAIJ_SeqSBAIJ", 2786a6175056SHong Zhang MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 278785fc7724SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C", 278885fc7724SBarry Smith "MatConvert_SeqAIJ_SeqBAIJ", 278985fc7724SBarry Smith MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 2790cd0d46ebSvictorle ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsSymmetric_C", 2791cd0d46ebSvictorle "MatIsSymmetric_SeqAIJ", 2792cd0d46ebSvictorle MatIsSymmetric_SeqAIJ);CHKERRQ(ierr); 279387828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) 2794f83d6046SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatMatlabEnginePut_SeqAIJ",MatMatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 279566826eb6SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatMatlabEngineGet_SeqAIJ",MatMatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 2796f83d6046SBarry Smith #endif 2797eb9c0419SKris Buschelman ierr = RegisterApplyPtAPRoutines_Private(B);CHKERRQ(ierr); 27983a40ed3dSBarry Smith PetscFunctionReturn(0); 279917ab2063SBarry Smith } 2800273d9f13SBarry Smith EXTERN_C_END 280117ab2063SBarry Smith 28024a2ae208SSatish Balay #undef __FUNCT__ 28034a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqAIJ" 2804be6bf707SBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 280517ab2063SBarry Smith { 2806416022c9SBarry Smith Mat C; 2807416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 2808a7ed9263SMatthew Knepley int i,m = A->m,shift = a->indexshift,ierr; 2809a7ed9263SMatthew Knepley size_t len; 281017ab2063SBarry Smith 28113a40ed3dSBarry Smith PetscFunctionBegin; 28124043dd9cSLois Curfman McInnes *B = 0; 2813273d9f13SBarry Smith ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr); 2814273d9f13SBarry Smith ierr = MatSetType(C,MATSEQAIJ);CHKERRQ(ierr); 2815273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 2816273d9f13SBarry Smith 2817416022c9SBarry Smith C->factor = A->factor; 2818416022c9SBarry Smith c->row = 0; 2819416022c9SBarry Smith c->col = 0; 282082bf6240SBarry Smith c->icol = 0; 2821416022c9SBarry Smith c->indexshift = shift; 2822f1e2ffcdSBarry Smith c->keepzeroedrows = a->keepzeroedrows; 2823c456f294SBarry Smith C->assembled = PETSC_TRUE; 282417ab2063SBarry Smith 2825273d9f13SBarry Smith C->M = A->m; 2826273d9f13SBarry Smith C->N = A->n; 282717ab2063SBarry Smith 2828b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&c->imax);CHKERRQ(ierr); 2829b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&c->ilen);CHKERRQ(ierr); 283017ab2063SBarry Smith for (i=0; i<m; i++) { 2831416022c9SBarry Smith c->imax[i] = a->imax[i]; 2832416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 283317ab2063SBarry Smith } 283417ab2063SBarry Smith 283517ab2063SBarry Smith /* allocate the matrix space */ 2836f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 2837a7ed9263SMatthew Knepley len = ((size_t) (m+1))*sizeof(int)+(a->i[m])*(sizeof(PetscScalar)+sizeof(int)); 2838b0a32e0cSBarry Smith ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr); 2839416022c9SBarry Smith c->j = (int*)(c->a + a->i[m] + shift); 2840416022c9SBarry Smith c->i = c->j + a->i[m] + shift; 2841549d3d68SSatish Balay ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));CHKERRQ(ierr); 284217ab2063SBarry Smith if (m > 0) { 2843549d3d68SSatish Balay ierr = PetscMemcpy(c->j,a->j,(a->i[m]+shift)*sizeof(int));CHKERRQ(ierr); 2844be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 284587828ca2SBarry Smith ierr = PetscMemcpy(c->a,a->a,(a->i[m]+shift)*sizeof(PetscScalar));CHKERRQ(ierr); 2846be6bf707SBarry Smith } else { 284787828ca2SBarry Smith ierr = PetscMemzero(c->a,(a->i[m]+shift)*sizeof(PetscScalar));CHKERRQ(ierr); 284817ab2063SBarry Smith } 284908480c60SBarry Smith } 285017ab2063SBarry Smith 2851b0a32e0cSBarry Smith PetscLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2852416022c9SBarry Smith c->sorted = a->sorted; 2853416022c9SBarry Smith c->roworiented = a->roworiented; 2854416022c9SBarry Smith c->nonew = a->nonew; 28557a743949SBarry Smith c->ilu_preserve_row_sums = a->ilu_preserve_row_sums; 2856be6bf707SBarry Smith c->saved_values = 0; 2857d7f994e1SBarry Smith c->idiag = 0; 2858d7f994e1SBarry Smith c->ssor = 0; 285936db0b34SBarry Smith c->ignorezeroentries = a->ignorezeroentries; 286036db0b34SBarry Smith c->freedata = PETSC_TRUE; 286117ab2063SBarry Smith 2862416022c9SBarry Smith if (a->diag) { 2863b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&c->diag);CHKERRQ(ierr); 2864b0a32e0cSBarry Smith PetscLogObjectMemory(C,(m+1)*sizeof(int)); 286517ab2063SBarry Smith for (i=0; i<m; i++) { 2866416022c9SBarry Smith c->diag[i] = a->diag[i]; 286717ab2063SBarry Smith } 28683a40ed3dSBarry Smith } else c->diag = 0; 2869b65db4caSBarry Smith c->inode.use = a->inode.use; 28706c7ebb05SLois Curfman McInnes c->inode.limit = a->inode.limit; 28716c7ebb05SLois Curfman McInnes c->inode.max_limit = a->inode.max_limit; 2872754ec7b1SSatish Balay if (a->inode.size){ 2873b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&c->inode.size);CHKERRQ(ierr); 2874754ec7b1SSatish Balay c->inode.node_count = a->inode.node_count; 2875549d3d68SSatish Balay ierr = PetscMemcpy(c->inode.size,a->inode.size,(m+1)*sizeof(int));CHKERRQ(ierr); 2876754ec7b1SSatish Balay } else { 2877754ec7b1SSatish Balay c->inode.size = 0; 2878754ec7b1SSatish Balay c->inode.node_count = 0; 2879754ec7b1SSatish Balay } 2880416022c9SBarry Smith c->nz = a->nz; 2881416022c9SBarry Smith c->maxnz = a->maxnz; 2882416022c9SBarry Smith c->solve_work = 0; 28832a1b7f2aSHong Zhang C->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 2884273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 2885754ec7b1SSatish Balay 2886416022c9SBarry Smith *B = C; 2887b0a32e0cSBarry Smith ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 28883a40ed3dSBarry Smith PetscFunctionReturn(0); 288917ab2063SBarry Smith } 289017ab2063SBarry Smith 2891273d9f13SBarry Smith EXTERN_C_BEGIN 28924a2ae208SSatish Balay #undef __FUNCT__ 28934a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ" 2894b0a32e0cSBarry Smith int MatLoad_SeqAIJ(PetscViewer viewer,MatType type,Mat *A) 289517ab2063SBarry Smith { 2896416022c9SBarry Smith Mat_SeqAIJ *a; 2897416022c9SBarry Smith Mat B; 289817699dbbSLois Curfman McInnes int i,nz,ierr,fd,header[4],size,*rowlengths = 0,M,N,shift; 2899bcd2baecSBarry Smith MPI_Comm comm; 2900eee76cafSHong Zhang #if defined(PETSC_HAVE_SPOOLES) || defined(PETSC_HAVE_SUPERLU) || defined(PETSC_HAVE_SUPERLUDIST) || defined(PETSC_HAVE_UMFPACK) || defined(PETSC_HAVE_MUMPS) 290127fa2452SHong Zhang PetscTruth flag; 290227fa2452SHong Zhang #endif 290317ab2063SBarry Smith 29043a40ed3dSBarry Smith PetscFunctionBegin; 2905e864ced6SBarry Smith ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 2906d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 290729bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,"view must have one processor"); 2908b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 29090752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 2910552e946dSBarry Smith if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 291117ab2063SBarry Smith M = header[1]; N = header[2]; nz = header[3]; 291217ab2063SBarry Smith 2913d64ed03dSBarry Smith if (nz < 0) { 291429bbc08cSBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 2915d64ed03dSBarry Smith } 2916d64ed03dSBarry Smith 291717ab2063SBarry Smith /* read in row lengths */ 2918b0a32e0cSBarry Smith ierr = PetscMalloc(M*sizeof(int),&rowlengths);CHKERRQ(ierr); 29190752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 292017ab2063SBarry Smith 292117ab2063SBarry Smith /* create our matrix */ 2922416022c9SBarry Smith ierr = MatCreateSeqAIJ(comm,M,N,0,rowlengths,A);CHKERRQ(ierr); 2923416022c9SBarry Smith B = *A; 2924416022c9SBarry Smith a = (Mat_SeqAIJ*)B->data; 2925416022c9SBarry Smith shift = a->indexshift; 292617ab2063SBarry Smith 292717ab2063SBarry Smith /* read in column indices and adjust for Fortran indexing*/ 29280752156aSBarry Smith ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 292917ab2063SBarry Smith if (shift) { 293017ab2063SBarry Smith for (i=0; i<nz; i++) { 2931416022c9SBarry Smith a->j[i] += 1; 293217ab2063SBarry Smith } 293317ab2063SBarry Smith } 293417ab2063SBarry Smith 293517ab2063SBarry Smith /* read in nonzero values */ 29360752156aSBarry Smith ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 293717ab2063SBarry Smith 293817ab2063SBarry Smith /* set matrix "i" values */ 2939416022c9SBarry Smith a->i[0] = -shift; 294017ab2063SBarry Smith for (i=1; i<= M; i++) { 2941416022c9SBarry Smith a->i[i] = a->i[i-1] + rowlengths[i-1]; 2942416022c9SBarry Smith a->ilen[i-1] = rowlengths[i-1]; 294317ab2063SBarry Smith } 2944606d414cSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 294517ab2063SBarry Smith 29466d4a8577SBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 29476d4a8577SBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 294827fa2452SHong Zhang #if defined(PETSC_HAVE_SPOOLES) 294927fa2452SHong Zhang ierr = PetscOptionsHasName(B->prefix,"-mat_aij_spooles",&flag);CHKERRQ(ierr); 295027fa2452SHong Zhang if (flag) { ierr = MatUseSpooles_SeqAIJ(B);CHKERRQ(ierr); } 295127fa2452SHong Zhang #endif 295227fa2452SHong Zhang #if defined(PETSC_HAVE_SUPERLU) 295327fa2452SHong Zhang ierr = PetscOptionsHasName(B->prefix,"-mat_aij_superlu",&flag);CHKERRQ(ierr); 295427fa2452SHong Zhang if (flag) { ierr = MatUseSuperLU_SeqAIJ(B);CHKERRQ(ierr); } 295527fa2452SHong Zhang #endif 295627fa2452SHong Zhang #if defined(PETSC_HAVE_SUPERLUDIST) 295727fa2452SHong Zhang ierr = PetscOptionsHasName(B->prefix,"-mat_aij_superlu_dist",&flag);CHKERRQ(ierr); 295827fa2452SHong Zhang if (flag) { ierr = MatUseSuperLU_DIST_MPIAIJ(B);CHKERRQ(ierr); } 295927fa2452SHong Zhang #endif 296027fa2452SHong Zhang #if defined(PETSC_HAVE_UMFPACK) 296127fa2452SHong Zhang ierr = PetscOptionsHasName(B->prefix,"-mat_aij_umfpack",&flag);CHKERRQ(ierr); 296227fa2452SHong Zhang if (flag) { ierr = MatUseUMFPACK_SeqAIJ(B);CHKERRQ(ierr); } 296327fa2452SHong Zhang #endif 2964eee76cafSHong Zhang #if defined(PETSC_HAVE_MUMPS) 2965eee76cafSHong Zhang ierr = PetscOptionsHasName(B->prefix,"-mat_aij_mumps",&flag);CHKERRQ(ierr); 2966eee76cafSHong Zhang if (flag) { ierr = MatUseMUMPS_MPIAIJ(B);CHKERRQ(ierr); } 2967eee76cafSHong Zhang #endif 29683a40ed3dSBarry Smith PetscFunctionReturn(0); 296917ab2063SBarry Smith } 2970273d9f13SBarry Smith EXTERN_C_END 297117ab2063SBarry Smith 29724a2ae208SSatish Balay #undef __FUNCT__ 2973b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ" 29748f6be9afSLois Curfman McInnes int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg) 29757264ac53SSatish Balay { 29767264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data; 29770f5bd95cSBarry Smith int ierr; 2978273d9f13SBarry Smith PetscTruth flag; 29797264ac53SSatish Balay 29803a40ed3dSBarry Smith PetscFunctionBegin; 2981273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)B,MATSEQAIJ,&flag);CHKERRQ(ierr); 2982273d9f13SBarry Smith if (!flag) SETERRQ(PETSC_ERR_ARG_INCOMP,"Matrices must be same type"); 29837264ac53SSatish Balay 29847264ac53SSatish Balay /* If the matrix dimensions are not equal,or no of nonzeros or shift */ 2985273d9f13SBarry Smith if ((A->m != B->m) || (A->n != B->n) ||(a->nz != b->nz)|| (a->indexshift != b->indexshift)) { 2986ca44d042SBarry Smith *flg = PETSC_FALSE; 2987ca44d042SBarry Smith PetscFunctionReturn(0); 2988bcd2baecSBarry Smith } 29897264ac53SSatish Balay 29907264ac53SSatish Balay /* if the a->i are the same */ 2991273d9f13SBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->m+1)*sizeof(int),flg);CHKERRQ(ierr); 29920f5bd95cSBarry Smith if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 29937264ac53SSatish Balay 29947264ac53SSatish Balay /* if a->j are the same */ 29950f5bd95cSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(int),flg);CHKERRQ(ierr); 29960f5bd95cSBarry Smith if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 2997bcd2baecSBarry Smith 2998bcd2baecSBarry Smith /* if a->a are the same */ 299987828ca2SBarry Smith ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 30000f5bd95cSBarry Smith 30013a40ed3dSBarry Smith PetscFunctionReturn(0); 30027264ac53SSatish Balay 30037264ac53SSatish Balay } 300436db0b34SBarry Smith 30054a2ae208SSatish Balay #undef __FUNCT__ 30064a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays" 300736db0b34SBarry Smith /*@C 300836db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 300936db0b34SBarry Smith provided by the user. 301036db0b34SBarry Smith 301136db0b34SBarry Smith Coolective on MPI_Comm 301236db0b34SBarry Smith 301336db0b34SBarry Smith Input Parameters: 301436db0b34SBarry Smith + comm - must be an MPI communicator of size 1 301536db0b34SBarry Smith . m - number of rows 301636db0b34SBarry Smith . n - number of columns 301736db0b34SBarry Smith . i - row indices 301836db0b34SBarry Smith . j - column indices 301936db0b34SBarry Smith - a - matrix values 302036db0b34SBarry Smith 302136db0b34SBarry Smith Output Parameter: 302236db0b34SBarry Smith . mat - the matrix 302336db0b34SBarry Smith 302436db0b34SBarry Smith Level: intermediate 302536db0b34SBarry Smith 302636db0b34SBarry Smith Notes: 30270551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 302836db0b34SBarry Smith once the matrix is destroyed 302936db0b34SBarry Smith 303036db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 303136db0b34SBarry Smith 303236db0b34SBarry Smith The i and j indices can be either 0- or 1 based 303336db0b34SBarry Smith 303436db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ() 303536db0b34SBarry Smith 303636db0b34SBarry Smith @*/ 303787828ca2SBarry Smith int MatCreateSeqAIJWithArrays(MPI_Comm comm,int m,int n,int* i,int*j,PetscScalar *a,Mat *mat) 303836db0b34SBarry Smith { 303936db0b34SBarry Smith int ierr,ii; 304036db0b34SBarry Smith Mat_SeqAIJ *aij; 304136db0b34SBarry Smith 304236db0b34SBarry Smith PetscFunctionBegin; 3043c461c341SBarry Smith ierr = MatCreateSeqAIJ(comm,m,n,SKIP_ALLOCATION,0,mat);CHKERRQ(ierr); 304436db0b34SBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 304536db0b34SBarry Smith 304636db0b34SBarry Smith if (i[0] == 1) { 304736db0b34SBarry Smith aij->indexshift = -1; 304836db0b34SBarry Smith } else if (i[0]) { 304929bbc08cSBarry Smith SETERRQ(1,"i (row indices) do not start with 0 or 1"); 305036db0b34SBarry Smith } 305136db0b34SBarry Smith aij->i = i; 305236db0b34SBarry Smith aij->j = j; 305336db0b34SBarry Smith aij->a = a; 305436db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 305536db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 305636db0b34SBarry Smith aij->freedata = PETSC_FALSE; 305736db0b34SBarry Smith 305836db0b34SBarry Smith for (ii=0; ii<m; ii++) { 305936db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 30609860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g) 306129bbc08cSBarry Smith if (i[ii+1] - i[ii] < 0) SETERRQ2(1,"Negative row length in i (row indices) row = %d length = %d",ii,i[ii+1] - i[ii]); 306236db0b34SBarry Smith #endif 306336db0b34SBarry Smith } 30649860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g) 306536db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 306629bbc08cSBarry Smith if (j[ii] < -aij->indexshift) SETERRQ2(1,"Negative column index at location = %d index = %d",ii,j[ii]); 306729bbc08cSBarry Smith if (j[ii] > n - 1 -aij->indexshift) SETERRQ2(1,"Column index to large at location = %d index = %d",ii,j[ii]); 306836db0b34SBarry Smith } 306936db0b34SBarry Smith #endif 307036db0b34SBarry Smith 3071b65db4caSBarry Smith /* changes indices to start at 0 */ 3072b65db4caSBarry Smith if (i[0]) { 3073b65db4caSBarry Smith aij->indexshift = 0; 3074b65db4caSBarry Smith for (ii=0; ii<m; ii++) { 3075b65db4caSBarry Smith i[ii]--; 3076b65db4caSBarry Smith } 3077b65db4caSBarry Smith for (ii=0; ii<i[m]; ii++) { 3078b65db4caSBarry Smith j[ii]--; 3079b65db4caSBarry Smith } 3080b65db4caSBarry Smith } 3081b65db4caSBarry Smith 3082b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3083b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 308436db0b34SBarry Smith PetscFunctionReturn(0); 308536db0b34SBarry Smith } 308636db0b34SBarry Smith 3087cc8ba8e1SBarry Smith #undef __FUNCT__ 3088ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ" 3089ee4f033dSBarry Smith int MatSetColoring_SeqAIJ(Mat A,ISColoring coloring) 3090cc8ba8e1SBarry Smith { 3091cc8ba8e1SBarry Smith int ierr; 3092cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 309336db0b34SBarry Smith 3094cc8ba8e1SBarry Smith PetscFunctionBegin; 309512c595b3SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 3096cc8ba8e1SBarry Smith ierr = ISColoringReference(coloring);CHKERRQ(ierr); 3097cc8ba8e1SBarry Smith a->coloring = coloring; 309812c595b3SBarry Smith } else if (coloring->ctype == IS_COLORING_GHOSTED) { 309908b6dcc0SBarry Smith int i,*larray; 310012c595b3SBarry Smith ISColoring ocoloring; 310108b6dcc0SBarry Smith ISColoringValue *colors; 310212c595b3SBarry Smith 310312c595b3SBarry Smith /* set coloring for diagonal portion */ 310412c595b3SBarry Smith ierr = PetscMalloc((A->n+1)*sizeof(int),&larray);CHKERRQ(ierr); 310512c595b3SBarry Smith for (i=0; i<A->n; i++) { 310612c595b3SBarry Smith larray[i] = i; 310712c595b3SBarry Smith } 310812c595b3SBarry Smith ierr = ISGlobalToLocalMappingApply(A->mapping,IS_GTOLM_MASK,A->n,larray,PETSC_NULL,larray);CHKERRQ(ierr); 310908b6dcc0SBarry Smith ierr = PetscMalloc((A->n+1)*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); 311012c595b3SBarry Smith for (i=0; i<A->n; i++) { 311112c595b3SBarry Smith colors[i] = coloring->colors[larray[i]]; 311212c595b3SBarry Smith } 311312c595b3SBarry Smith ierr = PetscFree(larray);CHKERRQ(ierr); 311412c595b3SBarry Smith ierr = ISColoringCreate(PETSC_COMM_SELF,A->n,colors,&ocoloring);CHKERRQ(ierr); 311512c595b3SBarry Smith a->coloring = ocoloring; 311612c595b3SBarry Smith } 3117cc8ba8e1SBarry Smith PetscFunctionReturn(0); 3118cc8ba8e1SBarry Smith } 3119cc8ba8e1SBarry Smith 312087828ca2SBarry Smith #if defined(PETSC_HAVE_ADIC) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) 3121ee4f033dSBarry Smith EXTERN_C_BEGIN 312229c1e371SBarry Smith #include "adic/ad_utils.h" 3123ee4f033dSBarry Smith EXTERN_C_END 3124cc8ba8e1SBarry Smith 3125cc8ba8e1SBarry Smith #undef __FUNCT__ 3126ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ" 3127ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues) 3128cc8ba8e1SBarry Smith { 3129cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 313008b6dcc0SBarry Smith int m = A->m,*ii = a->i,*jj = a->j,nz,i,j,nlen; 31314440f671SBarry Smith PetscScalar *v = a->a,*values = ((PetscScalar*)advalues)+1; 313208b6dcc0SBarry Smith ISColoringValue *color; 3133cc8ba8e1SBarry Smith 3134cc8ba8e1SBarry Smith PetscFunctionBegin; 3135cc8ba8e1SBarry Smith if (!a->coloring) SETERRQ(1,"Coloring not set for matrix"); 31364440f671SBarry Smith nlen = PetscADGetDerivTypeSize()/sizeof(PetscScalar); 3137cc8ba8e1SBarry Smith color = a->coloring->colors; 3138cc8ba8e1SBarry Smith /* loop over rows */ 3139cc8ba8e1SBarry Smith for (i=0; i<m; i++) { 3140cc8ba8e1SBarry Smith nz = ii[i+1] - ii[i]; 3141cc8ba8e1SBarry Smith /* loop over columns putting computed value into matrix */ 3142cc8ba8e1SBarry Smith for (j=0; j<nz; j++) { 3143cc8ba8e1SBarry Smith *v++ = values[color[*jj++]]; 3144cc8ba8e1SBarry Smith } 31454440f671SBarry Smith values += nlen; /* jump to next row of derivatives */ 3146ee4f033dSBarry Smith } 3147ee4f033dSBarry Smith PetscFunctionReturn(0); 3148ee4f033dSBarry Smith } 3149ee4f033dSBarry Smith 3150ee4f033dSBarry Smith #else 3151ee4f033dSBarry Smith 3152ee4f033dSBarry Smith #undef __FUNCT__ 3153ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ" 3154ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues) 3155ee4f033dSBarry Smith { 3156ee4f033dSBarry Smith PetscFunctionBegin; 3157ee4f033dSBarry Smith SETERRQ(1,"PETSc installed without ADIC"); 3158ee4f033dSBarry Smith } 3159ee4f033dSBarry Smith 3160ee4f033dSBarry Smith #endif 3161ee4f033dSBarry Smith 3162ee4f033dSBarry Smith #undef __FUNCT__ 3163ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ" 3164ee4f033dSBarry Smith int MatSetValuesAdifor_SeqAIJ(Mat A,int nl,void *advalues) 3165ee4f033dSBarry Smith { 3166ee4f033dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 316708b6dcc0SBarry Smith int m = A->m,*ii = a->i,*jj = a->j,nz,i,j; 316887828ca2SBarry Smith PetscScalar *v = a->a,*values = (PetscScalar *)advalues; 316908b6dcc0SBarry Smith ISColoringValue *color; 3170ee4f033dSBarry Smith 3171ee4f033dSBarry Smith PetscFunctionBegin; 3172ee4f033dSBarry Smith if (!a->coloring) SETERRQ(1,"Coloring not set for matrix"); 3173ee4f033dSBarry Smith color = a->coloring->colors; 3174ee4f033dSBarry Smith /* loop over rows */ 3175ee4f033dSBarry Smith for (i=0; i<m; i++) { 3176ee4f033dSBarry Smith nz = ii[i+1] - ii[i]; 3177ee4f033dSBarry Smith /* loop over columns putting computed value into matrix */ 3178ee4f033dSBarry Smith for (j=0; j<nz; j++) { 3179ee4f033dSBarry Smith *v++ = values[color[*jj++]]; 3180ee4f033dSBarry Smith } 3181ee4f033dSBarry Smith values += nl; /* jump to next row of derivatives */ 3182cc8ba8e1SBarry Smith } 3183cc8ba8e1SBarry Smith PetscFunctionReturn(0); 3184cc8ba8e1SBarry Smith } 318536db0b34SBarry Smith 3186