1b3cc6726SBarry Smith 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/inline/spops.h" 98d195f9aSBarry Smith #include "src/inline/dot.h" 100a835dfdSSatish Balay #include "petscbt.h" 1117ab2063SBarry Smith 124a2ae208SSatish Balay #undef __FUNCT__ 134a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ" 1497f1f81fSBarry Smith PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscInt *m,PetscInt *ia[],PetscInt *ja[],PetscTruth *done) 1517ab2063SBarry Smith { 16416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17dfbe8321SBarry Smith PetscErrorCode ierr; 1897f1f81fSBarry Smith PetscInt i,ishift; 1917ab2063SBarry Smith 203a40ed3dSBarry Smith PetscFunctionBegin; 2131625ec5SSatish Balay *m = A->m; 223a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 23bfeeae90SHong Zhang ishift = 0; 2453e63a63SBarry Smith if (symmetric && !A->structurally_symmetric) { 25273d9f13SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr); 26bfeeae90SHong Zhang } else if (oshift == 1) { 2797f1f81fSBarry Smith PetscInt nz = a->i[A->m]; 283b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 2997f1f81fSBarry Smith ierr = PetscMalloc((A->m+1)*sizeof(PetscInt),ia);CHKERRQ(ierr); 3097f1f81fSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscInt),ja);CHKERRQ(ierr); 313b2fbd54SBarry Smith for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1; 32273d9f13SBarry Smith for (i=0; i<A->m+1; i++) (*ia)[i] = a->i[i] + 1; 336945ee14SBarry Smith } else { 346945ee14SBarry Smith *ia = a->i; *ja = a->j; 35a2ce50c7SBarry Smith } 363a40ed3dSBarry Smith PetscFunctionReturn(0); 37a2744918SBarry Smith } 38a2744918SBarry Smith 394a2ae208SSatish Balay #undef __FUNCT__ 404a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ" 4197f1f81fSBarry Smith PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscTruth *done) 426945ee14SBarry Smith { 43dfbe8321SBarry Smith PetscErrorCode ierr; 446945ee14SBarry Smith 453a40ed3dSBarry Smith PetscFunctionBegin; 463a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 47bfeeae90SHong Zhang if ((symmetric && !A->structurally_symmetric) || oshift == 1) { 48606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 49606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 50bcd2baecSBarry Smith } 513a40ed3dSBarry Smith PetscFunctionReturn(0); 5217ab2063SBarry Smith } 5317ab2063SBarry Smith 544a2ae208SSatish Balay #undef __FUNCT__ 554a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ" 5697f1f81fSBarry Smith PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscInt *nn,PetscInt *ia[],PetscInt *ja[],PetscTruth *done) 573b2fbd54SBarry Smith { 583b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 59dfbe8321SBarry Smith PetscErrorCode ierr; 6097f1f81fSBarry Smith PetscInt i,*collengths,*cia,*cja,n = A->n,m = A->m; 6197f1f81fSBarry Smith PetscInt nz = a->i[m],row,*jj,mr,col; 623b2fbd54SBarry Smith 633a40ed3dSBarry Smith PetscFunctionBegin; 643b2fbd54SBarry Smith *nn = A->n; 653a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 663b2fbd54SBarry Smith if (symmetric) { 67bfeeae90SHong Zhang ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr); 683b2fbd54SBarry Smith } else { 6997f1f81fSBarry Smith ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr); 7097f1f81fSBarry Smith ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 7197f1f81fSBarry Smith ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr); 7297f1f81fSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr); 733b2fbd54SBarry Smith jj = a->j; 743b2fbd54SBarry Smith for (i=0; i<nz; i++) { 75bfeeae90SHong Zhang collengths[jj[i]]++; 763b2fbd54SBarry Smith } 773b2fbd54SBarry Smith cia[0] = oshift; 783b2fbd54SBarry Smith for (i=0; i<n; i++) { 793b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 803b2fbd54SBarry Smith } 8197f1f81fSBarry Smith ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 823b2fbd54SBarry Smith jj = a->j; 83a93ec695SBarry Smith for (row=0; row<m; row++) { 84a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 85a93ec695SBarry Smith for (i=0; i<mr; i++) { 86bfeeae90SHong Zhang col = *jj++; 873b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 883b2fbd54SBarry Smith } 893b2fbd54SBarry Smith } 90606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 913b2fbd54SBarry Smith *ia = cia; *ja = cja; 923b2fbd54SBarry Smith } 933a40ed3dSBarry Smith PetscFunctionReturn(0); 943b2fbd54SBarry Smith } 953b2fbd54SBarry Smith 964a2ae208SSatish Balay #undef __FUNCT__ 974a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ" 9897f1f81fSBarry Smith PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscTruth *done) 993b2fbd54SBarry Smith { 100dfbe8321SBarry Smith PetscErrorCode ierr; 101606d414cSSatish Balay 1023a40ed3dSBarry Smith PetscFunctionBegin; 1033a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 1043b2fbd54SBarry Smith 105606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 106606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 1073b2fbd54SBarry Smith 1083a40ed3dSBarry Smith PetscFunctionReturn(0); 1093b2fbd54SBarry Smith } 1103b2fbd54SBarry Smith 111227d817aSBarry Smith #define CHUNKSIZE 15 11217ab2063SBarry Smith 1134a2ae208SSatish Balay #undef __FUNCT__ 1144a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ" 11597f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 11617ab2063SBarry Smith { 117416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11897f1f81fSBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted = a->sorted; 11997f1f81fSBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 1206849ba73SBarry Smith PetscErrorCode ierr; 12197f1f81fSBarry Smith PetscInt *aj = a->j,nonew = a->nonew; 12287828ca2SBarry Smith PetscScalar *ap,value,*aa = a->a; 12336db0b34SBarry Smith PetscTruth ignorezeroentries = ((a->ignorezeroentries && is == ADD_VALUES) ? PETSC_TRUE:PETSC_FALSE); 124273d9f13SBarry Smith PetscTruth roworiented = a->roworiented; 12517ab2063SBarry Smith 1263a40ed3dSBarry Smith PetscFunctionBegin; 12717ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 128416022c9SBarry Smith row = im[k]; 1295ef9f2a5SBarry Smith if (row < 0) continue; 130aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 13177431f27SBarry Smith if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->m-1); 1323b2fbd54SBarry Smith #endif 133bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 13417ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 135416022c9SBarry Smith low = 0; 13617ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 1375ef9f2a5SBarry Smith if (in[l] < 0) continue; 138aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 13977431f27SBarry Smith if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->n-1); 1403b2fbd54SBarry Smith #endif 141bfeeae90SHong Zhang col = in[l]; 1424b0e389bSBarry Smith if (roworiented) { 1435ef9f2a5SBarry Smith value = v[l + k*n]; 144bef8e0ddSBarry Smith } else { 1454b0e389bSBarry Smith value = v[k + l*m]; 1464b0e389bSBarry Smith } 1475b8514ebSBarry Smith if (value == 0.0 && ignorezeroentries) continue; 14836db0b34SBarry Smith 149416022c9SBarry Smith if (!sorted) low = 0; high = nrow; 150416022c9SBarry Smith while (high-low > 5) { 151416022c9SBarry Smith t = (low+high)/2; 152416022c9SBarry Smith if (rp[t] > col) high = t; 153416022c9SBarry Smith else low = t; 15417ab2063SBarry Smith } 155416022c9SBarry Smith for (i=low; i<high; i++) { 15617ab2063SBarry Smith if (rp[i] > col) break; 15717ab2063SBarry Smith if (rp[i] == col) { 158416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 15917ab2063SBarry Smith else ap[i] = value; 16017ab2063SBarry Smith goto noinsert; 16117ab2063SBarry Smith } 16217ab2063SBarry Smith } 163c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 16477431f27SBarry Smith else if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 16517ab2063SBarry Smith if (nrow >= rmax) { 16617ab2063SBarry Smith /* there is no extra room in row, therefore enlarge */ 16797f1f81fSBarry Smith PetscInt new_nz = ai[A->m] + CHUNKSIZE,*new_i,*new_j; 168a7ed9263SMatthew Knepley size_t len; 16987828ca2SBarry Smith PetscScalar *new_a; 17017ab2063SBarry Smith 17177431f27SBarry Smith if (nonew == -2) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix requiring new malloc()",row,col); 17296854ed6SLois Curfman McInnes 17317ab2063SBarry Smith /* malloc new storage space */ 17497f1f81fSBarry Smith len = ((size_t) new_nz)*(sizeof(PetscInt)+sizeof(PetscScalar))+(A->m+1)*sizeof(PetscInt); 175b0a32e0cSBarry Smith ierr = PetscMalloc(len,&new_a);CHKERRQ(ierr); 17697f1f81fSBarry Smith new_j = (PetscInt*)(new_a + new_nz); 17717ab2063SBarry Smith new_i = new_j + new_nz; 17817ab2063SBarry Smith 17917ab2063SBarry Smith /* copy over old data into new slots */ 18017ab2063SBarry Smith for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];} 181273d9f13SBarry Smith for (ii=row+1; ii<A->m+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;} 18297f1f81fSBarry Smith ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(PetscInt));CHKERRQ(ierr); 183bfeeae90SHong Zhang len = (((size_t) new_nz) - CHUNKSIZE - ai[row] - nrow ); 18497f1f81fSBarry Smith ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(PetscInt));CHKERRQ(ierr); 185bfeeae90SHong Zhang ierr = PetscMemcpy(new_a,aa,(((size_t) ai[row])+nrow)*sizeof(PetscScalar));CHKERRQ(ierr); 186bfeeae90SHong Zhang ierr = PetscMemcpy(new_a+ai[row]+nrow+CHUNKSIZE,aa+ai[row]+nrow,len*sizeof(PetscScalar));CHKERRQ(ierr); 18717ab2063SBarry Smith /* free up old matrix storage */ 188606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 189606d414cSSatish Balay if (!a->singlemalloc) { 190606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 191606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 192606d414cSSatish Balay } 193416022c9SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 194f1e2ffcdSBarry Smith a->singlemalloc = PETSC_TRUE; 19517ab2063SBarry Smith 196bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row] ; 197416022c9SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 19897f1f81fSBarry Smith PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(PetscInt) + sizeof(PetscScalar))); 199416022c9SBarry Smith a->maxnz += CHUNKSIZE; 200b810aeb4SBarry Smith a->reallocs++; 20117ab2063SBarry Smith } 202416022c9SBarry Smith N = nrow++ - 1; a->nz++; 203416022c9SBarry Smith /* shift up all the later entries in this row */ 204416022c9SBarry Smith for (ii=N; ii>=i; ii--) { 20517ab2063SBarry Smith rp[ii+1] = rp[ii]; 20617ab2063SBarry Smith ap[ii+1] = ap[ii]; 20717ab2063SBarry Smith } 20817ab2063SBarry Smith rp[i] = col; 20917ab2063SBarry Smith ap[i] = value; 21017ab2063SBarry Smith noinsert:; 211416022c9SBarry Smith low = i + 1; 21217ab2063SBarry Smith } 21317ab2063SBarry Smith ailen[row] = nrow; 21417ab2063SBarry Smith } 2153a40ed3dSBarry Smith PetscFunctionReturn(0); 21617ab2063SBarry Smith } 21717ab2063SBarry Smith 2184a2ae208SSatish Balay #undef __FUNCT__ 2194a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ" 22097f1f81fSBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 2217eb43aa7SLois Curfman McInnes { 2227eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 22397f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 22497f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 22587828ca2SBarry Smith PetscScalar *ap,*aa = a->a,zero = 0.0; 2267eb43aa7SLois Curfman McInnes 2273a40ed3dSBarry Smith PetscFunctionBegin; 2287eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 2297eb43aa7SLois Curfman McInnes row = im[k]; 23077431f27SBarry Smith if (row < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); 23177431f27SBarry Smith if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->m-1); 232bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 2337eb43aa7SLois Curfman McInnes nrow = ailen[row]; 2347eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 23577431f27SBarry Smith if (in[l] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); 23677431f27SBarry Smith if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->n-1); 237bfeeae90SHong Zhang col = in[l] ; 2387eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 2397eb43aa7SLois Curfman McInnes while (high-low > 5) { 2407eb43aa7SLois Curfman McInnes t = (low+high)/2; 2417eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 2427eb43aa7SLois Curfman McInnes else low = t; 2437eb43aa7SLois Curfman McInnes } 2447eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 2457eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 2467eb43aa7SLois Curfman McInnes if (rp[i] == col) { 247b49de8d1SLois Curfman McInnes *v++ = ap[i]; 2487eb43aa7SLois Curfman McInnes goto finished; 2497eb43aa7SLois Curfman McInnes } 2507eb43aa7SLois Curfman McInnes } 251b49de8d1SLois Curfman McInnes *v++ = zero; 2527eb43aa7SLois Curfman McInnes finished:; 2537eb43aa7SLois Curfman McInnes } 2547eb43aa7SLois Curfman McInnes } 2553a40ed3dSBarry Smith PetscFunctionReturn(0); 2567eb43aa7SLois Curfman McInnes } 2577eb43aa7SLois Curfman McInnes 25817ab2063SBarry Smith 2594a2ae208SSatish Balay #undef __FUNCT__ 2604a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary" 261dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer) 26217ab2063SBarry Smith { 263416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2646849ba73SBarry Smith PetscErrorCode ierr; 2656f69ff64SBarry Smith PetscInt i,*col_lens; 2666f69ff64SBarry Smith int fd; 26717ab2063SBarry Smith 2683a40ed3dSBarry Smith PetscFunctionBegin; 269b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 27097f1f81fSBarry Smith ierr = PetscMalloc((4+A->m)*sizeof(PetscInt),&col_lens);CHKERRQ(ierr); 271552e946dSBarry Smith col_lens[0] = MAT_FILE_COOKIE; 272273d9f13SBarry Smith col_lens[1] = A->m; 273273d9f13SBarry Smith col_lens[2] = A->n; 274416022c9SBarry Smith col_lens[3] = a->nz; 275416022c9SBarry Smith 276416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 277273d9f13SBarry Smith for (i=0; i<A->m; i++) { 278416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 27917ab2063SBarry Smith } 2806f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 281606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 282416022c9SBarry Smith 283416022c9SBarry Smith /* store column indices (zero start index) */ 2846f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 285416022c9SBarry Smith 286416022c9SBarry Smith /* store nonzero values */ 2876f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 2883a40ed3dSBarry Smith PetscFunctionReturn(0); 28917ab2063SBarry Smith } 290416022c9SBarry Smith 291dfbe8321SBarry Smith EXTERN PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 292cd155464SBarry Smith 2934a2ae208SSatish Balay #undef __FUNCT__ 2944a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII" 295dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 296416022c9SBarry Smith { 297416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 298dfbe8321SBarry Smith PetscErrorCode ierr; 29997f1f81fSBarry Smith PetscInt i,j,m = A->m,shift=0; 300fb9695e5SSatish Balay char *name; 301f3ef73ceSBarry Smith PetscViewerFormat format; 30217ab2063SBarry Smith 3033a40ed3dSBarry Smith PetscFunctionBegin; 304435da068SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 305b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 306456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO_DETAIL || format == PETSC_VIEWER_ASCII_INFO) { 3076831982aSBarry Smith if (a->inode.size) { 30877431f27SBarry 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); 3096831982aSBarry Smith } else { 310b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"not using I-node routines\n");CHKERRQ(ierr); 3116831982aSBarry Smith } 312fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_MATLAB) { 31397f1f81fSBarry Smith PetscInt nofinalvalue = 0; 314273d9f13SBarry Smith if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->n-!shift)) { 315d00d2cf4SBarry Smith nofinalvalue = 1; 316d00d2cf4SBarry Smith } 317b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 31877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->n);CHKERRQ(ierr); 31977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 32077431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 321b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 32217ab2063SBarry Smith 32317ab2063SBarry Smith for (i=0; i<m; i++) { 324416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 325aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 32677431f27SBarry 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); 32717ab2063SBarry Smith #else 32877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr); 32917ab2063SBarry Smith #endif 33017ab2063SBarry Smith } 33117ab2063SBarry Smith } 332d00d2cf4SBarry Smith if (nofinalvalue) { 33377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->n,0.0);CHKERRQ(ierr); 334d00d2cf4SBarry Smith } 335fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 336b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 337cd155464SBarry Smith } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 338cd155464SBarry Smith PetscFunctionReturn(0); 339fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 340b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 34144cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 34277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 34344cd7ae7SLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 344aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 34536db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 34677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 34736db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 34877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 34936db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 35077431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 3516831982aSBarry Smith } 35244cd7ae7SLois Curfman McInnes #else 35377431f27SBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);} 35444cd7ae7SLois Curfman McInnes #endif 35544cd7ae7SLois Curfman McInnes } 356b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 35744cd7ae7SLois Curfman McInnes } 358b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 359fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 36097f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 361b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 36297f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&sptr);CHKERRQ(ierr); 363496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 364496be53dSLois Curfman McInnes sptr[i] = nzd+1; 365496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 366496be53dSLois Curfman McInnes if (a->j[j] >= i) { 367aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 36836db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 369496be53dSLois Curfman McInnes #else 370496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 371496be53dSLois Curfman McInnes #endif 372496be53dSLois Curfman McInnes } 373496be53dSLois Curfman McInnes } 374496be53dSLois Curfman McInnes } 3752e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 37677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 3772e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 37877431f27SBarry 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);} 37977431f27SBarry 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);} 38077431f27SBarry 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);} 38177431f27SBarry Smith else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);} 38277431f27SBarry Smith else if (i<m) {ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);} 38377431f27SBarry Smith else {ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);} 384496be53dSLois Curfman McInnes } 385b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 386606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 387496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 388496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 38977431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 390496be53dSLois Curfman McInnes } 391b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 392496be53dSLois Curfman McInnes } 393b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 394496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 395496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 396496be53dSLois Curfman McInnes if (a->j[j] >= i) { 397aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 39836db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 399b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 4006831982aSBarry Smith } 401496be53dSLois Curfman McInnes #else 402b0a32e0cSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);} 403496be53dSLois Curfman McInnes #endif 404496be53dSLois Curfman McInnes } 405496be53dSLois Curfman McInnes } 406b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 407496be53dSLois Curfman McInnes } 408b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 409fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 41097f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 41187828ca2SBarry Smith PetscScalar value; 41202594712SBarry Smith 413b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 41402594712SBarry Smith for (i=0; i<m; i++) { 41502594712SBarry Smith jcnt = 0; 416273d9f13SBarry Smith for (j=0; j<A->n; j++) { 417e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 41802594712SBarry Smith value = a->a[cnt++]; 419e24b481bSBarry Smith jcnt++; 42002594712SBarry Smith } else { 42102594712SBarry Smith value = 0.0; 42202594712SBarry Smith } 423aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 424b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr); 42502594712SBarry Smith #else 426b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr); 42702594712SBarry Smith #endif 42802594712SBarry Smith } 429b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 43002594712SBarry Smith } 431b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 4323a40ed3dSBarry Smith } else { 433b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 43417ab2063SBarry Smith for (i=0; i<m; i++) { 43577431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 436416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 437aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 43836db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 43977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 44036db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 44177431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 4423a40ed3dSBarry Smith } else { 44377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 44417ab2063SBarry Smith } 44517ab2063SBarry Smith #else 44677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 44717ab2063SBarry Smith #endif 44817ab2063SBarry Smith } 449b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 45017ab2063SBarry Smith } 451b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 45217ab2063SBarry Smith } 453b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 4543a40ed3dSBarry Smith PetscFunctionReturn(0); 455416022c9SBarry Smith } 456416022c9SBarry Smith 4574a2ae208SSatish Balay #undef __FUNCT__ 4584a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom" 459dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 460416022c9SBarry Smith { 461480ef9eaSBarry Smith Mat A = (Mat) Aa; 462416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 463dfbe8321SBarry Smith PetscErrorCode ierr; 46497f1f81fSBarry Smith PetscInt i,j,m = A->m,color; 46536db0b34SBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0; 466b0a32e0cSBarry Smith PetscViewer viewer; 467f3ef73ceSBarry Smith PetscViewerFormat format; 468cddf8d76SBarry Smith 4693a40ed3dSBarry Smith PetscFunctionBegin; 470480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 471b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 47219bcc07fSBarry Smith 473b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 474416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 4750513a670SBarry Smith 476fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 4770513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 478b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 479416022c9SBarry Smith for (i=0; i<m; i++) { 480cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 481bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 482bfeeae90SHong Zhang x_l = a->j[j] ; x_r = x_l + 1.0; 483aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 48436db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 485cddf8d76SBarry Smith #else 486cddf8d76SBarry Smith if (a->a[j] >= 0.) continue; 487cddf8d76SBarry Smith #endif 488b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 489cddf8d76SBarry Smith } 490cddf8d76SBarry Smith } 491b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 492cddf8d76SBarry Smith for (i=0; i<m; i++) { 493cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 494bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 495bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 496cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 497b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 498cddf8d76SBarry Smith } 499cddf8d76SBarry Smith } 500b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 501cddf8d76SBarry Smith for (i=0; i<m; i++) { 502cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 503bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 504bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 505aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 50636db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 507cddf8d76SBarry Smith #else 508cddf8d76SBarry Smith if (a->a[j] <= 0.) continue; 509cddf8d76SBarry Smith #endif 510b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 511416022c9SBarry Smith } 512416022c9SBarry Smith } 5130513a670SBarry Smith } else { 5140513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 5150513a670SBarry Smith /* first determine max of all nonzero values */ 51697f1f81fSBarry Smith PetscInt nz = a->nz,count; 517b0a32e0cSBarry Smith PetscDraw popup; 51836db0b34SBarry Smith PetscReal scale; 5190513a670SBarry Smith 5200513a670SBarry Smith for (i=0; i<nz; i++) { 5210513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 5220513a670SBarry Smith } 523b0a32e0cSBarry Smith scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv; 524b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 525b0a32e0cSBarry Smith if (popup) {ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);} 5260513a670SBarry Smith count = 0; 5270513a670SBarry Smith for (i=0; i<m; i++) { 5280513a670SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 529bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 530bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 53197f1f81fSBarry Smith color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count])); 532b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 5330513a670SBarry Smith count++; 5340513a670SBarry Smith } 5350513a670SBarry Smith } 5360513a670SBarry Smith } 537480ef9eaSBarry Smith PetscFunctionReturn(0); 538480ef9eaSBarry Smith } 539cddf8d76SBarry Smith 5404a2ae208SSatish Balay #undef __FUNCT__ 5414a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw" 542dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 543480ef9eaSBarry Smith { 544dfbe8321SBarry Smith PetscErrorCode ierr; 545b0a32e0cSBarry Smith PetscDraw draw; 54636db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 547480ef9eaSBarry Smith PetscTruth isnull; 548480ef9eaSBarry Smith 549480ef9eaSBarry Smith PetscFunctionBegin; 550b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 551b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 552480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 553480ef9eaSBarry Smith 554480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 555273d9f13SBarry Smith xr = A->n; yr = A->m; h = yr/10.0; w = xr/10.0; 556480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 557b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 558b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 559480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 5603a40ed3dSBarry Smith PetscFunctionReturn(0); 561416022c9SBarry Smith } 562416022c9SBarry Smith 5634a2ae208SSatish Balay #undef __FUNCT__ 5644a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ" 565dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 566416022c9SBarry Smith { 567416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 568dfbe8321SBarry Smith PetscErrorCode ierr; 56932077d6dSBarry Smith PetscTruth issocket,iascii,isbinary,isdraw; 570416022c9SBarry Smith 5713a40ed3dSBarry Smith PetscFunctionBegin; 572b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr); 57332077d6dSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 574fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr); 575fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr); 5760f5bd95cSBarry Smith if (issocket) { 577b0a32e0cSBarry Smith ierr = PetscViewerSocketPutSparse_Private(viewer,A->m,A->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr); 57832077d6dSBarry Smith } else if (iascii) { 5793a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 5800f5bd95cSBarry Smith } else if (isbinary) { 5813a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 5820f5bd95cSBarry Smith } else if (isdraw) { 5833a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 5845cd90555SBarry Smith } else { 585958c9bccSBarry Smith SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name); 58617ab2063SBarry Smith } 5873a40ed3dSBarry Smith PetscFunctionReturn(0); 58817ab2063SBarry Smith } 58919bcc07fSBarry Smith 5904a2ae208SSatish Balay #undef __FUNCT__ 5914a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ" 592dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 59317ab2063SBarry Smith { 594416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 5956849ba73SBarry Smith PetscErrorCode ierr; 59697f1f81fSBarry Smith PetscInt fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 59797f1f81fSBarry Smith PetscInt m = A->m,*ip,N,*ailen = a->ilen,rmax = 0; 59887828ca2SBarry Smith PetscScalar *aa = a->a,*ap; 5993447b6efSHong Zhang PetscReal ratio=0.6; 60017ab2063SBarry Smith 6013a40ed3dSBarry Smith PetscFunctionBegin; 6023a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 60317ab2063SBarry Smith 60443ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 60517ab2063SBarry Smith for (i=1; i<m; i++) { 606416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 60717ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 60894a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 60917ab2063SBarry Smith if (fshift) { 610bfeeae90SHong Zhang ip = aj + ai[i] ; 611bfeeae90SHong Zhang ap = aa + ai[i] ; 61217ab2063SBarry Smith N = ailen[i]; 61317ab2063SBarry Smith for (j=0; j<N; j++) { 61417ab2063SBarry Smith ip[j-fshift] = ip[j]; 61517ab2063SBarry Smith ap[j-fshift] = ap[j]; 61617ab2063SBarry Smith } 61717ab2063SBarry Smith } 61817ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 61917ab2063SBarry Smith } 62017ab2063SBarry Smith if (m) { 62117ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 62217ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 62317ab2063SBarry Smith } 62417ab2063SBarry Smith /* reset ilen and imax for each row */ 62517ab2063SBarry Smith for (i=0; i<m; i++) { 62617ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 62717ab2063SBarry Smith } 628bfeeae90SHong Zhang a->nz = ai[m]; 62917ab2063SBarry Smith 63017ab2063SBarry Smith /* diagonals may have moved, so kill the diagonal pointers */ 631416022c9SBarry Smith if (fshift && a->diag) { 632606d414cSSatish Balay ierr = PetscFree(a->diag);CHKERRQ(ierr); 63397f1f81fSBarry Smith PetscLogObjectMemory(A,-(m+1)*sizeof(PetscInt)); 634416022c9SBarry Smith a->diag = 0; 63517ab2063SBarry Smith } 63677431f27SBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %D X %D; storage space: %D unneeded,%D used\n",m,A->n,fshift,a->nz); 63777431f27SBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues() is %D\n",a->reallocs); 6381466f1e1SBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Maximum nonzeros in any row is %D\n",rmax); 639dd5f02e7SSatish Balay a->reallocs = 0; 6404e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift; 64136db0b34SBarry Smith a->rmax = rmax; 6424e220ebcSLois Curfman McInnes 64373e7a558SHong Zhang /* check for identical nodes. If found, use inode functions */ 64473e7a558SHong Zhang if (!a->inode.checked){ 6453a7fca6bSBarry Smith ierr = Mat_AIJ_CheckInode(A,(PetscTruth)(!fshift));CHKERRQ(ierr); 64673e7a558SHong Zhang } 647cfef3cccSHong Zhang 64873e7a558SHong Zhang /* check for zero rows. If found a large number of nonzero rows, use CompressedRow functions */ 6493447b6efSHong Zhang if (!a->inode.use && !a->compressedrow.checked && a->compressedrow.use){ 65073e7a558SHong Zhang ierr = Mat_CheckCompressedRow(A,&a->compressedrow,a->i,ratio);CHKERRQ(ierr); 65173e7a558SHong Zhang if (a->compressedrow.use){ 65273e7a558SHong Zhang A->ops->mult = MatMult_SeqAIJ_CompressedRow; 65373e7a558SHong Zhang A->ops->multadd = MatMultAdd_SeqAIJ_CompressedRow; 65473e7a558SHong Zhang } 655*27ea64f8SHong Zhang } else if (a->compressedrow.checked && a->compressedrow.use){ 656*27ea64f8SHong Zhang /* mat structure likely has been changed. Do not use compressed row format until a better 657*27ea64f8SHong Zhang flag on changing mat structure is introduced */ 658*27ea64f8SHong Zhang ierr = PetscFree(a->compressedrow.i);CHKERRQ(ierr); 659*27ea64f8SHong Zhang a->compressedrow.use = PETSC_FALSE; 660*27ea64f8SHong Zhang a->compressedrow.rindex = PETSC_NULL; 661*27ea64f8SHong Zhang A->ops->mult = MatMult_SeqAIJ; 662*27ea64f8SHong Zhang A->ops->multadd = MatMultAdd_SeqAIJ; 66373e7a558SHong Zhang } 6643a40ed3dSBarry Smith PetscFunctionReturn(0); 66517ab2063SBarry Smith } 66617ab2063SBarry Smith 6674a2ae208SSatish Balay #undef __FUNCT__ 6684a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ" 669dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 67017ab2063SBarry Smith { 671416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 672dfbe8321SBarry Smith PetscErrorCode ierr; 6733a40ed3dSBarry Smith 6743a40ed3dSBarry Smith PetscFunctionBegin; 675bfeeae90SHong Zhang ierr = PetscMemzero(a->a,(a->i[A->m])*sizeof(PetscScalar));CHKERRQ(ierr); 6763a40ed3dSBarry Smith PetscFunctionReturn(0); 67717ab2063SBarry Smith } 678416022c9SBarry Smith 6794a2ae208SSatish Balay #undef __FUNCT__ 6804a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ" 681dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 68217ab2063SBarry Smith { 683416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 684dfbe8321SBarry Smith PetscErrorCode ierr; 685d5d45c9bSBarry Smith 6863a40ed3dSBarry Smith PetscFunctionBegin; 687aa482453SBarry Smith #if defined(PETSC_USE_LOG) 68877431f27SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->m,A->n,a->nz); 68917ab2063SBarry Smith #endif 69036db0b34SBarry Smith if (a->freedata) { 691606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 692606d414cSSatish Balay if (!a->singlemalloc) { 693606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 694606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 695606d414cSSatish Balay } 69636db0b34SBarry Smith } 697c38d4ed2SBarry Smith if (a->row) { 698c38d4ed2SBarry Smith ierr = ISDestroy(a->row);CHKERRQ(ierr); 699c38d4ed2SBarry Smith } 700c38d4ed2SBarry Smith if (a->col) { 701c38d4ed2SBarry Smith ierr = ISDestroy(a->col);CHKERRQ(ierr); 702c38d4ed2SBarry Smith } 703606d414cSSatish Balay if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);} 704606d414cSSatish Balay if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);} 705606d414cSSatish Balay if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);} 706273d9f13SBarry Smith if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);} 707606d414cSSatish Balay if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);} 708606d414cSSatish Balay if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);} 70982bf6240SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 710606d414cSSatish Balay if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);} 711cc8ba8e1SBarry Smith if (a->coloring) {ierr = ISColoringDestroy(a->coloring);CHKERRQ(ierr);} 712a30b2313SHong Zhang if (a->xtoy) {ierr = PetscFree(a->xtoy);CHKERRQ(ierr);} 713d487561eSHong Zhang if (a->compressedrow.use){ierr = PetscFree(a->compressedrow.i);} 714a30b2313SHong Zhang 715606d414cSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 716901853e0SKris Buschelman 717901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetColumnIndices_C","",PETSC_NULL);CHKERRQ(ierr); 718901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatStoreValues_C","",PETSC_NULL);CHKERRQ(ierr); 719901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatRetrieveValues_C","",PETSC_NULL);CHKERRQ(ierr); 720901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqsbaij_C","",PETSC_NULL);CHKERRQ(ierr); 721901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqbaij_C","",PETSC_NULL);CHKERRQ(ierr); 722901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatIsTranspose_C","",PETSC_NULL);CHKERRQ(ierr); 723901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocation_C","",PETSC_NULL);CHKERRQ(ierr); 724901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatReorderForNonzeroDiagonal_C","",PETSC_NULL);CHKERRQ(ierr); 725901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatAdjustForInodes_C","",PETSC_NULL);CHKERRQ(ierr); 726901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJGetInodeSizes_C","",PETSC_NULL);CHKERRQ(ierr); 7273a40ed3dSBarry Smith PetscFunctionReturn(0); 72817ab2063SBarry Smith } 72917ab2063SBarry Smith 7304a2ae208SSatish Balay #undef __FUNCT__ 7314a2ae208SSatish Balay #define __FUNCT__ "MatCompress_SeqAIJ" 732dfbe8321SBarry Smith PetscErrorCode MatCompress_SeqAIJ(Mat A) 73317ab2063SBarry Smith { 7343a40ed3dSBarry Smith PetscFunctionBegin; 7353a40ed3dSBarry Smith PetscFunctionReturn(0); 73617ab2063SBarry Smith } 73717ab2063SBarry Smith 7384a2ae208SSatish Balay #undef __FUNCT__ 7394a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ" 740dfbe8321SBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op) 74117ab2063SBarry Smith { 742416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 7433a40ed3dSBarry Smith 7443a40ed3dSBarry Smith PetscFunctionBegin; 745a65d3064SKris Buschelman switch (op) { 746a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 747a65d3064SKris Buschelman a->roworiented = PETSC_TRUE; 748a65d3064SKris Buschelman break; 749a65d3064SKris Buschelman case MAT_KEEP_ZEROED_ROWS: 750a65d3064SKris Buschelman a->keepzeroedrows = PETSC_TRUE; 751a65d3064SKris Buschelman break; 752a65d3064SKris Buschelman case MAT_COLUMN_ORIENTED: 753a65d3064SKris Buschelman a->roworiented = PETSC_FALSE; 754a65d3064SKris Buschelman break; 755a65d3064SKris Buschelman case MAT_COLUMNS_SORTED: 756a65d3064SKris Buschelman a->sorted = PETSC_TRUE; 757a65d3064SKris Buschelman break; 758a65d3064SKris Buschelman case MAT_COLUMNS_UNSORTED: 759a65d3064SKris Buschelman a->sorted = PETSC_FALSE; 760a65d3064SKris Buschelman break; 761a65d3064SKris Buschelman case MAT_NO_NEW_NONZERO_LOCATIONS: 762a65d3064SKris Buschelman a->nonew = 1; 763a65d3064SKris Buschelman break; 764a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 765a65d3064SKris Buschelman a->nonew = -1; 766a65d3064SKris Buschelman break; 767a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 768a65d3064SKris Buschelman a->nonew = -2; 769a65d3064SKris Buschelman break; 770a65d3064SKris Buschelman case MAT_YES_NEW_NONZERO_LOCATIONS: 771a65d3064SKris Buschelman a->nonew = 0; 772a65d3064SKris Buschelman break; 773a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 774a65d3064SKris Buschelman a->ignorezeroentries = PETSC_TRUE; 775a65d3064SKris Buschelman break; 776a65d3064SKris Buschelman case MAT_USE_INODES: 777a65d3064SKris Buschelman a->inode.use = PETSC_TRUE; 778a65d3064SKris Buschelman break; 779a65d3064SKris Buschelman case MAT_DO_NOT_USE_INODES: 780a65d3064SKris Buschelman a->inode.use = PETSC_FALSE; 781a65d3064SKris Buschelman break; 782d487561eSHong Zhang case MAT_USE_COMPRESSEDROW: 783d487561eSHong Zhang a->compressedrow.use = PETSC_TRUE; 784d487561eSHong Zhang break; 785d487561eSHong Zhang case MAT_DO_NOT_USE_COMPRESSEDROW: 786d487561eSHong Zhang a->compressedrow.use = PETSC_FALSE; 787d487561eSHong Zhang break; 788a65d3064SKris Buschelman case MAT_ROWS_SORTED: 789a65d3064SKris Buschelman case MAT_ROWS_UNSORTED: 790a65d3064SKris Buschelman case MAT_YES_NEW_DIAGONALS: 791a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 792a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 793b0a32e0cSBarry Smith PetscLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n"); 794a65d3064SKris Buschelman break; 795a65d3064SKris Buschelman case MAT_NO_NEW_DIAGONALS: 79629bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS"); 797a65d3064SKris Buschelman case MAT_INODE_LIMIT_1: 798a65d3064SKris Buschelman a->inode.limit = 1; 799a65d3064SKris Buschelman break; 800a65d3064SKris Buschelman case MAT_INODE_LIMIT_2: 801a65d3064SKris Buschelman a->inode.limit = 2; 802a65d3064SKris Buschelman break; 803a65d3064SKris Buschelman case MAT_INODE_LIMIT_3: 804a65d3064SKris Buschelman a->inode.limit = 3; 805a65d3064SKris Buschelman break; 806a65d3064SKris Buschelman case MAT_INODE_LIMIT_4: 807a65d3064SKris Buschelman a->inode.limit = 4; 808a65d3064SKris Buschelman break; 809a65d3064SKris Buschelman case MAT_INODE_LIMIT_5: 810a65d3064SKris Buschelman a->inode.limit = 5; 811a65d3064SKris Buschelman break; 81277e54ba9SKris Buschelman case MAT_SYMMETRIC: 81377e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 8149a4540c5SBarry Smith case MAT_NOT_SYMMETRIC: 8159a4540c5SBarry Smith case MAT_NOT_STRUCTURALLY_SYMMETRIC: 8169a4540c5SBarry Smith case MAT_HERMITIAN: 8179a4540c5SBarry Smith case MAT_NOT_HERMITIAN: 8189a4540c5SBarry Smith case MAT_SYMMETRY_ETERNAL: 8199a4540c5SBarry Smith case MAT_NOT_SYMMETRY_ETERNAL: 82077e54ba9SKris Buschelman break; 821a65d3064SKris Buschelman default: 822a65d3064SKris Buschelman SETERRQ(PETSC_ERR_SUP,"unknown option"); 823a65d3064SKris Buschelman } 8243a40ed3dSBarry Smith PetscFunctionReturn(0); 82517ab2063SBarry Smith } 82617ab2063SBarry Smith 8274a2ae208SSatish Balay #undef __FUNCT__ 8284a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ" 829dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 83017ab2063SBarry Smith { 831416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 8326849ba73SBarry Smith PetscErrorCode ierr; 83397f1f81fSBarry Smith PetscInt i,j,n; 83487828ca2SBarry Smith PetscScalar *x,zero = 0.0; 83517ab2063SBarry Smith 8363a40ed3dSBarry Smith PetscFunctionBegin; 8373a40ed3dSBarry Smith ierr = VecSet(&zero,v);CHKERRQ(ierr); 8381ebc52fbSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 83936db0b34SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 840273d9f13SBarry Smith if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 841273d9f13SBarry Smith for (i=0; i<A->m; i++) { 842bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 843bfeeae90SHong Zhang if (a->j[j] == i) { 844416022c9SBarry Smith x[i] = a->a[j]; 84517ab2063SBarry Smith break; 84617ab2063SBarry Smith } 84717ab2063SBarry Smith } 84817ab2063SBarry Smith } 8491ebc52fbSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 8503a40ed3dSBarry Smith PetscFunctionReturn(0); 85117ab2063SBarry Smith } 85217ab2063SBarry Smith 8534a2ae208SSatish Balay #undef __FUNCT__ 8544a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ" 855dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 85617ab2063SBarry Smith { 857416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 8585c897100SBarry Smith PetscScalar *x,*y; 859dfbe8321SBarry Smith PetscErrorCode ierr; 86097f1f81fSBarry Smith PetscInt m = A->m; 8615c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 8625c897100SBarry Smith PetscScalar *v,alpha; 8637b2bb3b9SHong Zhang PetscInt n,i,*idx,*ii,*ridx=PETSC_NULL; 8643447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 8653447b6efSHong Zhang PetscTruth usecprow=cprow.use; 8665c897100SBarry Smith #endif 86717ab2063SBarry Smith 8683a40ed3dSBarry Smith PetscFunctionBegin; 8692e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 8701ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 8711ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 8725c897100SBarry Smith 8735c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 874bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 8755c897100SBarry Smith #else 8763447b6efSHong Zhang if (usecprow){ 8773447b6efSHong Zhang m = cprow.nrows; 8783447b6efSHong Zhang ii = cprow.i; 8797b2bb3b9SHong Zhang ridx = cprow.rindex; 8803447b6efSHong Zhang } else { 8813447b6efSHong Zhang ii = a->i; 8823447b6efSHong Zhang } 88317ab2063SBarry Smith for (i=0; i<m; i++) { 8843447b6efSHong Zhang idx = a->j + ii[i] ; 8853447b6efSHong Zhang v = a->a + ii[i] ; 8863447b6efSHong Zhang n = ii[i+1] - ii[i]; 8873447b6efSHong Zhang if (usecprow){ 8887b2bb3b9SHong Zhang alpha = x[ridx[i]]; 8893447b6efSHong Zhang } else { 89017ab2063SBarry Smith alpha = x[i]; 8913447b6efSHong Zhang } 89217ab2063SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 89317ab2063SBarry Smith } 8945c897100SBarry Smith #endif 895b0a32e0cSBarry Smith PetscLogFlops(2*a->nz); 8961ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 8971ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 8983a40ed3dSBarry Smith PetscFunctionReturn(0); 89917ab2063SBarry Smith } 90017ab2063SBarry Smith 9014a2ae208SSatish Balay #undef __FUNCT__ 9025c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ" 903dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 9045c897100SBarry Smith { 9058d5b0100SBarry Smith PetscScalar zero = 0.0; 906dfbe8321SBarry Smith PetscErrorCode ierr; 9075c897100SBarry Smith 9085c897100SBarry Smith PetscFunctionBegin; 9095c897100SBarry Smith ierr = VecSet(&zero,yy);CHKERRQ(ierr); 9105c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 9115c897100SBarry Smith PetscFunctionReturn(0); 9125c897100SBarry Smith } 9135c897100SBarry Smith 9145c897100SBarry Smith 9155c897100SBarry Smith #undef __FUNCT__ 9164a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ" 917dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 91817ab2063SBarry Smith { 919416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 920362ced78SSatish Balay PetscScalar *x,*y,*v; 921dfbe8321SBarry Smith PetscErrorCode ierr; 92297f1f81fSBarry Smith PetscInt m = A->m,*idx,*ii; 923aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 92497f1f81fSBarry Smith PetscInt 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; 9331ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 9341ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 935416022c9SBarry Smith idx = a->j; 936d64ed03dSBarry Smith v = a->a; 937416022c9SBarry Smith ii = a->i; 938aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 939bfeeae90SHong Zhang fortranmultaij_(&m,x,ii,idx,v,y); 9408d195f9aSBarry Smith #else 94117ab2063SBarry Smith for (i=0; i<m; i++) { 9429ea0dfa2SSatish Balay jrow = ii[i]; 9439ea0dfa2SSatish Balay n = ii[i+1] - jrow; 94417ab2063SBarry Smith sum = 0.0; 9459ea0dfa2SSatish Balay for (j=0; j<n; j++) { 9469ea0dfa2SSatish Balay sum += v[jrow]*x[idx[jrow]]; jrow++; 9479ea0dfa2SSatish Balay } 94817ab2063SBarry Smith y[i] = sum; 94917ab2063SBarry Smith } 9508d195f9aSBarry Smith #endif 951b0a32e0cSBarry Smith PetscLogFlops(2*a->nz - m); 9521ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 9531ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 9543a40ed3dSBarry Smith PetscFunctionReturn(0); 95517ab2063SBarry Smith } 95617ab2063SBarry Smith 9574a2ae208SSatish Balay #undef __FUNCT__ 95873e7a558SHong Zhang #define __FUNCT__ "MatMult_SeqAIJ_CompressedRow" 95973e7a558SHong Zhang PetscErrorCode MatMult_SeqAIJ_CompressedRow(Mat A,Vec xx,Vec yy) 96073e7a558SHong Zhang { 96173e7a558SHong Zhang PetscErrorCode ierr; 96273e7a558SHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 96373e7a558SHong Zhang PetscScalar *x,*y,*aa,sum; 9647b2bb3b9SHong Zhang PetscInt m,*ridx,nz,i,j,*aj,*ai; 96573e7a558SHong Zhang 96673e7a558SHong Zhang PetscFunctionBegin; 96773e7a558SHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 96873e7a558SHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 96973e7a558SHong Zhang 97073e7a558SHong Zhang m = a->compressedrow.nrows; 97173e7a558SHong Zhang ai = a->compressedrow.i; 9727b2bb3b9SHong Zhang ridx = a->compressedrow.rindex; 97373e7a558SHong Zhang for (i=0; i<m; i++){ 97473e7a558SHong Zhang nz = ai[i+1] - ai[i]; 97573e7a558SHong Zhang aj = a->j + ai[i]; 97673e7a558SHong Zhang aa = a->a + ai[i]; 97773e7a558SHong Zhang sum = 0.0; 97873e7a558SHong Zhang for (j=0; j<nz; j++) sum += (*aa++)*x[*aj++]; 9797b2bb3b9SHong Zhang y[*ridx++] = sum; 98073e7a558SHong Zhang } 98173e7a558SHong Zhang 98273e7a558SHong Zhang PetscLogFlops(2*a->nz - m); 98373e7a558SHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 98473e7a558SHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 98573e7a558SHong Zhang PetscFunctionReturn(0); 98673e7a558SHong Zhang } 98773e7a558SHong Zhang 98873e7a558SHong Zhang #undef __FUNCT__ 9894a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ" 990dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 99117ab2063SBarry Smith { 992416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 993362ced78SSatish Balay PetscScalar *x,*y,*z,*v; 994dfbe8321SBarry Smith PetscErrorCode ierr; 99597f1f81fSBarry Smith PetscInt m = A->m,*idx,*ii; 996aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 99797f1f81fSBarry Smith PetscInt n,i,jrow,j; 998362ced78SSatish Balay PetscScalar sum; 999e36a17ebSSatish Balay #endif 10009ea0dfa2SSatish Balay 10013a40ed3dSBarry Smith PetscFunctionBegin; 10021ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 10031ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 10042e8a6d31SBarry Smith if (zz != yy) { 10051ebc52fbSHong Zhang ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 10062e8a6d31SBarry Smith } else { 10072e8a6d31SBarry Smith z = y; 10082e8a6d31SBarry Smith } 1009bfeeae90SHong Zhang 1010cddf8d76SBarry Smith idx = a->j; 1011d64ed03dSBarry Smith v = a->a; 1012cddf8d76SBarry Smith ii = a->i; 1013aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 1014bfeeae90SHong Zhang fortranmultaddaij_(&m,x,ii,idx,v,y,z); 101502ab625aSSatish Balay #else 101617ab2063SBarry Smith for (i=0; i<m; i++) { 10179ea0dfa2SSatish Balay jrow = ii[i]; 10189ea0dfa2SSatish Balay n = ii[i+1] - jrow; 101917ab2063SBarry Smith sum = y[i]; 10209ea0dfa2SSatish Balay for (j=0; j<n; j++) { 10219ea0dfa2SSatish Balay sum += v[jrow]*x[idx[jrow]]; jrow++; 10229ea0dfa2SSatish Balay } 102317ab2063SBarry Smith z[i] = sum; 102417ab2063SBarry Smith } 102502ab625aSSatish Balay #endif 1026b0a32e0cSBarry Smith PetscLogFlops(2*a->nz); 10271ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 10281ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 10292e8a6d31SBarry Smith if (zz != yy) { 10301ebc52fbSHong Zhang ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 10312e8a6d31SBarry Smith } 10323a40ed3dSBarry Smith PetscFunctionReturn(0); 103317ab2063SBarry Smith } 103417ab2063SBarry Smith 103573e7a558SHong Zhang /* Almost same code as the MatMult_SeqAij_CompressedRow() */ 103673e7a558SHong Zhang #undef __FUNCT__ 103773e7a558SHong Zhang #define __FUNCT__ "MatMultAdd_SeqAIJ_CompressedRow" 103873e7a558SHong Zhang PetscErrorCode MatMultAdd_SeqAIJ_CompressedRow(Mat A,Vec xx,Vec zz,Vec yy) 103973e7a558SHong Zhang { 104073e7a558SHong Zhang PetscErrorCode ierr; 104173e7a558SHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 104273e7a558SHong Zhang PetscScalar *x,*y,*z,*aa,sum; 10437b2bb3b9SHong Zhang PetscInt m,*ridx,nz,i,j,*aj,*ai; 104473e7a558SHong Zhang 104573e7a558SHong Zhang PetscFunctionBegin; 104673e7a558SHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 104773e7a558SHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 104873e7a558SHong Zhang if (zz != yy) { 104973e7a558SHong Zhang ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 105073e7a558SHong Zhang } else { 105173e7a558SHong Zhang z = y; 105273e7a558SHong Zhang } 105373e7a558SHong Zhang 105473e7a558SHong Zhang m = a->compressedrow.nrows; 105573e7a558SHong Zhang ai = a->compressedrow.i; 10567b2bb3b9SHong Zhang ridx = a->compressedrow.rindex; 105773e7a558SHong Zhang for (i=0; i<m; i++){ 105873e7a558SHong Zhang nz = ai[i+1] - ai[i]; 105973e7a558SHong Zhang aj = a->j + ai[i]; 106073e7a558SHong Zhang aa = a->a + ai[i]; 10617b2bb3b9SHong Zhang sum = y[*ridx]; 106273e7a558SHong Zhang for (j=0; j<nz; j++) sum += (*aa++)*x[*aj++]; 10637b2bb3b9SHong Zhang z[*ridx++] = sum; 106473e7a558SHong Zhang } 106573e7a558SHong Zhang PetscLogFlops(2*a->nz - m); 106673e7a558SHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 106773e7a558SHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 106873e7a558SHong Zhang if (zz != yy) { 106973e7a558SHong Zhang ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 107073e7a558SHong Zhang } 107173e7a558SHong Zhang PetscFunctionReturn(0); 107273e7a558SHong Zhang } 107373e7a558SHong Zhang 107417ab2063SBarry Smith /* 107517ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 107617ab2063SBarry Smith */ 10774a2ae208SSatish Balay #undef __FUNCT__ 10784a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ" 1079dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 108017ab2063SBarry Smith { 1081416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 10826849ba73SBarry Smith PetscErrorCode ierr; 108397f1f81fSBarry Smith PetscInt i,j,*diag,m = A->m; 108417ab2063SBarry Smith 10853a40ed3dSBarry Smith PetscFunctionBegin; 1086f1e2ffcdSBarry Smith if (a->diag) PetscFunctionReturn(0); 1087f1e2ffcdSBarry Smith 108897f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&diag);CHKERRQ(ierr); 108997f1f81fSBarry Smith PetscLogObjectMemory(A,(m+1)*sizeof(PetscInt)); 1090273d9f13SBarry Smith for (i=0; i<A->m; i++) { 109135b0346bSBarry Smith diag[i] = a->i[i+1]; 1092bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1093bfeeae90SHong Zhang if (a->j[j] == i) { 1094bfeeae90SHong Zhang diag[i] = j; 109517ab2063SBarry Smith break; 109617ab2063SBarry Smith } 109717ab2063SBarry Smith } 109817ab2063SBarry Smith } 1099416022c9SBarry Smith a->diag = diag; 11003a40ed3dSBarry Smith PetscFunctionReturn(0); 110117ab2063SBarry Smith } 110217ab2063SBarry Smith 1103be5855fcSBarry Smith /* 1104be5855fcSBarry Smith Checks for missing diagonals 1105be5855fcSBarry Smith */ 11064a2ae208SSatish Balay #undef __FUNCT__ 11074a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ" 1108dfbe8321SBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A) 1109be5855fcSBarry Smith { 1110be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11116849ba73SBarry Smith PetscErrorCode ierr; 111297f1f81fSBarry Smith PetscInt *diag,*jj = a->j,i; 1113be5855fcSBarry Smith 1114be5855fcSBarry Smith PetscFunctionBegin; 1115f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1116f1e2ffcdSBarry Smith diag = a->diag; 1117273d9f13SBarry Smith for (i=0; i<A->m; i++) { 1118bfeeae90SHong Zhang if (jj[diag[i]] != i) { 111977431f27SBarry Smith SETERRQ1(PETSC_ERR_PLIB,"Matrix is missing diagonal number %D",i); 1120be5855fcSBarry Smith } 1121be5855fcSBarry Smith } 1122be5855fcSBarry Smith PetscFunctionReturn(0); 1123be5855fcSBarry Smith } 1124be5855fcSBarry Smith 11254a2ae208SSatish Balay #undef __FUNCT__ 11264a2ae208SSatish Balay #define __FUNCT__ "MatRelax_SeqAIJ" 112797f1f81fSBarry Smith PetscErrorCode MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 112817ab2063SBarry Smith { 1129416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1130beeb8507SBarry Smith PetscScalar *x,d,*xs,sum,*t,scale,*idiag=0,*mdiag; 1131beeb8507SBarry Smith const PetscScalar *v = a->a, *b, *bs,*xb, *ts; 1132dfbe8321SBarry Smith PetscErrorCode ierr; 113397f1f81fSBarry Smith PetscInt n = A->n,m = A->m,i; 113497f1f81fSBarry Smith const PetscInt *idx,*diag; 113517ab2063SBarry Smith 11363a40ed3dSBarry Smith PetscFunctionBegin; 1137b965ef7fSBarry Smith its = its*lits; 113877431f27SBarry Smith if (its <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D and local its %D both positive",its,lits); 113991723122SBarry Smith 1140ed480e8bSBarry Smith if (!a->diag) {ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);} 1141ed480e8bSBarry Smith diag = a->diag; 1142ed480e8bSBarry Smith if (!a->idiag) { 1143ed480e8bSBarry Smith ierr = PetscMalloc(3*m*sizeof(PetscScalar),&a->idiag);CHKERRQ(ierr); 1144ed480e8bSBarry Smith a->ssor = a->idiag + m; 1145ed480e8bSBarry Smith mdiag = a->ssor + m; 1146ed480e8bSBarry Smith 1147ed480e8bSBarry Smith v = a->a; 1148ed480e8bSBarry Smith 1149ed480e8bSBarry Smith /* this is wrong when fshift omega changes each iteration */ 1150958c9bccSBarry Smith if (omega == 1.0 && !fshift) { 1151ed480e8bSBarry Smith for (i=0; i<m; i++) { 1152ed480e8bSBarry Smith mdiag[i] = v[diag[i]]; 1153ed480e8bSBarry Smith a->idiag[i] = 1.0/v[diag[i]]; 1154ed480e8bSBarry Smith } 1155beeb8507SBarry Smith PetscLogFlops(m); 1156ed480e8bSBarry Smith } else { 1157ed480e8bSBarry Smith for (i=0; i<m; i++) { 1158ed480e8bSBarry Smith mdiag[i] = v[diag[i]]; 1159beeb8507SBarry Smith a->idiag[i] = omega/(fshift + v[diag[i]]); 1160ed480e8bSBarry Smith } 1161beeb8507SBarry Smith PetscLogFlops(2*m); 1162beeb8507SBarry Smith } 1163ed480e8bSBarry Smith } 1164ed480e8bSBarry Smith t = a->ssor; 1165ed480e8bSBarry Smith idiag = a->idiag; 1166ed480e8bSBarry Smith mdiag = a->idiag + 2*m; 1167ed480e8bSBarry Smith 11681ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 1169fb2e594dSBarry Smith if (xx != bb) { 11701ebc52fbSHong Zhang ierr = VecGetArray(bb,(PetscScalar**)&b);CHKERRQ(ierr); 1171fb2e594dSBarry Smith } else { 1172fb2e594dSBarry Smith b = x; 1173fb2e594dSBarry Smith } 1174fb2e594dSBarry Smith 1175ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 1176ed480e8bSBarry Smith xs = x; 117717ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 117817ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1179ed480e8bSBarry Smith bs = b; 118017ab2063SBarry Smith for (i=0; i<m; i++) { 1181ed480e8bSBarry Smith d = fshift + a->a[diag[i]]; 1182416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1183ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1184ed480e8bSBarry Smith v = a->a + diag[i] + 1; 118517ab2063SBarry Smith sum = b[i]*d/omega; 118617ab2063SBarry Smith SPARSEDENSEDOT(sum,bs,v,idx,n); 118717ab2063SBarry Smith x[i] = sum; 118817ab2063SBarry Smith } 11891ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 11901ebc52fbSHong Zhang if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);} 1191ed480e8bSBarry Smith PetscLogFlops(a->nz); 11923a40ed3dSBarry Smith PetscFunctionReturn(0); 119317ab2063SBarry Smith } 1194c783ea89SBarry Smith 1195ed480e8bSBarry Smith 1196fc3d8934SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1197fc3d8934SBarry Smith U is upper triangular, E is diagonal; This routine applies 1198fc3d8934SBarry Smith 1199fc3d8934SBarry Smith (L + E)^{-1} A (U + E)^{-1} 1200fc3d8934SBarry Smith 1201fc3d8934SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 1202fc3d8934SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 120348af12d7SBarry Smith is the relaxation factor. 1204fc3d8934SBarry Smith */ 1205fc3d8934SBarry Smith 120648af12d7SBarry Smith if (flag == SOR_APPLY_LOWER) { 120729bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 12083a40ed3dSBarry Smith } else if (flag & SOR_EISENSTAT) { 120917ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 121017ab2063SBarry Smith U is upper triangular, E is diagonal; This routine applies 121117ab2063SBarry Smith 121217ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 121317ab2063SBarry Smith 121417ab2063SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 121517ab2063SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 121617ab2063SBarry Smith is the relaxation factor. 121717ab2063SBarry Smith */ 121817ab2063SBarry Smith scale = (2.0/omega) - 1.0; 121917ab2063SBarry Smith 122017ab2063SBarry Smith /* x = (E + U)^{-1} b */ 122117ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1222416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1223ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1224ed480e8bSBarry Smith v = a->a + diag[i] + 1; 122517ab2063SBarry Smith sum = b[i]; 122617ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1227ed480e8bSBarry Smith x[i] = sum*idiag[i]; 122817ab2063SBarry Smith } 122917ab2063SBarry Smith 123017ab2063SBarry Smith /* t = b - (2*E - D)x */ 1231416022c9SBarry Smith v = a->a; 1232ed480e8bSBarry Smith for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; } 123317ab2063SBarry Smith 123417ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1235ed480e8bSBarry Smith ts = t; 1236416022c9SBarry Smith diag = a->diag; 123717ab2063SBarry Smith for (i=0; i<m; i++) { 1238416022c9SBarry Smith n = diag[i] - a->i[i]; 1239ed480e8bSBarry Smith idx = a->j + a->i[i]; 1240ed480e8bSBarry Smith v = a->a + a->i[i]; 124117ab2063SBarry Smith sum = t[i]; 124217ab2063SBarry Smith SPARSEDENSEMDOT(sum,ts,v,idx,n); 1243ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1244733d66baSBarry Smith /* x = x + t */ 1245733d66baSBarry Smith x[i] += t[i]; 124617ab2063SBarry Smith } 124717ab2063SBarry Smith 1248b0a32e0cSBarry Smith PetscLogFlops(6*m-1 + 2*a->nz); 12491ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 12501ebc52fbSHong Zhang if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);} 12513a40ed3dSBarry Smith PetscFunctionReturn(0); 125217ab2063SBarry Smith } 125317ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 125417ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 125577d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 125697f1f81fSBarry Smith fortranrelaxaijforwardzero_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,idiag,a->a,(void*)b); 125777d8c4bbSBarry Smith #else 125817ab2063SBarry Smith for (i=0; i<m; i++) { 1259416022c9SBarry Smith n = diag[i] - a->i[i]; 1260ed480e8bSBarry Smith idx = a->j + a->i[i]; 1261ed480e8bSBarry Smith v = a->a + a->i[i]; 126217ab2063SBarry Smith sum = b[i]; 126317ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1264ed480e8bSBarry Smith x[i] = sum*idiag[i]; 126517ab2063SBarry Smith } 126677d8c4bbSBarry Smith #endif 126717ab2063SBarry Smith xb = x; 1268ed480e8bSBarry Smith PetscLogFlops(a->nz); 12693a40ed3dSBarry Smith } else xb = b; 127017ab2063SBarry Smith if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) && 127117ab2063SBarry Smith (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) { 127217ab2063SBarry Smith for (i=0; i<m; i++) { 1273ed480e8bSBarry Smith x[i] *= mdiag[i]; 127417ab2063SBarry Smith } 1275b0a32e0cSBarry Smith PetscLogFlops(m); 127617ab2063SBarry Smith } 127717ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 127877d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 127997f1f81fSBarry Smith fortranrelaxaijbackwardzero_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,idiag,a->a,(void*)xb); 128077d8c4bbSBarry Smith #else 128117ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1282416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1283ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1284ed480e8bSBarry Smith v = a->a + diag[i] + 1; 128517ab2063SBarry Smith sum = xb[i]; 128617ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1287ed480e8bSBarry Smith x[i] = sum*idiag[i]; 128817ab2063SBarry Smith } 128977d8c4bbSBarry Smith #endif 1290ed480e8bSBarry Smith PetscLogFlops(a->nz); 129117ab2063SBarry Smith } 129217ab2063SBarry Smith its--; 129317ab2063SBarry Smith } 129417ab2063SBarry Smith while (its--) { 129517ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 129677d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 129797f1f81fSBarry Smith fortranrelaxaijforward_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,a->a,(void*)b); 129877d8c4bbSBarry Smith #else 129917ab2063SBarry Smith for (i=0; i<m; i++) { 1300ed480e8bSBarry Smith d = fshift + a->a[diag[i]]; 1301416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1302ed480e8bSBarry Smith idx = a->j + a->i[i]; 1303ed480e8bSBarry Smith v = a->a + a->i[i]; 130417ab2063SBarry Smith sum = b[i]; 130517ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1306ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 130717ab2063SBarry Smith } 130877d8c4bbSBarry Smith #endif 1309ed480e8bSBarry Smith PetscLogFlops(a->nz); 131017ab2063SBarry Smith } 131117ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 131277d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 131397f1f81fSBarry Smith fortranrelaxaijbackward_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,a->a,(void*)b); 131477d8c4bbSBarry Smith #else 131517ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1316ed480e8bSBarry Smith d = fshift + a->a[diag[i]]; 1317416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1318ed480e8bSBarry Smith idx = a->j + a->i[i]; 1319ed480e8bSBarry Smith v = a->a + a->i[i]; 132017ab2063SBarry Smith sum = b[i]; 132117ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1322ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 132317ab2063SBarry Smith } 132477d8c4bbSBarry Smith #endif 1325ed480e8bSBarry Smith PetscLogFlops(a->nz); 132617ab2063SBarry Smith } 132717ab2063SBarry Smith } 13281ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 13291ebc52fbSHong Zhang if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);} 13303a40ed3dSBarry Smith PetscFunctionReturn(0); 133117ab2063SBarry Smith } 133217ab2063SBarry Smith 13334a2ae208SSatish Balay #undef __FUNCT__ 13344a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ" 1335dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 133617ab2063SBarry Smith { 1337416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 13384e220ebcSLois Curfman McInnes 13393a40ed3dSBarry Smith PetscFunctionBegin; 1340273d9f13SBarry Smith info->rows_global = (double)A->m; 1341273d9f13SBarry Smith info->columns_global = (double)A->n; 1342273d9f13SBarry Smith info->rows_local = (double)A->m; 1343273d9f13SBarry Smith info->columns_local = (double)A->n; 13444e220ebcSLois Curfman McInnes info->block_size = 1.0; 13454e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 13464e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 13474e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 13484e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 13494e220ebcSLois Curfman McInnes info->mallocs = (double)a->reallocs; 13504e220ebcSLois Curfman McInnes info->memory = A->mem; 13514e220ebcSLois Curfman McInnes if (A->factor) { 13524e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 13534e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 13544e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 13554e220ebcSLois Curfman McInnes } else { 13564e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 13574e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 13584e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 13594e220ebcSLois Curfman McInnes } 13603a40ed3dSBarry Smith PetscFunctionReturn(0); 136117ab2063SBarry Smith } 136217ab2063SBarry Smith 13634a2ae208SSatish Balay #undef __FUNCT__ 13644a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ" 1365dfbe8321SBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,IS is,const PetscScalar *diag) 136617ab2063SBarry Smith { 1367416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 13686849ba73SBarry Smith PetscErrorCode ierr; 136997f1f81fSBarry Smith PetscInt i,N,*rows,m = A->m - 1; 137017ab2063SBarry Smith 13713a40ed3dSBarry Smith PetscFunctionBegin; 1372b9b97703SBarry Smith ierr = ISGetLocalSize(is,&N);CHKERRQ(ierr); 137317ab2063SBarry Smith ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 1374f1e2ffcdSBarry Smith if (a->keepzeroedrows) { 1375f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 137677431f27SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1377bfeeae90SHong Zhang ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 1378f1e2ffcdSBarry Smith } 1379f1e2ffcdSBarry Smith if (diag) { 1380f1e2ffcdSBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1381f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1382f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1383f1e2ffcdSBarry Smith a->a[a->diag[rows[i]]] = *diag; 1384f1e2ffcdSBarry Smith } 1385f1e2ffcdSBarry Smith } 1386f1e2ffcdSBarry Smith } else { 138717ab2063SBarry Smith if (diag) { 138817ab2063SBarry Smith for (i=0; i<N; i++) { 138977431f27SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 13907ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1391416022c9SBarry Smith a->ilen[rows[i]] = 1; 1392bfeeae90SHong Zhang a->a[a->i[rows[i]]] = *diag; 1393bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 13947ae801bdSBarry Smith } else { /* in case row was completely empty */ 1395d64ed03dSBarry Smith ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr); 139617ab2063SBarry Smith } 139717ab2063SBarry Smith } 13983a40ed3dSBarry Smith } else { 139917ab2063SBarry Smith for (i=0; i<N; i++) { 140077431f27SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1401416022c9SBarry Smith a->ilen[rows[i]] = 0; 140217ab2063SBarry Smith } 140317ab2063SBarry Smith } 1404f1e2ffcdSBarry Smith } 14057ae801bdSBarry Smith ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 140643a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14073a40ed3dSBarry Smith PetscFunctionReturn(0); 140817ab2063SBarry Smith } 140917ab2063SBarry Smith 14104a2ae208SSatish Balay #undef __FUNCT__ 14114a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ" 141297f1f81fSBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 141317ab2063SBarry Smith { 1414416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 141597f1f81fSBarry Smith PetscInt *itmp; 141617ab2063SBarry Smith 14173a40ed3dSBarry Smith PetscFunctionBegin; 141877431f27SBarry Smith if (row < 0 || row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 141917ab2063SBarry Smith 1420416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1421bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 142217ab2063SBarry Smith if (idx) { 1423bfeeae90SHong Zhang itmp = a->j + a->i[row]; 1424bfeeae90SHong Zhang if (*nz) { 14254e093b46SBarry Smith *idx = itmp; 142617ab2063SBarry Smith } 142717ab2063SBarry Smith else *idx = 0; 142817ab2063SBarry Smith } 14293a40ed3dSBarry Smith PetscFunctionReturn(0); 143017ab2063SBarry Smith } 143117ab2063SBarry Smith 1432bfeeae90SHong Zhang /* remove this function? */ 14334a2ae208SSatish Balay #undef __FUNCT__ 14344a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ" 143597f1f81fSBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 143617ab2063SBarry Smith { 14373a40ed3dSBarry Smith PetscFunctionBegin; 14383a40ed3dSBarry Smith PetscFunctionReturn(0); 143917ab2063SBarry Smith } 144017ab2063SBarry Smith 14414a2ae208SSatish Balay #undef __FUNCT__ 14424a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ" 1443dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 144417ab2063SBarry Smith { 1445416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 144687828ca2SBarry Smith PetscScalar *v = a->a; 144736db0b34SBarry Smith PetscReal sum = 0.0; 14486849ba73SBarry Smith PetscErrorCode ierr; 144997f1f81fSBarry Smith PetscInt i,j; 145017ab2063SBarry Smith 14513a40ed3dSBarry Smith PetscFunctionBegin; 145217ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1453416022c9SBarry Smith for (i=0; i<a->nz; i++) { 1454aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 145536db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 145617ab2063SBarry Smith #else 145717ab2063SBarry Smith sum += (*v)*(*v); v++; 145817ab2063SBarry Smith #endif 145917ab2063SBarry Smith } 1460064f8208SBarry Smith *nrm = sqrt(sum); 14613a40ed3dSBarry Smith } else if (type == NORM_1) { 146236db0b34SBarry Smith PetscReal *tmp; 146397f1f81fSBarry Smith PetscInt *jj = a->j; 1464b0a32e0cSBarry Smith ierr = PetscMalloc((A->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr); 1465273d9f13SBarry Smith ierr = PetscMemzero(tmp,A->n*sizeof(PetscReal));CHKERRQ(ierr); 1466064f8208SBarry Smith *nrm = 0.0; 1467416022c9SBarry Smith for (j=0; j<a->nz; j++) { 1468bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 146917ab2063SBarry Smith } 1470273d9f13SBarry Smith for (j=0; j<A->n; j++) { 1471064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 147217ab2063SBarry Smith } 1473606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 14743a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1475064f8208SBarry Smith *nrm = 0.0; 1476273d9f13SBarry Smith for (j=0; j<A->m; j++) { 1477bfeeae90SHong Zhang v = a->a + a->i[j]; 147817ab2063SBarry Smith sum = 0.0; 1479416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 1480cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 148117ab2063SBarry Smith } 1482064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 148317ab2063SBarry Smith } 14843a40ed3dSBarry Smith } else { 148529bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"No support for two norm"); 148617ab2063SBarry Smith } 14873a40ed3dSBarry Smith PetscFunctionReturn(0); 148817ab2063SBarry Smith } 148917ab2063SBarry Smith 14904a2ae208SSatish Balay #undef __FUNCT__ 14914a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ" 1492dfbe8321SBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,Mat *B) 149317ab2063SBarry Smith { 1494416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1495416022c9SBarry Smith Mat C; 14966849ba73SBarry Smith PetscErrorCode ierr; 149797f1f81fSBarry Smith PetscInt i,*aj = a->j,*ai = a->i,m = A->m,len,*col; 149887828ca2SBarry Smith PetscScalar *array = a->a; 149917ab2063SBarry Smith 15003a40ed3dSBarry Smith PetscFunctionBegin; 1501273d9f13SBarry Smith if (!B && m != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Square matrix only for in-place"); 150297f1f81fSBarry Smith ierr = PetscMalloc((1+A->n)*sizeof(PetscInt),&col);CHKERRQ(ierr); 150397f1f81fSBarry Smith ierr = PetscMemzero(col,(1+A->n)*sizeof(PetscInt));CHKERRQ(ierr); 1504bfeeae90SHong Zhang 1505bfeeae90SHong Zhang for (i=0; i<ai[m]; i++) col[aj[i]] += 1; 1506f204ca49SKris Buschelman ierr = MatCreate(A->comm,A->n,m,A->n,m,&C);CHKERRQ(ierr); 1507f204ca49SKris Buschelman ierr = MatSetType(C,A->type_name);CHKERRQ(ierr); 1508f204ca49SKris Buschelman ierr = MatSeqAIJSetPreallocation(C,0,col);CHKERRQ(ierr); 1509606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 151017ab2063SBarry Smith for (i=0; i<m; i++) { 151117ab2063SBarry Smith len = ai[i+1]-ai[i]; 1512416022c9SBarry Smith ierr = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 1513b9b97703SBarry Smith array += len; 1514b9b97703SBarry Smith aj += len; 151517ab2063SBarry Smith } 151617ab2063SBarry Smith 15176d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 15186d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 151917ab2063SBarry Smith 1520f1e2ffcdSBarry Smith if (B) { 1521416022c9SBarry Smith *B = C; 152217ab2063SBarry Smith } else { 1523273d9f13SBarry Smith ierr = MatHeaderCopy(A,C);CHKERRQ(ierr); 152417ab2063SBarry Smith } 15253a40ed3dSBarry Smith PetscFunctionReturn(0); 152617ab2063SBarry Smith } 152717ab2063SBarry Smith 1528cd0d46ebSvictorle EXTERN_C_BEGIN 1529cd0d46ebSvictorle #undef __FUNCT__ 15305fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ" 1531dfbe8321SBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscTruth *f) 1532cd0d46ebSvictorle { 1533cd0d46ebSvictorle Mat_SeqAIJ *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data; 153497f1f81fSBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; PetscScalar *va,*vb; 15356849ba73SBarry Smith PetscErrorCode ierr; 153697f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 1537cd0d46ebSvictorle 1538cd0d46ebSvictorle PetscFunctionBegin; 1539cd0d46ebSvictorle bij = (Mat_SeqAIJ *) B->data; 1540cd0d46ebSvictorle 1541cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 1542cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 15435485867bSBarry Smith if (ma!=nb || na!=mb){ 15445485867bSBarry Smith *f = PETSC_FALSE; 15455485867bSBarry Smith PetscFunctionReturn(0); 15465485867bSBarry Smith } 1547cd0d46ebSvictorle aii = aij->i; bii = bij->i; 1548cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 1549cd0d46ebSvictorle va = aij->a; vb = bij->a; 155097f1f81fSBarry Smith ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr); 155197f1f81fSBarry Smith ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr); 1552cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 1553cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 1554cd0d46ebSvictorle 1555cd0d46ebSvictorle *f = PETSC_TRUE; 1556cd0d46ebSvictorle for (i=0; i<ma; i++) { 1557cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 155897f1f81fSBarry Smith PetscInt idc,idr; 15595485867bSBarry Smith PetscScalar vc,vr; 1560cd0d46ebSvictorle /* column/row index/value */ 15615485867bSBarry Smith idc = adx[aptr[i]]; 15625485867bSBarry Smith idr = bdx[bptr[idc]]; 15635485867bSBarry Smith vc = va[aptr[i]]; 15645485867bSBarry Smith vr = vb[bptr[idc]]; 15655485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 15665485867bSBarry Smith *f = PETSC_FALSE; 15675485867bSBarry Smith goto done; 1568cd0d46ebSvictorle } else { 15695485867bSBarry Smith aptr[i]++; 15705485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 1571cd0d46ebSvictorle } 1572cd0d46ebSvictorle } 1573cd0d46ebSvictorle } 1574cd0d46ebSvictorle done: 1575cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 15763aeef889SHong Zhang if (B) { 15773aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 15783aeef889SHong Zhang } 1579cd0d46ebSvictorle PetscFunctionReturn(0); 1580cd0d46ebSvictorle } 1581cd0d46ebSvictorle EXTERN_C_END 1582cd0d46ebSvictorle 15839e29f15eSvictorle #undef __FUNCT__ 15849e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ" 1585dfbe8321SBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscTruth *f) 15869e29f15eSvictorle { 1587dfbe8321SBarry Smith PetscErrorCode ierr; 15889e29f15eSvictorle PetscFunctionBegin; 15895485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 15909e29f15eSvictorle PetscFunctionReturn(0); 15919e29f15eSvictorle } 15929e29f15eSvictorle 15934a2ae208SSatish Balay #undef __FUNCT__ 15944a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ" 1595dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 159617ab2063SBarry Smith { 1597416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 159887828ca2SBarry Smith PetscScalar *l,*r,x,*v; 1599dfbe8321SBarry Smith PetscErrorCode ierr; 160097f1f81fSBarry Smith PetscInt i,j,m = A->m,n = A->n,M,nz = a->nz,*jj; 160117ab2063SBarry Smith 16023a40ed3dSBarry Smith PetscFunctionBegin; 160317ab2063SBarry Smith if (ll) { 16043ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 16053ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 1606e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 1607273d9f13SBarry Smith if (m != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 16081ebc52fbSHong Zhang ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 1609416022c9SBarry Smith v = a->a; 161017ab2063SBarry Smith for (i=0; i<m; i++) { 161117ab2063SBarry Smith x = l[i]; 1612416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 161317ab2063SBarry Smith for (j=0; j<M; j++) { (*v++) *= x;} 161417ab2063SBarry Smith } 16151ebc52fbSHong Zhang ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 1616b0a32e0cSBarry Smith PetscLogFlops(nz); 161717ab2063SBarry Smith } 161817ab2063SBarry Smith if (rr) { 1619e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 1620273d9f13SBarry Smith if (n != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 16211ebc52fbSHong Zhang ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 1622416022c9SBarry Smith v = a->a; jj = a->j; 162317ab2063SBarry Smith for (i=0; i<nz; i++) { 1624bfeeae90SHong Zhang (*v++) *= r[*jj++]; 162517ab2063SBarry Smith } 16261ebc52fbSHong Zhang ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 1627b0a32e0cSBarry Smith PetscLogFlops(nz); 162817ab2063SBarry Smith } 16293a40ed3dSBarry Smith PetscFunctionReturn(0); 163017ab2063SBarry Smith } 163117ab2063SBarry Smith 16324a2ae208SSatish Balay #undef __FUNCT__ 16334a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ" 163497f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 163517ab2063SBarry Smith { 1636db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 16376849ba73SBarry Smith PetscErrorCode ierr; 163897f1f81fSBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->n,*lens; 163997f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 164097f1f81fSBarry Smith PetscInt *irow,*icol,nrows,ncols; 164197f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 164287828ca2SBarry Smith PetscScalar *a_new,*mat_a; 1643416022c9SBarry Smith Mat C; 1644fee21e36SBarry Smith PetscTruth stride; 164517ab2063SBarry Smith 16463a40ed3dSBarry Smith PetscFunctionBegin; 1647d64ed03dSBarry Smith ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr); 164829bbc08cSBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted"); 1649d64ed03dSBarry Smith ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr); 165029bbc08cSBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted"); 165199141d43SSatish Balay 165217ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 1653b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 1654b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 165517ab2063SBarry Smith 1656fee21e36SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 1657fee21e36SBarry Smith ierr = ISStride(iscol,&stride);CHKERRQ(ierr); 1658fee21e36SBarry Smith if (stride && step == 1) { 165902834360SBarry Smith /* special case of contiguous rows */ 166097f1f81fSBarry Smith ierr = PetscMalloc((2*nrows+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 166131ebf83bSSatish Balay starts = lens + nrows; 166202834360SBarry Smith /* loop over new rows determining lens and starting points */ 166302834360SBarry Smith for (i=0; i<nrows; i++) { 1664bfeeae90SHong Zhang kstart = ai[irow[i]]; 1665a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 166602834360SBarry Smith for (k=kstart; k<kend; k++) { 1667bfeeae90SHong Zhang if (aj[k] >= first) { 166802834360SBarry Smith starts[i] = k; 166902834360SBarry Smith break; 167002834360SBarry Smith } 167102834360SBarry Smith } 1672a2744918SBarry Smith sum = 0; 167302834360SBarry Smith while (k < kend) { 1674bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 1675a2744918SBarry Smith sum++; 167602834360SBarry Smith } 1677a2744918SBarry Smith lens[i] = sum; 167802834360SBarry Smith } 167902834360SBarry Smith /* create submatrix */ 1680cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 168197f1f81fSBarry Smith PetscInt n_cols,n_rows; 168208480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 168329bbc08cSBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 1684d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 168508480c60SBarry Smith C = *B; 16863a40ed3dSBarry Smith } else { 1687e2d9671bSKris Buschelman ierr = MatCreate(A->comm,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE,&C);CHKERRQ(ierr); 1688e2d9671bSKris Buschelman ierr = MatSetType(C,A->type_name);CHKERRQ(ierr); 1689e2d9671bSKris Buschelman ierr = MatSeqAIJSetPreallocation(C,0,lens);CHKERRQ(ierr); 169008480c60SBarry Smith } 1691db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 1692db02288aSLois Curfman McInnes 169302834360SBarry Smith /* loop over rows inserting into submatrix */ 1694db02288aSLois Curfman McInnes a_new = c->a; 1695db02288aSLois Curfman McInnes j_new = c->j; 1696db02288aSLois Curfman McInnes i_new = c->i; 1697bfeeae90SHong Zhang 169802834360SBarry Smith for (i=0; i<nrows; i++) { 1699a2744918SBarry Smith ii = starts[i]; 1700a2744918SBarry Smith lensi = lens[i]; 1701a2744918SBarry Smith for (k=0; k<lensi; k++) { 1702a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 170302834360SBarry Smith } 170487828ca2SBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr); 1705a2744918SBarry Smith a_new += lensi; 1706a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 1707a2744918SBarry Smith c->ilen[i] = lensi; 170802834360SBarry Smith } 1709606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 17103a40ed3dSBarry Smith } else { 171102834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 171297f1f81fSBarry Smith ierr = PetscMalloc((1+oldcols)*sizeof(PetscInt),&smap);CHKERRQ(ierr); 1713bfeeae90SHong Zhang 171497f1f81fSBarry Smith ierr = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 171597f1f81fSBarry Smith ierr = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr); 171617ab2063SBarry Smith for (i=0; i<ncols; i++) smap[icol[i]] = i+1; 171702834360SBarry Smith /* determine lens of each row */ 171802834360SBarry Smith for (i=0; i<nrows; i++) { 1719bfeeae90SHong Zhang kstart = ai[irow[i]]; 172002834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 172102834360SBarry Smith lens[i] = 0; 172202834360SBarry Smith for (k=kstart; k<kend; k++) { 1723bfeeae90SHong Zhang if (smap[aj[k]]) { 172402834360SBarry Smith lens[i]++; 172502834360SBarry Smith } 172602834360SBarry Smith } 172702834360SBarry Smith } 172817ab2063SBarry Smith /* Create and fill new matrix */ 1729a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 17300f5bd95cSBarry Smith PetscTruth equal; 17310f5bd95cSBarry Smith 173299141d43SSatish Balay c = (Mat_SeqAIJ *)((*B)->data); 1733273d9f13SBarry Smith if ((*B)->m != nrows || (*B)->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 173497f1f81fSBarry Smith ierr = PetscMemcmp(c->ilen,lens,(*B)->m*sizeof(PetscInt),&equal);CHKERRQ(ierr); 17350f5bd95cSBarry Smith if (!equal) { 173629bbc08cSBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 173799141d43SSatish Balay } 173897f1f81fSBarry Smith ierr = PetscMemzero(c->ilen,(*B)->m*sizeof(PetscInt));CHKERRQ(ierr); 173908480c60SBarry Smith C = *B; 17403a40ed3dSBarry Smith } else { 1741e2d9671bSKris Buschelman ierr = MatCreate(A->comm,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE,&C);CHKERRQ(ierr); 1742e2d9671bSKris Buschelman ierr = MatSetType(C,A->type_name);CHKERRQ(ierr); 1743e2d9671bSKris Buschelman ierr = MatSeqAIJSetPreallocation(C,0,lens);CHKERRQ(ierr); 174408480c60SBarry Smith } 174599141d43SSatish Balay c = (Mat_SeqAIJ *)(C->data); 174617ab2063SBarry Smith for (i=0; i<nrows; i++) { 174799141d43SSatish Balay row = irow[i]; 1748bfeeae90SHong Zhang kstart = ai[row]; 174999141d43SSatish Balay kend = kstart + a->ilen[row]; 1750bfeeae90SHong Zhang mat_i = c->i[i]; 175199141d43SSatish Balay mat_j = c->j + mat_i; 175299141d43SSatish Balay mat_a = c->a + mat_i; 175399141d43SSatish Balay mat_ilen = c->ilen + i; 175417ab2063SBarry Smith for (k=kstart; k<kend; k++) { 1755bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 1756ed480e8bSBarry Smith *mat_j++ = tcol - 1; 175799141d43SSatish Balay *mat_a++ = a->a[k]; 175899141d43SSatish Balay (*mat_ilen)++; 175999141d43SSatish Balay 176017ab2063SBarry Smith } 176117ab2063SBarry Smith } 176217ab2063SBarry Smith } 176302834360SBarry Smith /* Free work space */ 176402834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 1765606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 1766606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 176702834360SBarry Smith } 17686d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17696d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 177017ab2063SBarry Smith 177117ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 1772416022c9SBarry Smith *B = C; 17733a40ed3dSBarry Smith PetscFunctionReturn(0); 177417ab2063SBarry Smith } 177517ab2063SBarry Smith 1776a871dcd8SBarry Smith /* 1777a871dcd8SBarry Smith */ 17784a2ae208SSatish Balay #undef __FUNCT__ 17794a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ" 1780dfbe8321SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatFactorInfo *info) 1781a871dcd8SBarry Smith { 178263b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 1783dfbe8321SBarry Smith PetscErrorCode ierr; 178463b91edcSBarry Smith Mat outA; 1785b8a78c4aSBarry Smith PetscTruth row_identity,col_identity; 178663b91edcSBarry Smith 17873a40ed3dSBarry Smith PetscFunctionBegin; 1788d3d32019SBarry Smith if (info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 1789b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 1790b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 1791b8a78c4aSBarry Smith if (!row_identity || !col_identity) { 1792634064b4SBarry Smith SETERRQ(PETSC_ERR_ARG_WRONG,"Row and column permutations must be identity for in-place ILU"); 1793b8a78c4aSBarry Smith } 1794a871dcd8SBarry Smith 179563b91edcSBarry Smith outA = inA; 179663b91edcSBarry Smith inA->factor = FACTOR_LU; 179763b91edcSBarry Smith a->row = row; 179863b91edcSBarry Smith a->col = col; 1799c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1800c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 180163b91edcSBarry Smith 180236db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 1803b9b97703SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */ 18044c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 1805b0a32e0cSBarry Smith PetscLogObjectParent(inA,a->icol); 1806f0ec6fceSSatish Balay 180794a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 180887828ca2SBarry Smith ierr = PetscMalloc((inA->m+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr); 180994a9d846SBarry Smith } 181063b91edcSBarry Smith 181108480c60SBarry Smith if (!a->diag) { 1812f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 181363b91edcSBarry Smith } 181463b91edcSBarry Smith ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA);CHKERRQ(ierr); 18153a40ed3dSBarry Smith PetscFunctionReturn(0); 1816a871dcd8SBarry Smith } 1817a871dcd8SBarry Smith 1818d9eff348SSatish Balay #include "petscblaslapack.h" 18194a2ae208SSatish Balay #undef __FUNCT__ 18204a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ" 1821dfbe8321SBarry Smith PetscErrorCode MatScale_SeqAIJ(const PetscScalar *alpha,Mat inA) 1822f0b747eeSBarry Smith { 1823f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 18244ce68768SBarry Smith PetscBLASInt bnz = (PetscBLASInt)a->nz,one = 1; 18253a40ed3dSBarry Smith 18263a40ed3dSBarry Smith PetscFunctionBegin; 18274ce68768SBarry Smith BLscal_(&bnz,(PetscScalar*)alpha,a->a,&one); 1828b0a32e0cSBarry Smith PetscLogFlops(a->nz); 18293a40ed3dSBarry Smith PetscFunctionReturn(0); 1830f0b747eeSBarry Smith } 1831f0b747eeSBarry Smith 18324a2ae208SSatish Balay #undef __FUNCT__ 18334a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ" 183497f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 1835cddf8d76SBarry Smith { 1836dfbe8321SBarry Smith PetscErrorCode ierr; 183797f1f81fSBarry Smith PetscInt i; 1838cddf8d76SBarry Smith 18393a40ed3dSBarry Smith PetscFunctionBegin; 1840cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 1841b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr); 1842cddf8d76SBarry Smith } 1843cddf8d76SBarry Smith 1844cddf8d76SBarry Smith for (i=0; i<n; i++) { 18456a6a5d1dSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 1846cddf8d76SBarry Smith } 18473a40ed3dSBarry Smith PetscFunctionReturn(0); 1848cddf8d76SBarry Smith } 1849cddf8d76SBarry Smith 18504a2ae208SSatish Balay #undef __FUNCT__ 18514a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ" 185297f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 18534dcbc457SBarry Smith { 1854e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18556849ba73SBarry Smith PetscErrorCode ierr; 185697f1f81fSBarry Smith PetscInt row,i,j,k,l,m,n,*idx,*nidx,isz,val; 185797f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 1858f1af5d2fSBarry Smith PetscBT table; 1859bbd702dbSSatish Balay 18603a40ed3dSBarry Smith PetscFunctionBegin; 1861273d9f13SBarry Smith m = A->m; 1862e4d965acSSatish Balay ai = a->i; 1863bfeeae90SHong Zhang aj = a->j; 18648a047759SSatish Balay 1865a45adfd6SMatthew Knepley if (ov < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 186606763907SSatish Balay 186797f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr); 18686831982aSBarry Smith ierr = PetscBTCreate(m,table);CHKERRQ(ierr); 186906763907SSatish Balay 1870e4d965acSSatish Balay for (i=0; i<is_max; i++) { 1871b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 1872e4d965acSSatish Balay isz = 0; 18736831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 1874e4d965acSSatish Balay 1875e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 18764dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 1877b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 1878e4d965acSSatish Balay 1879dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 1880e4d965acSSatish Balay for (j=0; j<n ; ++j){ 1881f1af5d2fSBarry Smith if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];} 18824dcbc457SBarry Smith } 188306763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 188406763907SSatish Balay ierr = ISDestroy(is[i]);CHKERRQ(ierr); 1885e4d965acSSatish Balay 188604a348a9SBarry Smith k = 0; 188704a348a9SBarry Smith for (j=0; j<ov; j++){ /* for each overlap */ 188804a348a9SBarry Smith n = isz; 188906763907SSatish Balay for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */ 1890e4d965acSSatish Balay row = nidx[k]; 1891e4d965acSSatish Balay start = ai[row]; 1892e4d965acSSatish Balay end = ai[row+1]; 189304a348a9SBarry Smith for (l = start; l<end ; l++){ 1894efb16452SHong Zhang val = aj[l] ; 1895f1af5d2fSBarry Smith if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;} 1896e4d965acSSatish Balay } 1897e4d965acSSatish Balay } 1898e4d965acSSatish Balay } 1899029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr); 1900e4d965acSSatish Balay } 19016831982aSBarry Smith ierr = PetscBTDestroy(table);CHKERRQ(ierr); 1902606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 19033a40ed3dSBarry Smith PetscFunctionReturn(0); 19044dcbc457SBarry Smith } 190517ab2063SBarry Smith 19060513a670SBarry Smith /* -------------------------------------------------------------- */ 19074a2ae208SSatish Balay #undef __FUNCT__ 19084a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ" 1909dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 19100513a670SBarry Smith { 19110513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 19126849ba73SBarry Smith PetscErrorCode ierr; 191397f1f81fSBarry Smith PetscInt i,nz,m = A->m,n = A->n,*col; 191497f1f81fSBarry Smith PetscInt *row,*cnew,j,*lens; 191556cd22aeSBarry Smith IS icolp,irowp; 191697f1f81fSBarry Smith PetscInt *cwork; 191732ec9ce4SBarry Smith PetscScalar *vwork; 19180513a670SBarry Smith 19193a40ed3dSBarry Smith PetscFunctionBegin; 19204c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 192156cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 19224c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 192356cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 19240513a670SBarry Smith 19250513a670SBarry Smith /* determine lengths of permuted rows */ 192697f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 19270513a670SBarry Smith for (i=0; i<m; i++) { 19280513a670SBarry Smith lens[row[i]] = a->i[i+1] - a->i[i]; 19290513a670SBarry Smith } 1930f204ca49SKris Buschelman ierr = MatCreate(A->comm,m,n,m,n,B);CHKERRQ(ierr); 1931f204ca49SKris Buschelman ierr = MatSetType(*B,A->type_name);CHKERRQ(ierr); 1932f204ca49SKris Buschelman ierr = MatSeqAIJSetPreallocation(*B,0,lens);CHKERRQ(ierr); 1933606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 19340513a670SBarry Smith 193597f1f81fSBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr); 19360513a670SBarry Smith for (i=0; i<m; i++) { 193732ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 19380513a670SBarry Smith for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];} 1939cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 194032ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 19410513a670SBarry Smith } 1942606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 19433c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 19440513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 19450513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 194656cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 194756cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 194856cd22aeSBarry Smith ierr = ISDestroy(irowp);CHKERRQ(ierr); 194956cd22aeSBarry Smith ierr = ISDestroy(icolp);CHKERRQ(ierr); 19503a40ed3dSBarry Smith PetscFunctionReturn(0); 19510513a670SBarry Smith } 19520513a670SBarry Smith 19534a2ae208SSatish Balay #undef __FUNCT__ 19544a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqAIJ" 1955dfbe8321SBarry Smith PetscErrorCode MatPrintHelp_SeqAIJ(Mat A) 1956682d7d0cSBarry Smith { 1957c38d4ed2SBarry Smith static PetscTruth called = PETSC_FALSE; 1958682d7d0cSBarry Smith MPI_Comm comm = A->comm; 1959dfbe8321SBarry Smith PetscErrorCode ierr; 1960682d7d0cSBarry Smith 19613a40ed3dSBarry Smith PetscFunctionBegin; 1962c38d4ed2SBarry Smith if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE; 1963d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr); 1964d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr); 1965d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr); 1966d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_no_inode: Do not use inodes\n");CHKERRQ(ierr); 1967d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");CHKERRQ(ierr); 196873e7a558SHong Zhang ierr = (*PetscHelpPrintf)(comm," -mat_no_compressedrow: Do not use compressedrow\n");CHKERRQ(ierr); 19693a40ed3dSBarry Smith PetscFunctionReturn(0); 1970682d7d0cSBarry Smith } 197197304618SKris Buschelman 19724a2ae208SSatish Balay #undef __FUNCT__ 19734a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ" 1974dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 1975cb5b572fSBarry Smith { 1976dfbe8321SBarry Smith PetscErrorCode ierr; 1977cb5b572fSBarry Smith 1978cb5b572fSBarry Smith PetscFunctionBegin; 197933f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 198033f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 1981be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1982be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 1983be6bf707SBarry Smith 1984bfeeae90SHong Zhang if (a->i[A->m] != b->i[B->m]) { 1985634064b4SBarry Smith SETERRQ(PETSC_ERR_ARG_INCOMP,"Number of nonzeros in two matrices are different"); 1986cb5b572fSBarry Smith } 1987bfeeae90SHong Zhang ierr = PetscMemcpy(b->a,a->a,(a->i[A->m])*sizeof(PetscScalar));CHKERRQ(ierr); 1988cb5b572fSBarry Smith } else { 1989cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1990cb5b572fSBarry Smith } 1991cb5b572fSBarry Smith PetscFunctionReturn(0); 1992cb5b572fSBarry Smith } 1993cb5b572fSBarry Smith 19944a2ae208SSatish Balay #undef __FUNCT__ 19954a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ" 1996dfbe8321SBarry Smith PetscErrorCode MatSetUpPreallocation_SeqAIJ(Mat A) 1997273d9f13SBarry Smith { 1998dfbe8321SBarry Smith PetscErrorCode ierr; 1999273d9f13SBarry Smith 2000273d9f13SBarry Smith PetscFunctionBegin; 2001273d9f13SBarry Smith ierr = MatSeqAIJSetPreallocation(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 2002273d9f13SBarry Smith PetscFunctionReturn(0); 2003273d9f13SBarry Smith } 2004273d9f13SBarry Smith 20054a2ae208SSatish Balay #undef __FUNCT__ 20064a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ" 2007dfbe8321SBarry Smith PetscErrorCode MatGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 20086c0721eeSBarry Smith { 20096c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 20106c0721eeSBarry Smith PetscFunctionBegin; 20116c0721eeSBarry Smith *array = a->a; 20126c0721eeSBarry Smith PetscFunctionReturn(0); 20136c0721eeSBarry Smith } 20146c0721eeSBarry Smith 20154a2ae208SSatish Balay #undef __FUNCT__ 20164a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ" 2017dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 20186c0721eeSBarry Smith { 20196c0721eeSBarry Smith PetscFunctionBegin; 20206c0721eeSBarry Smith PetscFunctionReturn(0); 20216c0721eeSBarry Smith } 2022273d9f13SBarry Smith 2023ee4f033dSBarry Smith #undef __FUNCT__ 2024ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ" 2025dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 2026ee4f033dSBarry Smith { 20276849ba73SBarry Smith PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f; 20286849ba73SBarry Smith PetscErrorCode ierr; 202997f1f81fSBarry Smith PetscInt k,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2; 203087828ca2SBarry Smith PetscScalar dx,mone = -1.0,*y,*xx,*w3_array; 203187828ca2SBarry Smith PetscScalar *vscale_array; 2032ee4f033dSBarry Smith PetscReal epsilon = coloring->error_rel,umin = coloring->umin; 2033ee4f033dSBarry Smith Vec w1,w2,w3; 2034ee4f033dSBarry Smith void *fctx = coloring->fctx; 2035ee4f033dSBarry Smith PetscTruth flg; 2036ee4f033dSBarry Smith 2037ee4f033dSBarry Smith PetscFunctionBegin; 2038ee4f033dSBarry Smith if (!coloring->w1) { 2039ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr); 2040ee4f033dSBarry Smith PetscLogObjectParent(coloring,coloring->w1); 2041ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr); 2042ee4f033dSBarry Smith PetscLogObjectParent(coloring,coloring->w2); 2043ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr); 2044ee4f033dSBarry Smith PetscLogObjectParent(coloring,coloring->w3); 2045ee4f033dSBarry Smith } 2046ee4f033dSBarry Smith w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3; 2047ee4f033dSBarry Smith 2048ee4f033dSBarry Smith ierr = MatSetUnfactored(J);CHKERRQ(ierr); 2049e82a3eeeSBarry Smith ierr = PetscOptionsHasName(coloring->prefix,"-mat_fd_coloring_dont_rezero",&flg);CHKERRQ(ierr); 2050ee4f033dSBarry Smith if (flg) { 2051ee4f033dSBarry Smith PetscLogInfo(coloring,"MatFDColoringApply_SeqAIJ: Not calling MatZeroEntries()\n"); 2052ee4f033dSBarry Smith } else { 20530b9b6f31SBarry Smith PetscTruth assembled; 20540b9b6f31SBarry Smith ierr = MatAssembled(J,&assembled);CHKERRQ(ierr); 20550b9b6f31SBarry Smith if (assembled) { 2056ee4f033dSBarry Smith ierr = MatZeroEntries(J);CHKERRQ(ierr); 2057ee4f033dSBarry Smith } 20580b9b6f31SBarry Smith } 2059ee4f033dSBarry Smith 2060ee4f033dSBarry Smith ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr); 2061ee4f033dSBarry Smith ierr = VecGetSize(x1,&N);CHKERRQ(ierr); 2062ee4f033dSBarry Smith 2063ee4f033dSBarry Smith /* 2064ee4f033dSBarry Smith This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets 2065ee4f033dSBarry Smith coloring->F for the coarser grids from the finest 2066ee4f033dSBarry Smith */ 2067ee4f033dSBarry Smith if (coloring->F) { 2068ee4f033dSBarry Smith ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr); 2069ee4f033dSBarry Smith ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr); 2070ee4f033dSBarry Smith if (m1 != m2) { 2071ee4f033dSBarry Smith coloring->F = 0; 2072ee4f033dSBarry Smith } 2073ee4f033dSBarry Smith } 2074ee4f033dSBarry Smith 2075ee4f033dSBarry Smith if (coloring->F) { 2076ee4f033dSBarry Smith w1 = coloring->F; 2077ee4f033dSBarry Smith coloring->F = 0; 2078ee4f033dSBarry Smith } else { 207966f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2080ee4f033dSBarry Smith ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr); 208166f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2082ee4f033dSBarry Smith } 2083ee4f033dSBarry Smith 2084ee4f033dSBarry Smith /* 2085ee4f033dSBarry Smith Compute all the scale factors and share with other processors 2086ee4f033dSBarry Smith */ 20871ebc52fbSHong Zhang ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start; 20881ebc52fbSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start; 2089ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 2090ee4f033dSBarry Smith /* 2091ee4f033dSBarry Smith Loop over each column associated with color adding the 2092ee4f033dSBarry Smith perturbation to the vector w3. 2093ee4f033dSBarry Smith */ 2094ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 2095ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 2096ee4f033dSBarry Smith dx = xx[col]; 2097ee4f033dSBarry Smith if (dx == 0.0) dx = 1.0; 2098ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 2099ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 2100ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 2101ee4f033dSBarry Smith #else 2102ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2103ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2104ee4f033dSBarry Smith #endif 2105ee4f033dSBarry Smith dx *= epsilon; 2106ee4f033dSBarry Smith vscale_array[col] = 1.0/dx; 2107ee4f033dSBarry Smith } 2108ee4f033dSBarry Smith } 21091ebc52fbSHong Zhang vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2110ee4f033dSBarry Smith ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2111ee4f033dSBarry Smith ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2112ee4f033dSBarry Smith 2113ee4f033dSBarry Smith /* ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD); 2114ee4f033dSBarry Smith ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/ 2115ee4f033dSBarry Smith 2116ee4f033dSBarry Smith if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow; 2117ee4f033dSBarry Smith else vscaleforrow = coloring->columnsforrow; 2118ee4f033dSBarry Smith 21191ebc52fbSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2120ee4f033dSBarry Smith /* 2121ee4f033dSBarry Smith Loop over each color 2122ee4f033dSBarry Smith */ 2123ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 212449b058dcSBarry Smith coloring->currentcolor = k; 2125ee4f033dSBarry Smith ierr = VecCopy(x1,w3);CHKERRQ(ierr); 21261ebc52fbSHong Zhang ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start; 2127ee4f033dSBarry Smith /* 2128ee4f033dSBarry Smith Loop over each column associated with color adding the 2129ee4f033dSBarry Smith perturbation to the vector w3. 2130ee4f033dSBarry Smith */ 2131ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 2132ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 2133ee4f033dSBarry Smith dx = xx[col]; 21345b8514ebSBarry Smith if (dx == 0.0) dx = 1.0; 2135ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 2136ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 2137ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 2138ee4f033dSBarry Smith #else 2139ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2140ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2141ee4f033dSBarry Smith #endif 2142ee4f033dSBarry Smith dx *= epsilon; 2143634064b4SBarry Smith if (!PetscAbsScalar(dx)) SETERRQ(PETSC_ERR_PLIB,"Computed 0 differencing parameter"); 2144ee4f033dSBarry Smith w3_array[col] += dx; 2145ee4f033dSBarry Smith } 21461ebc52fbSHong Zhang w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr); 2147ee4f033dSBarry Smith 2148ee4f033dSBarry Smith /* 2149ee4f033dSBarry Smith Evaluate function at x1 + dx (here dx is a vector of perturbations) 2150ee4f033dSBarry Smith */ 2151ee4f033dSBarry Smith 215266f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2153ee4f033dSBarry Smith ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr); 215466f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2155ee4f033dSBarry Smith ierr = VecAXPY(&mone,w1,w2);CHKERRQ(ierr); 2156ee4f033dSBarry Smith 2157ee4f033dSBarry Smith /* 2158ee4f033dSBarry Smith Loop over rows of vector, putting results into Jacobian matrix 2159ee4f033dSBarry Smith */ 21601ebc52fbSHong Zhang ierr = VecGetArray(w2,&y);CHKERRQ(ierr); 2161ee4f033dSBarry Smith for (l=0; l<coloring->nrows[k]; l++) { 2162ee4f033dSBarry Smith row = coloring->rows[k][l]; 2163ee4f033dSBarry Smith col = coloring->columnsforrow[k][l]; 2164ee4f033dSBarry Smith y[row] *= vscale_array[vscaleforrow[k][l]]; 2165ee4f033dSBarry Smith srow = row + start; 2166ee4f033dSBarry Smith ierr = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr); 2167ee4f033dSBarry Smith } 21681ebc52fbSHong Zhang ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr); 2169ee4f033dSBarry Smith } 217049b058dcSBarry Smith coloring->currentcolor = k; 21711ebc52fbSHong Zhang ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 21721ebc52fbSHong Zhang xx = xx + start; ierr = VecRestoreArray(x1,&xx);CHKERRQ(ierr); 2173ee4f033dSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2174ee4f033dSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2175ee4f033dSBarry Smith PetscFunctionReturn(0); 2176ee4f033dSBarry Smith } 2177ee4f033dSBarry Smith 2178ac90fabeSBarry Smith #include "petscblaslapack.h" 2179ac90fabeSBarry Smith #undef __FUNCT__ 2180ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ" 2181dfbe8321SBarry Smith PetscErrorCode MatAXPY_SeqAIJ(const PetscScalar a[],Mat X,Mat Y,MatStructure str) 2182ac90fabeSBarry Smith { 2183dfbe8321SBarry Smith PetscErrorCode ierr; 218497f1f81fSBarry Smith PetscInt i; 2185ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data; 21864ce68768SBarry Smith PetscBLASInt one=1,bnz = (PetscBLASInt)x->nz; 2187ac90fabeSBarry Smith 2188ac90fabeSBarry Smith PetscFunctionBegin; 2189ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 21904ce68768SBarry Smith BLaxpy_(&bnz,(PetscScalar*)a,x->a,&one,y->a,&one); 2191c537a176SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 2192a30b2313SHong Zhang if (y->xtoy && y->XtoY != X) { 2193a30b2313SHong Zhang ierr = PetscFree(y->xtoy);CHKERRQ(ierr); 2194a30b2313SHong Zhang ierr = MatDestroy(y->XtoY);CHKERRQ(ierr); 2195a30b2313SHong Zhang } 2196a30b2313SHong Zhang if (!y->xtoy) { /* get xtoy */ 219724f910e3SHong Zhang ierr = MatAXPYGetxtoy_Private(X->m,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr); 2198a30b2313SHong Zhang y->XtoY = X; 2199c537a176SHong Zhang } 2200a30b2313SHong Zhang for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += (*a)*(x->a[i]); 2201e2dd4fc4Svictorle PetscLogInfo(0,"MatAXPY_SeqAIJ: ratio of nnz(X)/nnz(Y): %d/%d = %g\n",x->nz,y->nz,(PetscReal)(x->nz)/y->nz); 2202ac90fabeSBarry Smith } else { 2203ac90fabeSBarry Smith ierr = MatAXPY_Basic(a,X,Y,str);CHKERRQ(ierr); 2204ac90fabeSBarry Smith } 2205ac90fabeSBarry Smith PetscFunctionReturn(0); 2206ac90fabeSBarry Smith } 2207ac90fabeSBarry Smith 2208521d7252SBarry Smith #undef __FUNCT__ 2209521d7252SBarry Smith #define __FUNCT__ "MatSetBlockSize_SeqAIJ" 2210521d7252SBarry Smith PetscErrorCode MatSetBlockSize_SeqAIJ(Mat A,PetscInt bs) 2211521d7252SBarry Smith { 2212521d7252SBarry Smith PetscFunctionBegin; 2213521d7252SBarry Smith PetscFunctionReturn(0); 2214521d7252SBarry Smith } 2215521d7252SBarry Smith 2216682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 22170a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ, 2218cb5b572fSBarry Smith MatGetRow_SeqAIJ, 2219cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 2220cb5b572fSBarry Smith MatMult_SeqAIJ, 222197304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 22227c922b88SBarry Smith MatMultTranspose_SeqAIJ, 22237c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 2224cb5b572fSBarry Smith MatSolve_SeqAIJ, 2225cb5b572fSBarry Smith MatSolveAdd_SeqAIJ, 22267c922b88SBarry Smith MatSolveTranspose_SeqAIJ, 222797304618SKris Buschelman /*10*/ MatSolveTransposeAdd_SeqAIJ, 2228cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 2229cb5b572fSBarry Smith 0, 223017ab2063SBarry Smith MatRelax_SeqAIJ, 223117ab2063SBarry Smith MatTranspose_SeqAIJ, 223297304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ, 2233cb5b572fSBarry Smith MatEqual_SeqAIJ, 2234cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 2235cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 2236cb5b572fSBarry Smith MatNorm_SeqAIJ, 223797304618SKris Buschelman /*20*/ 0, 2238cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 223917ab2063SBarry Smith MatCompress_SeqAIJ, 2240cb5b572fSBarry Smith MatSetOption_SeqAIJ, 2241cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 224297304618SKris Buschelman /*25*/ MatZeroRows_SeqAIJ, 2243cb5b572fSBarry Smith MatLUFactorSymbolic_SeqAIJ, 2244cb5b572fSBarry Smith MatLUFactorNumeric_SeqAIJ, 2245f76d2b81SHong Zhang MatCholeskyFactorSymbolic_SeqAIJ, 2246a6175056SHong Zhang MatCholeskyFactorNumeric_SeqAIJ, 224797304618SKris Buschelman /*30*/ MatSetUpPreallocation_SeqAIJ, 2248cb5b572fSBarry Smith MatILUFactorSymbolic_SeqAIJ, 2249861ba921SHong Zhang MatICCFactorSymbolic_SeqAIJ, 22506c0721eeSBarry Smith MatGetArray_SeqAIJ, 22516c0721eeSBarry Smith MatRestoreArray_SeqAIJ, 225297304618SKris Buschelman /*35*/ MatDuplicate_SeqAIJ, 2253cb5b572fSBarry Smith 0, 2254cb5b572fSBarry Smith 0, 2255cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 2256cb5b572fSBarry Smith 0, 225797304618SKris Buschelman /*40*/ MatAXPY_SeqAIJ, 2258cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 2259cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 2260cb5b572fSBarry Smith MatGetValues_SeqAIJ, 2261cb5b572fSBarry Smith MatCopy_SeqAIJ, 226297304618SKris Buschelman /*45*/ MatPrintHelp_SeqAIJ, 2263cb5b572fSBarry Smith MatScale_SeqAIJ, 2264cb5b572fSBarry Smith 0, 2265cb5b572fSBarry Smith 0, 22666945ee14SBarry Smith MatILUDTFactor_SeqAIJ, 2267521d7252SBarry Smith /*50*/ MatSetBlockSize_SeqAIJ, 22683b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 22693b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 22703b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 2271a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 227297304618SKris Buschelman /*55*/ MatFDColoringCreate_SeqAIJ, 2273b9617806SBarry Smith 0, 22740513a670SBarry Smith 0, 2275cda55fadSBarry Smith MatPermute_SeqAIJ, 2276cda55fadSBarry Smith 0, 227797304618SKris Buschelman /*60*/ 0, 2278b9b97703SBarry Smith MatDestroy_SeqAIJ, 2279b9b97703SBarry Smith MatView_SeqAIJ, 22808a124369SBarry Smith MatGetPetscMaps_Petsc, 2281ee4f033dSBarry Smith 0, 228297304618SKris Buschelman /*65*/ 0, 2283ee4f033dSBarry Smith 0, 2284ee4f033dSBarry Smith 0, 2285ee4f033dSBarry Smith 0, 2286ee4f033dSBarry Smith 0, 228797304618SKris Buschelman /*70*/ 0, 2288ee4f033dSBarry Smith 0, 2289ee4f033dSBarry Smith MatSetColoring_SeqAIJ, 2290ee4f033dSBarry Smith MatSetValuesAdic_SeqAIJ, 2291ee4f033dSBarry Smith MatSetValuesAdifor_SeqAIJ, 229297304618SKris Buschelman /*75*/ MatFDColoringApply_SeqAIJ, 229397304618SKris Buschelman 0, 229497304618SKris Buschelman 0, 229597304618SKris Buschelman 0, 229697304618SKris Buschelman 0, 229797304618SKris Buschelman /*80*/ 0, 229897304618SKris Buschelman 0, 229997304618SKris Buschelman 0, 230097304618SKris Buschelman 0, 2301bc011b1eSHong Zhang MatLoad_SeqAIJ, 2302bc011b1eSHong Zhang /*85*/ MatIsSymmetric_SeqAIJ, 23036284ec50SHong Zhang 0, 23046284ec50SHong Zhang 0, 23056284ec50SHong Zhang 0, 2306bc011b1eSHong Zhang 0, 2307bc011b1eSHong Zhang /*90*/ MatMatMult_SeqAIJ_SeqAIJ, 230826be0446SHong Zhang MatMatMultSymbolic_SeqAIJ_SeqAIJ, 230926be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 23109af31e4aSHong Zhang MatPtAP_SeqAIJ_SeqAIJ, 2311bc011b1eSHong Zhang MatPtAPSymbolic_SeqAIJ_SeqAIJ, 2312bc011b1eSHong Zhang /*95*/ MatPtAPNumeric_SeqAIJ_SeqAIJ, 2313bc011b1eSHong Zhang MatMatMultTranspose_SeqAIJ_SeqAIJ, 2314bc011b1eSHong Zhang MatMatMultTransposeSymbolic_SeqAIJ_SeqAIJ, 2315bc011b1eSHong Zhang MatMatMultTransposeNumeric_SeqAIJ_SeqAIJ, 23169e29f15eSvictorle }; 231717ab2063SBarry Smith 2318fb2e594dSBarry Smith EXTERN_C_BEGIN 23194a2ae208SSatish Balay #undef __FUNCT__ 23204a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ" 232197f1f81fSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 2322bef8e0ddSBarry Smith { 2323bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 232497f1f81fSBarry Smith PetscInt i,nz,n; 2325bef8e0ddSBarry Smith 2326bef8e0ddSBarry Smith PetscFunctionBegin; 2327bef8e0ddSBarry Smith 2328bef8e0ddSBarry Smith nz = aij->maxnz; 2329273d9f13SBarry Smith n = mat->n; 2330bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 2331bef8e0ddSBarry Smith aij->j[i] = indices[i]; 2332bef8e0ddSBarry Smith } 2333bef8e0ddSBarry Smith aij->nz = nz; 2334bef8e0ddSBarry Smith for (i=0; i<n; i++) { 2335bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 2336bef8e0ddSBarry Smith } 2337bef8e0ddSBarry Smith 2338bef8e0ddSBarry Smith PetscFunctionReturn(0); 2339bef8e0ddSBarry Smith } 2340fb2e594dSBarry Smith EXTERN_C_END 2341bef8e0ddSBarry Smith 23424a2ae208SSatish Balay #undef __FUNCT__ 23434a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices" 2344bef8e0ddSBarry Smith /*@ 2345bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 2346bef8e0ddSBarry Smith in the matrix. 2347bef8e0ddSBarry Smith 2348bef8e0ddSBarry Smith Input Parameters: 2349bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 2350bef8e0ddSBarry Smith - indices - the column indices 2351bef8e0ddSBarry Smith 235215091d37SBarry Smith Level: advanced 235315091d37SBarry Smith 2354bef8e0ddSBarry Smith Notes: 2355bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 2356bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 2357bef8e0ddSBarry Smith of the MatSetValues() operation. 2358bef8e0ddSBarry Smith 2359bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 2360bef8e0ddSBarry Smith MatCreateSeqAIJ(). 2361bef8e0ddSBarry Smith 2362bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 2363bef8e0ddSBarry Smith 2364b9617806SBarry Smith The indices should start with zero, not one. 2365b9617806SBarry Smith 2366bef8e0ddSBarry Smith @*/ 236797f1f81fSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 2368bef8e0ddSBarry Smith { 236997f1f81fSBarry Smith PetscErrorCode ierr,(*f)(Mat,PetscInt *); 2370bef8e0ddSBarry Smith 2371bef8e0ddSBarry Smith PetscFunctionBegin; 23724482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 23734482741eSBarry Smith PetscValidPointer(indices,2); 2374c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr); 2375bef8e0ddSBarry Smith if (f) { 2376bef8e0ddSBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 2377bef8e0ddSBarry Smith } else { 2378634064b4SBarry Smith SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to set column indices"); 2379bef8e0ddSBarry Smith } 2380bef8e0ddSBarry Smith PetscFunctionReturn(0); 2381bef8e0ddSBarry Smith } 2382bef8e0ddSBarry Smith 2383be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 2384be6bf707SBarry Smith 2385fb2e594dSBarry Smith EXTERN_C_BEGIN 23864a2ae208SSatish Balay #undef __FUNCT__ 23874a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ" 2388dfbe8321SBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 2389be6bf707SBarry Smith { 2390be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 23916849ba73SBarry Smith PetscErrorCode ierr; 23926849ba73SBarry Smith size_t nz = aij->i[mat->m]; 2393be6bf707SBarry Smith 2394be6bf707SBarry Smith PetscFunctionBegin; 2395be6bf707SBarry Smith if (aij->nonew != 1) { 2396634064b4SBarry Smith SETERRQ(PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2397be6bf707SBarry Smith } 2398be6bf707SBarry Smith 2399be6bf707SBarry Smith /* allocate space for values if not already there */ 2400be6bf707SBarry Smith if (!aij->saved_values) { 240187828ca2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr); 2402be6bf707SBarry Smith } 2403be6bf707SBarry Smith 2404be6bf707SBarry Smith /* copy values over */ 240587828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 2406be6bf707SBarry Smith PetscFunctionReturn(0); 2407be6bf707SBarry Smith } 2408fb2e594dSBarry Smith EXTERN_C_END 2409be6bf707SBarry Smith 24104a2ae208SSatish Balay #undef __FUNCT__ 2411b9617806SBarry Smith #define __FUNCT__ "MatStoreValues" 2412be6bf707SBarry Smith /*@ 2413be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 2414be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2415be6bf707SBarry Smith nonlinear portion. 2416be6bf707SBarry Smith 2417be6bf707SBarry Smith Collect on Mat 2418be6bf707SBarry Smith 2419be6bf707SBarry Smith Input Parameters: 2420be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2421be6bf707SBarry Smith 242215091d37SBarry Smith Level: advanced 242315091d37SBarry Smith 2424be6bf707SBarry Smith Common Usage, with SNESSolve(): 2425be6bf707SBarry Smith $ Create Jacobian matrix 2426be6bf707SBarry Smith $ Set linear terms into matrix 2427be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 2428be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 2429be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 2430be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2431be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2432be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 2433be6bf707SBarry Smith $ In your Jacobian routine 2434be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2435be6bf707SBarry Smith $ Set nonlinear terms in matrix 2436be6bf707SBarry Smith 2437be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 2438be6bf707SBarry Smith $ // build linear portion of Jacobian 2439be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2440be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2441be6bf707SBarry Smith $ loop over nonlinear iterations 2442be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2443be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 2444be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 2445be6bf707SBarry Smith $ Solve linear system with Jacobian 2446be6bf707SBarry Smith $ endloop 2447be6bf707SBarry Smith 2448be6bf707SBarry Smith Notes: 2449be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 2450be6bf707SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before 2451be6bf707SBarry Smith calling this routine. 2452be6bf707SBarry Smith 2453be6bf707SBarry Smith .seealso: MatRetrieveValues() 2454be6bf707SBarry Smith 2455be6bf707SBarry Smith @*/ 2456dfbe8321SBarry Smith PetscErrorCode MatStoreValues(Mat mat) 2457be6bf707SBarry Smith { 2458dfbe8321SBarry Smith PetscErrorCode ierr,(*f)(Mat); 2459be6bf707SBarry Smith 2460be6bf707SBarry Smith PetscFunctionBegin; 24614482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 246229bbc08cSBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 246329bbc08cSBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2464be6bf707SBarry Smith 2465c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void (**)(void))&f);CHKERRQ(ierr); 2466be6bf707SBarry Smith if (f) { 2467be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2468be6bf707SBarry Smith } else { 2469634064b4SBarry Smith SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to store values"); 2470be6bf707SBarry Smith } 2471be6bf707SBarry Smith PetscFunctionReturn(0); 2472be6bf707SBarry Smith } 2473be6bf707SBarry Smith 2474fb2e594dSBarry Smith EXTERN_C_BEGIN 24754a2ae208SSatish Balay #undef __FUNCT__ 24764a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ" 2477dfbe8321SBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 2478be6bf707SBarry Smith { 2479be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 24806849ba73SBarry Smith PetscErrorCode ierr; 248197f1f81fSBarry Smith PetscInt nz = aij->i[mat->m]; 2482be6bf707SBarry Smith 2483be6bf707SBarry Smith PetscFunctionBegin; 2484be6bf707SBarry Smith if (aij->nonew != 1) { 2485634064b4SBarry Smith SETERRQ(PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2486be6bf707SBarry Smith } 2487be6bf707SBarry Smith if (!aij->saved_values) { 2488634064b4SBarry Smith SETERRQ(PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 2489be6bf707SBarry Smith } 2490be6bf707SBarry Smith /* copy values over */ 249187828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 2492be6bf707SBarry Smith PetscFunctionReturn(0); 2493be6bf707SBarry Smith } 2494fb2e594dSBarry Smith EXTERN_C_END 2495be6bf707SBarry Smith 24964a2ae208SSatish Balay #undef __FUNCT__ 24974a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues" 2498be6bf707SBarry Smith /*@ 2499be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 2500be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2501be6bf707SBarry Smith nonlinear portion. 2502be6bf707SBarry Smith 2503be6bf707SBarry Smith Collect on Mat 2504be6bf707SBarry Smith 2505be6bf707SBarry Smith Input Parameters: 2506be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2507be6bf707SBarry Smith 250815091d37SBarry Smith Level: advanced 250915091d37SBarry Smith 2510be6bf707SBarry Smith .seealso: MatStoreValues() 2511be6bf707SBarry Smith 2512be6bf707SBarry Smith @*/ 2513dfbe8321SBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 2514be6bf707SBarry Smith { 2515dfbe8321SBarry Smith PetscErrorCode ierr,(*f)(Mat); 2516be6bf707SBarry Smith 2517be6bf707SBarry Smith PetscFunctionBegin; 25184482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 251929bbc08cSBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 252029bbc08cSBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2521be6bf707SBarry Smith 2522c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void (**)(void))&f);CHKERRQ(ierr); 2523be6bf707SBarry Smith if (f) { 2524be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2525be6bf707SBarry Smith } else { 2526634064b4SBarry Smith SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to retrieve values"); 2527be6bf707SBarry Smith } 2528be6bf707SBarry Smith PetscFunctionReturn(0); 2529be6bf707SBarry Smith } 2530be6bf707SBarry Smith 2531f83d6046SBarry Smith 2532be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 25334a2ae208SSatish Balay #undef __FUNCT__ 25344a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ" 253517ab2063SBarry Smith /*@C 2536682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 25370d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 25386e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 253951c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 25402bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 254117ab2063SBarry Smith 2542db81eaa0SLois Curfman McInnes Collective on MPI_Comm 2543db81eaa0SLois Curfman McInnes 254417ab2063SBarry Smith Input Parameters: 2545db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 254617ab2063SBarry Smith . m - number of rows 254717ab2063SBarry Smith . n - number of columns 254817ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 254951c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 25502bd5e0b2SLois Curfman McInnes (possibly different for each row) or PETSC_NULL 255117ab2063SBarry Smith 255217ab2063SBarry Smith Output Parameter: 2553416022c9SBarry Smith . A - the matrix 255417ab2063SBarry Smith 2555b259b22eSLois Curfman McInnes Notes: 255649a6f317SBarry Smith If nnz is given then nz is ignored 255749a6f317SBarry Smith 255817ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 255917ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 25600002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 256144cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 256217ab2063SBarry Smith 256317ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2564a40aa06bSLois Curfman McInnes Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 25653d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 25666da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 256717ab2063SBarry Smith 2568682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 25694fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 2570682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 25716c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 25726c7ebb05SLois Curfman McInnes 25736c7ebb05SLois Curfman McInnes Options Database Keys: 2574db81eaa0SLois Curfman McInnes + -mat_aij_no_inode - Do not use inodes 2575db81eaa0SLois Curfman McInnes . -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5) 2576db81eaa0SLois Curfman McInnes - -mat_aij_oneindex - Internally use indexing starting at 1 2577db81eaa0SLois Curfman McInnes rather than 0. Note that when calling MatSetValues(), 2578db81eaa0SLois Curfman McInnes the user still MUST index entries starting at 0! 257917ab2063SBarry Smith 2580027ccd11SLois Curfman McInnes Level: intermediate 2581027ccd11SLois Curfman McInnes 258236db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 258336db0b34SBarry Smith 258417ab2063SBarry Smith @*/ 258597f1f81fSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 258617ab2063SBarry Smith { 2587dfbe8321SBarry Smith PetscErrorCode ierr; 25886945ee14SBarry Smith 25893a40ed3dSBarry Smith PetscFunctionBegin; 2590273d9f13SBarry Smith ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr); 2591273d9f13SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 2592273d9f13SBarry Smith ierr = MatSeqAIJSetPreallocation(*A,nz,nnz);CHKERRQ(ierr); 2593273d9f13SBarry Smith PetscFunctionReturn(0); 2594273d9f13SBarry Smith } 2595273d9f13SBarry Smith 25965da197adSKris Buschelman #define SKIP_ALLOCATION -4 25975da197adSKris Buschelman 25984a2ae208SSatish Balay #undef __FUNCT__ 25994a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation" 2600273d9f13SBarry Smith /*@C 2601273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 2602273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 2603273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 2604273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 2605273d9f13SBarry Smith 2606273d9f13SBarry Smith Collective on MPI_Comm 2607273d9f13SBarry Smith 2608273d9f13SBarry Smith Input Parameters: 2609273d9f13SBarry Smith + comm - MPI communicator, set to PETSC_COMM_SELF 2610273d9f13SBarry Smith . m - number of rows 2611273d9f13SBarry Smith . n - number of columns 2612273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 2613273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 2614273d9f13SBarry Smith (possibly different for each row) or PETSC_NULL 2615273d9f13SBarry Smith 2616273d9f13SBarry Smith Output Parameter: 2617273d9f13SBarry Smith . A - the matrix 2618273d9f13SBarry Smith 2619273d9f13SBarry Smith Notes: 262049a6f317SBarry Smith If nnz is given then nz is ignored 262149a6f317SBarry Smith 2622273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 2623273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 2624273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 2625273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 2626273d9f13SBarry Smith 2627273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2628273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 2629273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 2630273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 2631273d9f13SBarry Smith 2632273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 2633273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 2634273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 2635273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 2636273d9f13SBarry Smith 2637273d9f13SBarry Smith Options Database Keys: 2638273d9f13SBarry Smith + -mat_aij_no_inode - Do not use inodes 2639273d9f13SBarry Smith . -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5) 2640273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 2641273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 2642273d9f13SBarry Smith the user still MUST index entries starting at 0! 2643273d9f13SBarry Smith 2644273d9f13SBarry Smith Level: intermediate 2645273d9f13SBarry Smith 2646273d9f13SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 2647273d9f13SBarry Smith 2648273d9f13SBarry Smith @*/ 264997f1f81fSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 2650273d9f13SBarry Smith { 265197f1f81fSBarry Smith PetscErrorCode ierr,(*f)(Mat,PetscInt,const PetscInt[]); 2652a23d5eceSKris Buschelman 2653a23d5eceSKris Buschelman PetscFunctionBegin; 2654a23d5eceSKris Buschelman ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",(void (**)(void))&f);CHKERRQ(ierr); 2655a23d5eceSKris Buschelman if (f) { 2656a23d5eceSKris Buschelman ierr = (*f)(B,nz,nnz);CHKERRQ(ierr); 2657a23d5eceSKris Buschelman } 2658a23d5eceSKris Buschelman PetscFunctionReturn(0); 2659a23d5eceSKris Buschelman } 2660a23d5eceSKris Buschelman 2661a23d5eceSKris Buschelman EXTERN_C_BEGIN 2662a23d5eceSKris Buschelman #undef __FUNCT__ 2663a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ" 266497f1f81fSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,PetscInt *nnz) 2665a23d5eceSKris Buschelman { 2666273d9f13SBarry Smith Mat_SeqAIJ *b; 2667a7ed9263SMatthew Knepley size_t len = 0; 2668a43ee2ecSKris Buschelman PetscTruth skipallocation = PETSC_FALSE; 26696849ba73SBarry Smith PetscErrorCode ierr; 267097f1f81fSBarry Smith PetscInt i; 2671273d9f13SBarry Smith 2672273d9f13SBarry Smith PetscFunctionBegin; 2673d5d45c9bSBarry Smith 2674c461c341SBarry Smith if (nz == SKIP_ALLOCATION) { 2675c461c341SBarry Smith skipallocation = PETSC_TRUE; 2676c461c341SBarry Smith nz = 0; 2677c461c341SBarry Smith } 2678c461c341SBarry Smith 2679435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 2680435da068SBarry Smith if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 2681b73539f3SBarry Smith if (nnz) { 2682273d9f13SBarry Smith for (i=0; i<B->m; i++) { 268329bbc08cSBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 26843a7fca6bSBarry 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); 2685b73539f3SBarry Smith } 2686b73539f3SBarry Smith } 2687b73539f3SBarry Smith 2688273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 2689273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 2690273d9f13SBarry Smith 269197f1f81fSBarry Smith ierr = PetscMalloc((B->m+1)*sizeof(PetscInt),&b->imax);CHKERRQ(ierr); 2692273d9f13SBarry Smith if (!nnz) { 2693435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 2694273d9f13SBarry Smith else if (nz <= 0) nz = 1; 2695273d9f13SBarry Smith for (i=0; i<B->m; i++) b->imax[i] = nz; 2696273d9f13SBarry Smith nz = nz*B->m; 2697273d9f13SBarry Smith } else { 2698273d9f13SBarry Smith nz = 0; 2699273d9f13SBarry Smith for (i=0; i<B->m; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 2700273d9f13SBarry Smith } 2701273d9f13SBarry Smith 2702c461c341SBarry Smith if (!skipallocation) { 2703273d9f13SBarry Smith /* allocate the matrix space */ 270497f1f81fSBarry Smith len = ((size_t) nz)*(sizeof(PetscInt) + sizeof(PetscScalar)) + (B->m+1)*sizeof(PetscInt); 2705b0a32e0cSBarry Smith ierr = PetscMalloc(len,&b->a);CHKERRQ(ierr); 270697f1f81fSBarry Smith b->j = (PetscInt*)(b->a + nz); 270797f1f81fSBarry Smith ierr = PetscMemzero(b->j,nz*sizeof(PetscInt));CHKERRQ(ierr); 2708273d9f13SBarry Smith b->i = b->j + nz; 2709bfeeae90SHong Zhang b->i[0] = 0; 27105da197adSKris Buschelman for (i=1; i<B->m+1; i++) { 27115da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 27125da197adSKris Buschelman } 2713273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 2714273d9f13SBarry Smith b->freedata = PETSC_TRUE; 2715c461c341SBarry Smith } else { 2716c461c341SBarry Smith b->freedata = PETSC_FALSE; 2717c461c341SBarry Smith } 2718273d9f13SBarry Smith 2719273d9f13SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 272097f1f81fSBarry Smith ierr = PetscMalloc((B->m+1)*sizeof(PetscInt),&b->ilen);CHKERRQ(ierr); 272197f1f81fSBarry Smith PetscLogObjectMemory(B,len+2*(B->m+1)*sizeof(PetscInt)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2722273d9f13SBarry Smith for (i=0; i<B->m; i++) { b->ilen[i] = 0;} 2723273d9f13SBarry Smith 2724273d9f13SBarry Smith b->nz = 0; 2725273d9f13SBarry Smith b->maxnz = nz; 2726273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 2727273d9f13SBarry Smith PetscFunctionReturn(0); 2728273d9f13SBarry Smith } 2729a23d5eceSKris Buschelman EXTERN_C_END 2730273d9f13SBarry Smith 27310bad9183SKris Buschelman /*MC 2732fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 27330bad9183SKris Buschelman based on compressed sparse row format. 27340bad9183SKris Buschelman 27350bad9183SKris Buschelman Options Database Keys: 27360bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 27370bad9183SKris Buschelman 27380bad9183SKris Buschelman Level: beginner 27390bad9183SKris Buschelman 2740f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 27410bad9183SKris Buschelman M*/ 27420bad9183SKris Buschelman 2743a6175056SHong Zhang EXTERN_C_BEGIN 27444a2ae208SSatish Balay #undef __FUNCT__ 27454a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ" 2746dfbe8321SBarry Smith PetscErrorCode MatCreate_SeqAIJ(Mat B) 2747273d9f13SBarry Smith { 2748273d9f13SBarry Smith Mat_SeqAIJ *b; 2749dfbe8321SBarry Smith PetscErrorCode ierr; 275038baddfdSBarry Smith PetscMPIInt size; 2751273d9f13SBarry Smith 2752273d9f13SBarry Smith PetscFunctionBegin; 2753273d9f13SBarry Smith ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr); 2754273d9f13SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 2755273d9f13SBarry Smith 2756273d9f13SBarry Smith B->m = B->M = PetscMax(B->m,B->M); 2757273d9f13SBarry Smith B->n = B->N = PetscMax(B->n,B->N); 2758273d9f13SBarry Smith 2759b0a32e0cSBarry Smith ierr = PetscNew(Mat_SeqAIJ,&b);CHKERRQ(ierr); 2760b0a32e0cSBarry Smith B->data = (void*)b; 2761549d3d68SSatish Balay ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr); 2762549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 2763416022c9SBarry Smith B->factor = 0; 2764416022c9SBarry Smith B->lupivotthreshold = 1.0; 276590f02eecSBarry Smith B->mapping = 0; 2766e82a3eeeSBarry Smith ierr = PetscOptionsGetReal(B->prefix,"-mat_lu_pivotthreshold",&B->lupivotthreshold,PETSC_NULL);CHKERRQ(ierr); 2767e82a3eeeSBarry Smith ierr = PetscOptionsHasName(B->prefix,"-pc_ilu_preserve_row_sums",&b->ilu_preserve_row_sums);CHKERRQ(ierr); 2768416022c9SBarry Smith b->row = 0; 2769416022c9SBarry Smith b->col = 0; 277082bf6240SBarry Smith b->icol = 0; 2771b810aeb4SBarry Smith b->reallocs = 0; 2772922d95a3SBarry Smith b->lu_shift = PETSC_FALSE; 277317ab2063SBarry Smith 27748a124369SBarry Smith ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr); 27758a124369SBarry Smith ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr); 2776a5ae1ecdSBarry Smith 2777f1e2ffcdSBarry Smith b->sorted = PETSC_FALSE; 277836db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 2779f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 2780416022c9SBarry Smith b->nonew = 0; 2781416022c9SBarry Smith b->diag = 0; 2782416022c9SBarry Smith b->solve_work = 0; 27832a1b7f2aSHong Zhang B->spptr = 0; 2784b65db4caSBarry Smith b->inode.use = PETSC_TRUE; 2785754ec7b1SSatish Balay b->inode.node_count = 0; 2786754ec7b1SSatish Balay b->inode.size = 0; 27876c7ebb05SLois Curfman McInnes b->inode.limit = 5; 27886c7ebb05SLois Curfman McInnes b->inode.max_limit = 5; 2789be6bf707SBarry Smith b->saved_values = 0; 2790d7f994e1SBarry Smith b->idiag = 0; 2791d7f994e1SBarry Smith b->ssor = 0; 2792f1e2ffcdSBarry Smith b->keepzeroedrows = PETSC_FALSE; 2793a30b2313SHong Zhang b->xtoy = 0; 2794a30b2313SHong Zhang b->XtoY = 0; 279573e7a558SHong Zhang b->compressedrow.use = PETSC_FALSE; 2796d487561eSHong Zhang b->compressedrow.nrows = B->m; 2797d487561eSHong Zhang b->compressedrow.i = PETSC_NULL; 2798d487561eSHong Zhang b->compressedrow.rindex = PETSC_NULL; 2799d487561eSHong Zhang b->compressedrow.checked = PETSC_FALSE; 280017ab2063SBarry Smith 280135d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 280235d8aa7fSBarry Smith 2803f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C", 2804bef8e0ddSBarry Smith "MatSeqAIJSetColumnIndices_SeqAIJ", 2805bc4b532fSSatish Balay MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 2806f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 2807be6bf707SBarry Smith "MatStoreValues_SeqAIJ", 2808bc4b532fSSatish Balay MatStoreValues_SeqAIJ);CHKERRQ(ierr); 2809f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 2810be6bf707SBarry Smith "MatRetrieveValues_SeqAIJ", 2811bc4b532fSSatish Balay MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 2812b24ad042SBarry Smith #if !defined(PETSC_USE_64BIT_INT) 2813a6175056SHong Zhang ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C", 2814a6175056SHong Zhang "MatConvert_SeqAIJ_SeqSBAIJ", 2815a6175056SHong Zhang MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 2816b24ad042SBarry Smith #endif 281785fc7724SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C", 281885fc7724SBarry Smith "MatConvert_SeqAIJ_SeqBAIJ", 281985fc7724SBarry Smith MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 28205fbd3699SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C", 28215fbd3699SBarry Smith "MatIsTranspose_SeqAIJ", 28225fbd3699SBarry Smith MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 2823a23d5eceSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C", 2824a23d5eceSKris Buschelman "MatSeqAIJSetPreallocation_SeqAIJ", 2825a23d5eceSKris Buschelman MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 282605b94e36SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C", 282705b94e36SKris Buschelman "MatReorderForNonzeroDiagonal_SeqAIJ", 282805b94e36SKris Buschelman MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 28290a99d0a2SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatAdjustForInodes_C", 28300a99d0a2SKris Buschelman "MatAdjustForInodes_SeqAIJ", 28310a99d0a2SKris Buschelman MatAdjustForInodes_SeqAIJ);CHKERRQ(ierr); 2832d758967fSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJGetInodeSizes_C", 2833d758967fSKris Buschelman "MatSeqAIJGetInodeSizes_SeqAIJ", 2834d758967fSKris Buschelman MatSeqAIJGetInodeSizes_SeqAIJ);CHKERRQ(ierr); 28353a40ed3dSBarry Smith PetscFunctionReturn(0); 283617ab2063SBarry Smith } 2837273d9f13SBarry Smith EXTERN_C_END 283817ab2063SBarry Smith 28394a2ae208SSatish Balay #undef __FUNCT__ 28404a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqAIJ" 2841dfbe8321SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 284217ab2063SBarry Smith { 2843416022c9SBarry Smith Mat C; 2844416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 28456849ba73SBarry Smith PetscErrorCode ierr; 284697f1f81fSBarry Smith PetscInt i,m = A->m; 2847a7ed9263SMatthew Knepley size_t len; 284817ab2063SBarry Smith 28493a40ed3dSBarry Smith PetscFunctionBegin; 28504043dd9cSLois Curfman McInnes *B = 0; 2851273d9f13SBarry Smith ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr); 2852be5d1d56SKris Buschelman ierr = MatSetType(C,A->type_name);CHKERRQ(ierr); 28531d5dac46SHong Zhang ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 28541d5dac46SHong Zhang 2855273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 2856273d9f13SBarry Smith 2857416022c9SBarry Smith C->factor = A->factor; 28586ad4291fSHong Zhang C->lupivotthreshold = A->lupivotthreshold; 28596ad4291fSHong Zhang 2860416022c9SBarry Smith c->row = 0; 2861416022c9SBarry Smith c->col = 0; 286282bf6240SBarry Smith c->icol = 0; 28636ad4291fSHong Zhang c->reallocs = 0; 28646ad4291fSHong Zhang c->lu_shift = PETSC_FALSE; 286517ab2063SBarry Smith 28666ad4291fSHong Zhang C->assembled = PETSC_TRUE; 286717ab2063SBarry Smith 286897f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->imax);CHKERRQ(ierr); 286997f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->ilen);CHKERRQ(ierr); 287017ab2063SBarry Smith for (i=0; i<m; i++) { 2871416022c9SBarry Smith c->imax[i] = a->imax[i]; 2872416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 287317ab2063SBarry Smith } 287417ab2063SBarry Smith 287517ab2063SBarry Smith /* allocate the matrix space */ 2876f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 287797f1f81fSBarry Smith len = ((size_t) (m+1))*sizeof(PetscInt)+(a->i[m])*(sizeof(PetscScalar)+sizeof(PetscInt)); 2878b0a32e0cSBarry Smith ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr); 287997f1f81fSBarry Smith c->j = (PetscInt*)(c->a + a->i[m] ); 2880bfeeae90SHong Zhang c->i = c->j + a->i[m]; 288197f1f81fSBarry Smith ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 288217ab2063SBarry Smith if (m > 0) { 288397f1f81fSBarry Smith ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr); 2884be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 2885bfeeae90SHong Zhang ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 2886be6bf707SBarry Smith } else { 2887bfeeae90SHong Zhang ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 288817ab2063SBarry Smith } 288908480c60SBarry Smith } 289017ab2063SBarry Smith 289197f1f81fSBarry Smith PetscLogObjectMemory(C,len+2*(m+1)*sizeof(PetscInt)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2892416022c9SBarry Smith c->sorted = a->sorted; 28936ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 2894416022c9SBarry Smith c->roworiented = a->roworiented; 2895416022c9SBarry Smith c->nonew = a->nonew; 2896416022c9SBarry Smith if (a->diag) { 289797f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr); 289897f1f81fSBarry Smith PetscLogObjectMemory(C,(m+1)*sizeof(PetscInt)); 289917ab2063SBarry Smith for (i=0; i<m; i++) { 2900416022c9SBarry Smith c->diag[i] = a->diag[i]; 290117ab2063SBarry Smith } 29023a40ed3dSBarry Smith } else c->diag = 0; 29036ad4291fSHong Zhang c->solve_work = 0; 2904b65db4caSBarry Smith c->inode.use = a->inode.use; 29056c7ebb05SLois Curfman McInnes c->inode.limit = a->inode.limit; 29066c7ebb05SLois Curfman McInnes c->inode.max_limit = a->inode.max_limit; 2907754ec7b1SSatish Balay if (a->inode.size){ 290897f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->inode.size);CHKERRQ(ierr); 2909754ec7b1SSatish Balay c->inode.node_count = a->inode.node_count; 291097f1f81fSBarry Smith ierr = PetscMemcpy(c->inode.size,a->inode.size,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 2911754ec7b1SSatish Balay } else { 2912754ec7b1SSatish Balay c->inode.size = 0; 2913754ec7b1SSatish Balay c->inode.node_count = 0; 2914754ec7b1SSatish Balay } 29156ad4291fSHong Zhang c->saved_values = 0; 29166ad4291fSHong Zhang c->idiag = 0; 29176ad4291fSHong Zhang c->ilu_preserve_row_sums = a->ilu_preserve_row_sums; 29186ad4291fSHong Zhang c->ssor = 0; 29196ad4291fSHong Zhang c->keepzeroedrows = a->keepzeroedrows; 29206ad4291fSHong Zhang c->freedata = PETSC_TRUE; 29216ad4291fSHong Zhang c->xtoy = 0; 29226ad4291fSHong Zhang c->XtoY = 0; 29236ad4291fSHong Zhang 2924416022c9SBarry Smith c->nz = a->nz; 2925416022c9SBarry Smith c->maxnz = a->maxnz; 2926273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 2927754ec7b1SSatish Balay 29286ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 29296ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 29306ad4291fSHong Zhang c->compressedrow.checked = a->compressedrow.checked; 29316ad4291fSHong Zhang if ( a->compressedrow.checked && a->compressedrow.use){ 29326ad4291fSHong Zhang i = a->compressedrow.nrows; 29336ad4291fSHong Zhang ierr = PetscMalloc((2*i+1)*sizeof(PetscInt),&c->compressedrow.i);CHKERRQ(ierr); 29346ad4291fSHong Zhang c->compressedrow.rindex = c->compressedrow.i + i + 1; 29356ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr); 29366ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr); 2937*27ea64f8SHong Zhang } else { 2938*27ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 2939*27ea64f8SHong Zhang c->compressedrow.i = PETSC_NULL; 2940*27ea64f8SHong Zhang c->compressedrow.rindex = PETSC_NULL; 2941*27ea64f8SHong Zhang C->ops->mult = MatMult_SeqAIJ; 2942*27ea64f8SHong Zhang C->ops->multadd = MatMultAdd_SeqAIJ; 29436ad4291fSHong Zhang } 29446ad4291fSHong Zhang 2945416022c9SBarry Smith *B = C; 2946b0a32e0cSBarry Smith ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 29473a40ed3dSBarry Smith PetscFunctionReturn(0); 294817ab2063SBarry Smith } 294917ab2063SBarry Smith 29504a2ae208SSatish Balay #undef __FUNCT__ 29514a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ" 2952dfbe8321SBarry Smith PetscErrorCode MatLoad_SeqAIJ(PetscViewer viewer,const MatType type,Mat *A) 295317ab2063SBarry Smith { 2954416022c9SBarry Smith Mat_SeqAIJ *a; 2955416022c9SBarry Smith Mat B; 29566849ba73SBarry Smith PetscErrorCode ierr; 295738baddfdSBarry Smith PetscInt i,nz,header[4],*rowlengths = 0,M,N; 295838baddfdSBarry Smith int fd; 295938baddfdSBarry Smith PetscMPIInt size; 2960bcd2baecSBarry Smith MPI_Comm comm; 296117ab2063SBarry Smith 29623a40ed3dSBarry Smith PetscFunctionBegin; 2963e864ced6SBarry Smith ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 2964d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 296529bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,"view must have one processor"); 2966b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 29670752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 2968552e946dSBarry Smith if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 296917ab2063SBarry Smith M = header[1]; N = header[2]; nz = header[3]; 297017ab2063SBarry Smith 2971d64ed03dSBarry Smith if (nz < 0) { 297229bbc08cSBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 2973d64ed03dSBarry Smith } 2974d64ed03dSBarry Smith 297517ab2063SBarry Smith /* read in row lengths */ 297697f1f81fSBarry Smith ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr); 29770752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 297817ab2063SBarry Smith 297917ab2063SBarry Smith /* create our matrix */ 2980b3a1e11cSKris Buschelman ierr = MatCreate(comm,PETSC_DECIDE,PETSC_DECIDE,M,N,&B);CHKERRQ(ierr); 2981b3a1e11cSKris Buschelman ierr = MatSetType(B,type);CHKERRQ(ierr); 2982b3a1e11cSKris Buschelman ierr = MatSeqAIJSetPreallocation(B,0,rowlengths);CHKERRQ(ierr); 2983416022c9SBarry Smith a = (Mat_SeqAIJ*)B->data; 298417ab2063SBarry Smith 298517ab2063SBarry Smith /* read in column indices and adjust for Fortran indexing*/ 29860752156aSBarry Smith ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 298717ab2063SBarry Smith 298817ab2063SBarry Smith /* read in nonzero values */ 29890752156aSBarry Smith ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 299017ab2063SBarry Smith 299117ab2063SBarry Smith /* set matrix "i" values */ 2992efb16452SHong Zhang a->i[0] = 0; 299317ab2063SBarry Smith for (i=1; i<= M; i++) { 2994416022c9SBarry Smith a->i[i] = a->i[i-1] + rowlengths[i-1]; 2995416022c9SBarry Smith a->ilen[i-1] = rowlengths[i-1]; 299617ab2063SBarry Smith } 2997606d414cSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 299817ab2063SBarry Smith 29996d4a8577SBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 30006d4a8577SBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3001b3a1e11cSKris Buschelman *A = B; 30023a40ed3dSBarry Smith PetscFunctionReturn(0); 300317ab2063SBarry Smith } 300417ab2063SBarry Smith 30054a2ae208SSatish Balay #undef __FUNCT__ 3006b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ" 3007dfbe8321SBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg) 30087264ac53SSatish Balay { 30097264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data; 3010dfbe8321SBarry Smith PetscErrorCode ierr; 30117264ac53SSatish Balay 30123a40ed3dSBarry Smith PetscFunctionBegin; 3013bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 3014bfeeae90SHong Zhang if ((A->m != B->m) || (A->n != B->n) ||(a->nz != b->nz)) { 3015ca44d042SBarry Smith *flg = PETSC_FALSE; 3016ca44d042SBarry Smith PetscFunctionReturn(0); 3017bcd2baecSBarry Smith } 30187264ac53SSatish Balay 30197264ac53SSatish Balay /* if the a->i are the same */ 302097f1f81fSBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->m+1)*sizeof(PetscInt),flg);CHKERRQ(ierr); 30210f5bd95cSBarry Smith if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 30227264ac53SSatish Balay 30237264ac53SSatish Balay /* if a->j are the same */ 302497f1f81fSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr); 30250f5bd95cSBarry Smith if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 3026bcd2baecSBarry Smith 3027bcd2baecSBarry Smith /* if a->a are the same */ 302887828ca2SBarry Smith ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 30290f5bd95cSBarry Smith 30303a40ed3dSBarry Smith PetscFunctionReturn(0); 30317264ac53SSatish Balay 30327264ac53SSatish Balay } 303336db0b34SBarry Smith 30344a2ae208SSatish Balay #undef __FUNCT__ 30354a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays" 303636db0b34SBarry Smith /*@C 303736db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 303836db0b34SBarry Smith provided by the user. 303936db0b34SBarry Smith 304036db0b34SBarry Smith Coolective on MPI_Comm 304136db0b34SBarry Smith 304236db0b34SBarry Smith Input Parameters: 304336db0b34SBarry Smith + comm - must be an MPI communicator of size 1 304436db0b34SBarry Smith . m - number of rows 304536db0b34SBarry Smith . n - number of columns 304636db0b34SBarry Smith . i - row indices 304736db0b34SBarry Smith . j - column indices 304836db0b34SBarry Smith - a - matrix values 304936db0b34SBarry Smith 305036db0b34SBarry Smith Output Parameter: 305136db0b34SBarry Smith . mat - the matrix 305236db0b34SBarry Smith 305336db0b34SBarry Smith Level: intermediate 305436db0b34SBarry Smith 305536db0b34SBarry Smith Notes: 30560551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 305736db0b34SBarry Smith once the matrix is destroyed 305836db0b34SBarry Smith 305936db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 306036db0b34SBarry Smith 3061bfeeae90SHong Zhang The i and j indices are 0 based 306236db0b34SBarry Smith 306336db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ() 306436db0b34SBarry Smith 306536db0b34SBarry Smith @*/ 306697f1f81fSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat) 306736db0b34SBarry Smith { 3068dfbe8321SBarry Smith PetscErrorCode ierr; 306997f1f81fSBarry Smith PetscInt ii; 307036db0b34SBarry Smith Mat_SeqAIJ *aij; 307136db0b34SBarry Smith 307236db0b34SBarry Smith PetscFunctionBegin; 3073f204ca49SKris Buschelman ierr = MatCreate(comm,m,n,m,n,mat);CHKERRQ(ierr); 3074f204ca49SKris Buschelman ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 3075f204ca49SKris Buschelman ierr = MatSeqAIJSetPreallocation(*mat,SKIP_ALLOCATION,0);CHKERRQ(ierr); 307636db0b34SBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 307736db0b34SBarry Smith 3078bfeeae90SHong Zhang if (i[0] != 0) { 3079634064b4SBarry Smith SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 308036db0b34SBarry Smith } 308136db0b34SBarry Smith aij->i = i; 308236db0b34SBarry Smith aij->j = j; 308336db0b34SBarry Smith aij->a = a; 308436db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 308536db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 308636db0b34SBarry Smith aij->freedata = PETSC_FALSE; 308736db0b34SBarry Smith 308836db0b34SBarry Smith for (ii=0; ii<m; ii++) { 308936db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 30909860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g) 309179a5c55eSBarry Smith if (i[ii+1] - i[ii] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Negative row length in i (row indices) row = %d length = %d",ii,i[ii+1] - i[ii]); 309236db0b34SBarry Smith #endif 309336db0b34SBarry Smith } 30949860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g) 309536db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 309679a5c55eSBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]); 309779a5c55eSBarry Smith if (j[ii] > n - 1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column index to large at location = %d index = %d",ii,j[ii]); 309836db0b34SBarry Smith } 309936db0b34SBarry Smith #endif 310036db0b34SBarry Smith 3101b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3102b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 310336db0b34SBarry Smith PetscFunctionReturn(0); 310436db0b34SBarry Smith } 310536db0b34SBarry Smith 3106cc8ba8e1SBarry Smith #undef __FUNCT__ 3107ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ" 3108dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring) 3109cc8ba8e1SBarry Smith { 3110dfbe8321SBarry Smith PetscErrorCode ierr; 3111cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 311236db0b34SBarry Smith 3113cc8ba8e1SBarry Smith PetscFunctionBegin; 311412c595b3SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 3115cc8ba8e1SBarry Smith ierr = ISColoringReference(coloring);CHKERRQ(ierr); 3116cc8ba8e1SBarry Smith a->coloring = coloring; 311712c595b3SBarry Smith } else if (coloring->ctype == IS_COLORING_GHOSTED) { 311897f1f81fSBarry Smith PetscInt i,*larray; 311912c595b3SBarry Smith ISColoring ocoloring; 312008b6dcc0SBarry Smith ISColoringValue *colors; 312112c595b3SBarry Smith 312212c595b3SBarry Smith /* set coloring for diagonal portion */ 312397f1f81fSBarry Smith ierr = PetscMalloc((A->n+1)*sizeof(PetscInt),&larray);CHKERRQ(ierr); 312412c595b3SBarry Smith for (i=0; i<A->n; i++) { 312512c595b3SBarry Smith larray[i] = i; 312612c595b3SBarry Smith } 312712c595b3SBarry Smith ierr = ISGlobalToLocalMappingApply(A->mapping,IS_GTOLM_MASK,A->n,larray,PETSC_NULL,larray);CHKERRQ(ierr); 312808b6dcc0SBarry Smith ierr = PetscMalloc((A->n+1)*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); 312912c595b3SBarry Smith for (i=0; i<A->n; i++) { 313012c595b3SBarry Smith colors[i] = coloring->colors[larray[i]]; 313112c595b3SBarry Smith } 313212c595b3SBarry Smith ierr = PetscFree(larray);CHKERRQ(ierr); 313312c595b3SBarry Smith ierr = ISColoringCreate(PETSC_COMM_SELF,A->n,colors,&ocoloring);CHKERRQ(ierr); 313412c595b3SBarry Smith a->coloring = ocoloring; 313512c595b3SBarry Smith } 3136cc8ba8e1SBarry Smith PetscFunctionReturn(0); 3137cc8ba8e1SBarry Smith } 3138cc8ba8e1SBarry Smith 313987828ca2SBarry Smith #if defined(PETSC_HAVE_ADIC) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) 3140ee4f033dSBarry Smith EXTERN_C_BEGIN 314129c1e371SBarry Smith #include "adic/ad_utils.h" 3142ee4f033dSBarry Smith EXTERN_C_END 3143cc8ba8e1SBarry Smith 3144cc8ba8e1SBarry Smith #undef __FUNCT__ 3145ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ" 3146dfbe8321SBarry Smith PetscErrorCode MatSetValuesAdic_SeqAIJ(Mat A,void *advalues) 3147cc8ba8e1SBarry Smith { 3148cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 314997f1f81fSBarry Smith PetscInt m = A->m,*ii = a->i,*jj = a->j,nz,i,j,nlen; 31504440f671SBarry Smith PetscScalar *v = a->a,*values = ((PetscScalar*)advalues)+1; 315108b6dcc0SBarry Smith ISColoringValue *color; 3152cc8ba8e1SBarry Smith 3153cc8ba8e1SBarry Smith PetscFunctionBegin; 3154e005ede5SBarry Smith if (!a->coloring) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix"); 31554440f671SBarry Smith nlen = PetscADGetDerivTypeSize()/sizeof(PetscScalar); 3156cc8ba8e1SBarry Smith color = a->coloring->colors; 3157cc8ba8e1SBarry Smith /* loop over rows */ 3158cc8ba8e1SBarry Smith for (i=0; i<m; i++) { 3159cc8ba8e1SBarry Smith nz = ii[i+1] - ii[i]; 3160cc8ba8e1SBarry Smith /* loop over columns putting computed value into matrix */ 3161cc8ba8e1SBarry Smith for (j=0; j<nz; j++) { 3162cc8ba8e1SBarry Smith *v++ = values[color[*jj++]]; 3163cc8ba8e1SBarry Smith } 31644440f671SBarry Smith values += nlen; /* jump to next row of derivatives */ 3165ee4f033dSBarry Smith } 3166ee4f033dSBarry Smith PetscFunctionReturn(0); 3167ee4f033dSBarry Smith } 3168ee4f033dSBarry Smith 3169ee4f033dSBarry Smith #else 3170ee4f033dSBarry Smith 3171ee4f033dSBarry Smith #undef __FUNCT__ 3172ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ" 3173dfbe8321SBarry Smith PetscErrorCode MatSetValuesAdic_SeqAIJ(Mat A,void *advalues) 3174ee4f033dSBarry Smith { 3175ee4f033dSBarry Smith PetscFunctionBegin; 3176e005ede5SBarry Smith SETERRQ(PETSC_ERR_SUP_SYS,"PETSc installed without ADIC"); 3177ee4f033dSBarry Smith } 3178ee4f033dSBarry Smith 3179ee4f033dSBarry Smith #endif 3180ee4f033dSBarry Smith 3181ee4f033dSBarry Smith #undef __FUNCT__ 3182ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ" 318397f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues) 3184ee4f033dSBarry Smith { 3185ee4f033dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 318697f1f81fSBarry Smith PetscInt m = A->m,*ii = a->i,*jj = a->j,nz,i,j; 318787828ca2SBarry Smith PetscScalar *v = a->a,*values = (PetscScalar *)advalues; 318808b6dcc0SBarry Smith ISColoringValue *color; 3189ee4f033dSBarry Smith 3190ee4f033dSBarry Smith PetscFunctionBegin; 3191e005ede5SBarry Smith if (!a->coloring) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix"); 3192ee4f033dSBarry Smith color = a->coloring->colors; 3193ee4f033dSBarry Smith /* loop over rows */ 3194ee4f033dSBarry Smith for (i=0; i<m; i++) { 3195ee4f033dSBarry Smith nz = ii[i+1] - ii[i]; 3196ee4f033dSBarry Smith /* loop over columns putting computed value into matrix */ 3197ee4f033dSBarry Smith for (j=0; j<nz; j++) { 3198ee4f033dSBarry Smith *v++ = values[color[*jj++]]; 3199ee4f033dSBarry Smith } 3200ee4f033dSBarry Smith values += nl; /* jump to next row of derivatives */ 3201cc8ba8e1SBarry Smith } 3202cc8ba8e1SBarry Smith PetscFunctionReturn(0); 3203cc8ba8e1SBarry Smith } 320436db0b34SBarry Smith 3205