173f4d377SMatthew Knepley /*$Id: aij.c,v 1.385 2001/09/07 20:09:22 bsmith Exp $*/ 2d5d45c9bSBarry Smith /* 33369ce9aSBarry Smith Defines the basic matrix operations for the AIJ (compressed row) 4d5d45c9bSBarry Smith matrix storage format. 5d5d45c9bSBarry Smith */ 63369ce9aSBarry Smith 79e070d67SMatthew Knepley #include "src/mat/impls/aij/seq/aij.h" /*I "petscmat.h" I*/ 8f5eb4b81SSatish Balay #include "src/vec/vecimpl.h" 9f5eb4b81SSatish Balay #include "src/inline/spops.h" 108d195f9aSBarry Smith #include "src/inline/dot.h" 110a835dfdSSatish Balay #include "petscbt.h" 1217ab2063SBarry Smith 134a2ae208SSatish Balay #undef __FUNCT__ 144a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ" 154e7234bfSBarry Smith int MatGetRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *m,int *ia[],int *ja[],PetscTruth *done) 1617ab2063SBarry Smith { 17416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 186945ee14SBarry Smith int ierr,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) { 27435da068SBarry Smith int nz = a->i[A->m]; 283b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 291bc30dd5SBarry Smith ierr = PetscMalloc((A->m+1)*sizeof(int),ia);CHKERRQ(ierr); 30b0a32e0cSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(int),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" 414e7234bfSBarry Smith int MatRestoreRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int *ia[],int *ja[],PetscTruth *done) 426945ee14SBarry Smith { 43bfeeae90SHong Zhang int 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" 564e7234bfSBarry Smith int MatGetColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int *ia[],int *ja[],PetscTruth *done) 573b2fbd54SBarry Smith { 583b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 59bfeeae90SHong Zhang int ierr,i,*collengths,*cia,*cja,n = A->n,m = A->m; 60bfeeae90SHong Zhang int nz = a->i[m],row,*jj,mr,col; 613b2fbd54SBarry Smith 623a40ed3dSBarry Smith PetscFunctionBegin; 633b2fbd54SBarry Smith *nn = A->n; 643a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 653b2fbd54SBarry Smith if (symmetric) { 66bfeeae90SHong Zhang ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr); 673b2fbd54SBarry Smith } else { 68b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&collengths);CHKERRQ(ierr); 69549d3d68SSatish Balay ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr); 70b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&cia);CHKERRQ(ierr); 71b0a32e0cSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(int),&cja);CHKERRQ(ierr); 723b2fbd54SBarry Smith jj = a->j; 733b2fbd54SBarry Smith for (i=0; i<nz; i++) { 74bfeeae90SHong Zhang collengths[jj[i]]++; 753b2fbd54SBarry Smith } 763b2fbd54SBarry Smith cia[0] = oshift; 773b2fbd54SBarry Smith for (i=0; i<n; i++) { 783b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 793b2fbd54SBarry Smith } 80549d3d68SSatish Balay ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr); 813b2fbd54SBarry Smith jj = a->j; 82a93ec695SBarry Smith for (row=0; row<m; row++) { 83a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 84a93ec695SBarry Smith for (i=0; i<mr; i++) { 85bfeeae90SHong Zhang col = *jj++; 863b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 873b2fbd54SBarry Smith } 883b2fbd54SBarry Smith } 89606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 903b2fbd54SBarry Smith *ia = cia; *ja = cja; 913b2fbd54SBarry Smith } 923a40ed3dSBarry Smith PetscFunctionReturn(0); 933b2fbd54SBarry Smith } 943b2fbd54SBarry Smith 954a2ae208SSatish Balay #undef __FUNCT__ 964a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ" 974e7234bfSBarry Smith int MatRestoreColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int *ia[],int *ja[],PetscTruth *done) 983b2fbd54SBarry Smith { 99606d414cSSatish Balay int ierr; 100606d414cSSatish Balay 1013a40ed3dSBarry Smith PetscFunctionBegin; 1023a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 1033b2fbd54SBarry Smith 104606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 105606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 1063b2fbd54SBarry Smith 1073a40ed3dSBarry Smith PetscFunctionReturn(0); 1083b2fbd54SBarry Smith } 1093b2fbd54SBarry Smith 110227d817aSBarry Smith #define CHUNKSIZE 15 11117ab2063SBarry Smith 1124a2ae208SSatish Balay #undef __FUNCT__ 1134a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ" 114f15d580aSBarry Smith int MatSetValues_SeqAIJ(Mat A,int m,const int im[],int n,const int in[],const PetscScalar v[],InsertMode is) 11517ab2063SBarry Smith { 116416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 117416022c9SBarry Smith int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted = a->sorted; 118273d9f13SBarry Smith int *imax = a->imax,*ai = a->i,*ailen = a->ilen; 119bfeeae90SHong Zhang int *aj = a->j,nonew = a->nonew,ierr; 12087828ca2SBarry Smith PetscScalar *ap,value,*aa = a->a; 12136db0b34SBarry Smith PetscTruth ignorezeroentries = ((a->ignorezeroentries && is == ADD_VALUES) ? PETSC_TRUE:PETSC_FALSE); 122273d9f13SBarry Smith PetscTruth roworiented = a->roworiented; 12317ab2063SBarry Smith 1243a40ed3dSBarry Smith PetscFunctionBegin; 12517ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 126416022c9SBarry Smith row = im[k]; 1275ef9f2a5SBarry Smith if (row < 0) continue; 128aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 129590ac198SBarry Smith if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m-1); 1303b2fbd54SBarry Smith #endif 131bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 13217ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 133416022c9SBarry Smith low = 0; 13417ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 1355ef9f2a5SBarry Smith if (in[l] < 0) continue; 136aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 137590ac198SBarry Smith if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n-1); 1383b2fbd54SBarry Smith #endif 139bfeeae90SHong Zhang col = in[l]; 1404b0e389bSBarry Smith if (roworiented) { 1415ef9f2a5SBarry Smith value = v[l + k*n]; 142bef8e0ddSBarry Smith } else { 1434b0e389bSBarry Smith value = v[k + l*m]; 1444b0e389bSBarry Smith } 14536db0b34SBarry Smith if (value == 0.0 && ignorezeroentries) continue; 14636db0b34SBarry Smith 147416022c9SBarry Smith if (!sorted) low = 0; high = nrow; 148416022c9SBarry Smith while (high-low > 5) { 149416022c9SBarry Smith t = (low+high)/2; 150416022c9SBarry Smith if (rp[t] > col) high = t; 151416022c9SBarry Smith else low = t; 15217ab2063SBarry Smith } 153416022c9SBarry Smith for (i=low; i<high; i++) { 15417ab2063SBarry Smith if (rp[i] > col) break; 15517ab2063SBarry Smith if (rp[i] == col) { 156416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 15717ab2063SBarry Smith else ap[i] = value; 15817ab2063SBarry Smith goto noinsert; 15917ab2063SBarry Smith } 16017ab2063SBarry Smith } 161c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 16229bbc08cSBarry Smith else if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%d,%d) in the matrix",row,col); 16317ab2063SBarry Smith if (nrow >= rmax) { 16417ab2063SBarry Smith /* there is no extra room in row, therefore enlarge */ 165a7ed9263SMatthew Knepley int new_nz = ai[A->m] + CHUNKSIZE,*new_i,*new_j; 166a7ed9263SMatthew Knepley size_t len; 16787828ca2SBarry Smith PetscScalar *new_a; 16817ab2063SBarry Smith 16929bbc08cSBarry Smith if (nonew == -2) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%d,%d) in the matrix requiring new malloc()",row,col); 17096854ed6SLois Curfman McInnes 17117ab2063SBarry Smith /* malloc new storage space */ 172a7ed9263SMatthew Knepley len = ((size_t) new_nz)*(sizeof(int)+sizeof(PetscScalar))+(A->m+1)*sizeof(int); 173b0a32e0cSBarry Smith ierr = PetscMalloc(len,&new_a);CHKERRQ(ierr); 17417ab2063SBarry Smith new_j = (int*)(new_a + new_nz); 17517ab2063SBarry Smith new_i = new_j + new_nz; 17617ab2063SBarry Smith 17717ab2063SBarry Smith /* copy over old data into new slots */ 17817ab2063SBarry Smith for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];} 179273d9f13SBarry Smith for (ii=row+1; ii<A->m+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;} 180bfeeae90SHong Zhang ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr); 181bfeeae90SHong Zhang len = (((size_t) new_nz) - CHUNKSIZE - ai[row] - nrow ); 182bfeeae90SHong Zhang ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr); 183bfeeae90SHong Zhang ierr = PetscMemcpy(new_a,aa,(((size_t) ai[row])+nrow)*sizeof(PetscScalar));CHKERRQ(ierr); 184bfeeae90SHong Zhang ierr = PetscMemcpy(new_a+ai[row]+nrow+CHUNKSIZE,aa+ai[row]+nrow,len*sizeof(PetscScalar));CHKERRQ(ierr); 18517ab2063SBarry Smith /* free up old matrix storage */ 186606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 187606d414cSSatish Balay if (!a->singlemalloc) { 188606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 189606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 190606d414cSSatish Balay } 191416022c9SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 192f1e2ffcdSBarry Smith a->singlemalloc = PETSC_TRUE; 19317ab2063SBarry Smith 194bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row] ; 195416022c9SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 19687828ca2SBarry Smith PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + sizeof(PetscScalar))); 197416022c9SBarry Smith a->maxnz += CHUNKSIZE; 198b810aeb4SBarry Smith a->reallocs++; 19917ab2063SBarry Smith } 200416022c9SBarry Smith N = nrow++ - 1; a->nz++; 201416022c9SBarry Smith /* shift up all the later entries in this row */ 202416022c9SBarry Smith for (ii=N; ii>=i; ii--) { 20317ab2063SBarry Smith rp[ii+1] = rp[ii]; 20417ab2063SBarry Smith ap[ii+1] = ap[ii]; 20517ab2063SBarry Smith } 20617ab2063SBarry Smith rp[i] = col; 20717ab2063SBarry Smith ap[i] = value; 20817ab2063SBarry Smith noinsert:; 209416022c9SBarry Smith low = i + 1; 21017ab2063SBarry Smith } 21117ab2063SBarry Smith ailen[row] = nrow; 21217ab2063SBarry Smith } 2133a40ed3dSBarry Smith PetscFunctionReturn(0); 21417ab2063SBarry Smith } 21517ab2063SBarry Smith 2164a2ae208SSatish Balay #undef __FUNCT__ 2174a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ" 218f15d580aSBarry Smith int MatGetValues_SeqAIJ(Mat A,int m,const int im[],int n,const int in[],PetscScalar v[]) 2197eb43aa7SLois Curfman McInnes { 2207eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 221b49de8d1SLois Curfman McInnes int *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 222bfeeae90SHong Zhang int *ai = a->i,*ailen = a->ilen; 22387828ca2SBarry Smith PetscScalar *ap,*aa = a->a,zero = 0.0; 2247eb43aa7SLois Curfman McInnes 2253a40ed3dSBarry Smith PetscFunctionBegin; 2267eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 2277eb43aa7SLois Curfman McInnes row = im[k]; 22829bbc08cSBarry Smith if (row < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %d",row); 229590ac198SBarry Smith if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m-1); 230bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 2317eb43aa7SLois Curfman McInnes nrow = ailen[row]; 2327eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 23329bbc08cSBarry Smith if (in[l] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %d",in[l]); 234590ac198SBarry Smith if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n-1); 235bfeeae90SHong Zhang col = in[l] ; 2367eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 2377eb43aa7SLois Curfman McInnes while (high-low > 5) { 2387eb43aa7SLois Curfman McInnes t = (low+high)/2; 2397eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 2407eb43aa7SLois Curfman McInnes else low = t; 2417eb43aa7SLois Curfman McInnes } 2427eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 2437eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 2447eb43aa7SLois Curfman McInnes if (rp[i] == col) { 245b49de8d1SLois Curfman McInnes *v++ = ap[i]; 2467eb43aa7SLois Curfman McInnes goto finished; 2477eb43aa7SLois Curfman McInnes } 2487eb43aa7SLois Curfman McInnes } 249b49de8d1SLois Curfman McInnes *v++ = zero; 2507eb43aa7SLois Curfman McInnes finished:; 2517eb43aa7SLois Curfman McInnes } 2527eb43aa7SLois Curfman McInnes } 2533a40ed3dSBarry Smith PetscFunctionReturn(0); 2547eb43aa7SLois Curfman McInnes } 2557eb43aa7SLois Curfman McInnes 25617ab2063SBarry Smith 2574a2ae208SSatish Balay #undef __FUNCT__ 2584a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary" 259b0a32e0cSBarry Smith int MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer) 26017ab2063SBarry Smith { 261416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 262416022c9SBarry Smith int i,fd,*col_lens,ierr; 26317ab2063SBarry Smith 2643a40ed3dSBarry Smith PetscFunctionBegin; 265b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 266b0a32e0cSBarry Smith ierr = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr); 267552e946dSBarry Smith col_lens[0] = MAT_FILE_COOKIE; 268273d9f13SBarry Smith col_lens[1] = A->m; 269273d9f13SBarry Smith col_lens[2] = A->n; 270416022c9SBarry Smith col_lens[3] = a->nz; 271416022c9SBarry Smith 272416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 273273d9f13SBarry Smith for (i=0; i<A->m; i++) { 274416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 27517ab2063SBarry Smith } 276273d9f13SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr); 277606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 278416022c9SBarry Smith 279416022c9SBarry Smith /* store column indices (zero start index) */ 2800752156aSBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,0);CHKERRQ(ierr); 281416022c9SBarry Smith 282416022c9SBarry Smith /* store nonzero values */ 2830752156aSBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,0);CHKERRQ(ierr); 2843a40ed3dSBarry Smith PetscFunctionReturn(0); 28517ab2063SBarry Smith } 286416022c9SBarry Smith 2874ffef66eSHong Zhang extern int MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 288cd155464SBarry Smith 2894a2ae208SSatish Balay #undef __FUNCT__ 2904a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII" 291b0a32e0cSBarry Smith int MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 292416022c9SBarry Smith { 293416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 294bfeeae90SHong Zhang int ierr,i,j,m = A->m,shift=0; 295fb9695e5SSatish Balay char *name; 296f3ef73ceSBarry Smith PetscViewerFormat format; 29717ab2063SBarry Smith 2983a40ed3dSBarry Smith PetscFunctionBegin; 299435da068SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 300b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 301456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO_DETAIL || format == PETSC_VIEWER_ASCII_INFO) { 3026831982aSBarry Smith if (a->inode.size) { 303b0a32e0cSBarry 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); 3046831982aSBarry Smith } else { 305b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"not using I-node routines\n");CHKERRQ(ierr); 3066831982aSBarry Smith } 307fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_MATLAB) { 308d00d2cf4SBarry Smith int nofinalvalue = 0; 309273d9f13SBarry Smith if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->n-!shift)) { 310d00d2cf4SBarry Smith nofinalvalue = 1; 311d00d2cf4SBarry Smith } 312b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 313b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %d %d \n",m,A->n);CHKERRQ(ierr); 314b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %d \n",a->nz);CHKERRQ(ierr); 315b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%d,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 316b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 31717ab2063SBarry Smith 31817ab2063SBarry Smith for (i=0; i<m; i++) { 319416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 320aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 321b0a32e0cSBarry 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); 32217ab2063SBarry Smith #else 323b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%d %d %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr); 32417ab2063SBarry Smith #endif 32517ab2063SBarry Smith } 32617ab2063SBarry Smith } 327d00d2cf4SBarry Smith if (nofinalvalue) { 328b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%d %d %18.16e\n",m,A->n,0.0);CHKERRQ(ierr); 329d00d2cf4SBarry Smith } 330fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 331b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 332cd155464SBarry Smith } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 33316ce804cSBarry Smith #if defined(PETSC_HAVE_MATLAB) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_COMPLEX) 3344ffef66eSHong Zhang ierr = MatSeqAIJFactorInfo_Matlab(A,viewer);CHKERRQ(ierr); 3354ffef66eSHong Zhang #endif 336cd155464SBarry Smith PetscFunctionReturn(0); 337fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 338b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 33944cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 340b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr); 34144cd7ae7SLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 342aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 34336db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 34462b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 34536db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 34662b941d6SBarry 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 (PetscRealPart(a->a[j]) != 0.0) { 34862b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 3496831982aSBarry Smith } 35044cd7ae7SLois Curfman McInnes #else 35162b941d6SBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);} 35244cd7ae7SLois Curfman McInnes #endif 35344cd7ae7SLois Curfman McInnes } 354b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 35544cd7ae7SLois Curfman McInnes } 356b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 357fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 358496be53dSLois Curfman McInnes int nzd=0,fshift=1,*sptr; 359b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 360b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&sptr);CHKERRQ(ierr); 361496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 362496be53dSLois Curfman McInnes sptr[i] = nzd+1; 363496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 364496be53dSLois Curfman McInnes if (a->j[j] >= i) { 365aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 36636db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 367496be53dSLois Curfman McInnes #else 368496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 369496be53dSLois Curfman McInnes #endif 370496be53dSLois Curfman McInnes } 371496be53dSLois Curfman McInnes } 372496be53dSLois Curfman McInnes } 3732e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 374b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %d\n\n",m,nzd);CHKERRQ(ierr); 3752e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 376b0a32e0cSBarry 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);} 377b0a32e0cSBarry 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);} 378b0a32e0cSBarry 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);} 379b0a32e0cSBarry Smith else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);} 380b0a32e0cSBarry Smith else if (i<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);} 381b0a32e0cSBarry Smith else {ierr = PetscViewerASCIIPrintf(viewer," %d\n",sptr[i]);CHKERRQ(ierr);} 382496be53dSLois Curfman McInnes } 383b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 384606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 385496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 386496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 387b0a32e0cSBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %d ",a->j[j]+fshift);CHKERRQ(ierr);} 388496be53dSLois Curfman McInnes } 389b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 390496be53dSLois Curfman McInnes } 391b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 392496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 393496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 394496be53dSLois Curfman McInnes if (a->j[j] >= i) { 395aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 39636db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 397b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 3986831982aSBarry Smith } 399496be53dSLois Curfman McInnes #else 400b0a32e0cSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);} 401496be53dSLois Curfman McInnes #endif 402496be53dSLois Curfman McInnes } 403496be53dSLois Curfman McInnes } 404b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 405496be53dSLois Curfman McInnes } 406b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 407fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 40802594712SBarry Smith int cnt = 0,jcnt; 40987828ca2SBarry Smith PetscScalar value; 41002594712SBarry Smith 411b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 41202594712SBarry Smith for (i=0; i<m; i++) { 41302594712SBarry Smith jcnt = 0; 414273d9f13SBarry Smith for (j=0; j<A->n; j++) { 415e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 41602594712SBarry Smith value = a->a[cnt++]; 417e24b481bSBarry Smith jcnt++; 41802594712SBarry Smith } else { 41902594712SBarry Smith value = 0.0; 42002594712SBarry Smith } 421aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 422b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr); 42302594712SBarry Smith #else 424b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr); 42502594712SBarry Smith #endif 42602594712SBarry Smith } 427b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 42802594712SBarry Smith } 429b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 4303a40ed3dSBarry Smith } else { 431b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 43217ab2063SBarry Smith for (i=0; i<m; i++) { 433b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr); 434416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 435aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 43636db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 43762b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 43836db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 43962b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 4403a40ed3dSBarry Smith } else { 44162b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 44217ab2063SBarry Smith } 44317ab2063SBarry Smith #else 44462b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 44517ab2063SBarry Smith #endif 44617ab2063SBarry Smith } 447b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 44817ab2063SBarry Smith } 449b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 45017ab2063SBarry Smith } 451b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 4523a40ed3dSBarry Smith PetscFunctionReturn(0); 453416022c9SBarry Smith } 454416022c9SBarry Smith 4554a2ae208SSatish Balay #undef __FUNCT__ 4564a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom" 457b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 458416022c9SBarry Smith { 459480ef9eaSBarry Smith Mat A = (Mat) Aa; 460416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 461bfeeae90SHong Zhang int ierr,i,j,m = A->m,color; 46236db0b34SBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0; 463b0a32e0cSBarry Smith PetscViewer viewer; 464f3ef73ceSBarry Smith PetscViewerFormat format; 465cddf8d76SBarry Smith 4663a40ed3dSBarry Smith PetscFunctionBegin; 467480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 468b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 46919bcc07fSBarry Smith 470b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 471416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 4720513a670SBarry Smith 473fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 4740513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 475b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 476416022c9SBarry Smith for (i=0; i<m; i++) { 477cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 478bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 479bfeeae90SHong Zhang x_l = a->j[j] ; x_r = x_l + 1.0; 480aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 48136db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 482cddf8d76SBarry Smith #else 483cddf8d76SBarry Smith if (a->a[j] >= 0.) continue; 484cddf8d76SBarry Smith #endif 485b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 486cddf8d76SBarry Smith } 487cddf8d76SBarry Smith } 488b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 489cddf8d76SBarry Smith for (i=0; i<m; i++) { 490cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 491bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 492bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 493cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 494b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 495cddf8d76SBarry Smith } 496cddf8d76SBarry Smith } 497b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 498cddf8d76SBarry Smith for (i=0; i<m; i++) { 499cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 500bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 501bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 502aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 50336db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 504cddf8d76SBarry Smith #else 505cddf8d76SBarry Smith if (a->a[j] <= 0.) continue; 506cddf8d76SBarry Smith #endif 507b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 508416022c9SBarry Smith } 509416022c9SBarry Smith } 5100513a670SBarry Smith } else { 5110513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 5120513a670SBarry Smith /* first determine max of all nonzero values */ 5130513a670SBarry Smith int nz = a->nz,count; 514b0a32e0cSBarry Smith PetscDraw popup; 51536db0b34SBarry Smith PetscReal scale; 5160513a670SBarry Smith 5170513a670SBarry Smith for (i=0; i<nz; i++) { 5180513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 5190513a670SBarry Smith } 520b0a32e0cSBarry Smith scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv; 521b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 522b0a32e0cSBarry Smith if (popup) {ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);} 5230513a670SBarry Smith count = 0; 5240513a670SBarry Smith for (i=0; i<m; i++) { 5250513a670SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 526bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 527bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 528b0a32e0cSBarry Smith color = PETSC_DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(a->a[count])); 529b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 5300513a670SBarry Smith count++; 5310513a670SBarry Smith } 5320513a670SBarry Smith } 5330513a670SBarry Smith } 534480ef9eaSBarry Smith PetscFunctionReturn(0); 535480ef9eaSBarry Smith } 536cddf8d76SBarry Smith 5374a2ae208SSatish Balay #undef __FUNCT__ 5384a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw" 539b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 540480ef9eaSBarry Smith { 541480ef9eaSBarry Smith int ierr; 542b0a32e0cSBarry Smith PetscDraw draw; 54336db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 544480ef9eaSBarry Smith PetscTruth isnull; 545480ef9eaSBarry Smith 546480ef9eaSBarry Smith PetscFunctionBegin; 547b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 548b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 549480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 550480ef9eaSBarry Smith 551480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 552273d9f13SBarry Smith xr = A->n; yr = A->m; h = yr/10.0; w = xr/10.0; 553480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 554b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 555b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 556480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 5573a40ed3dSBarry Smith PetscFunctionReturn(0); 558416022c9SBarry Smith } 559416022c9SBarry Smith 5604a2ae208SSatish Balay #undef __FUNCT__ 5614a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ" 562b0a32e0cSBarry Smith int MatView_SeqAIJ(Mat A,PetscViewer viewer) 563416022c9SBarry Smith { 564416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 565bcd2baecSBarry Smith int ierr; 5666831982aSBarry Smith PetscTruth issocket,isascii,isbinary,isdraw; 567416022c9SBarry Smith 5683a40ed3dSBarry Smith PetscFunctionBegin; 569b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr); 570b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr); 571fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr); 572fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr); 5730f5bd95cSBarry Smith if (issocket) { 574b0a32e0cSBarry Smith ierr = PetscViewerSocketPutSparse_Private(viewer,A->m,A->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr); 5750f5bd95cSBarry Smith } else if (isascii) { 5763a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 5770f5bd95cSBarry Smith } else if (isbinary) { 5783a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 5790f5bd95cSBarry Smith } else if (isdraw) { 5803a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 5815cd90555SBarry Smith } else { 58229bbc08cSBarry Smith SETERRQ1(1,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name); 58317ab2063SBarry Smith } 5843a40ed3dSBarry Smith PetscFunctionReturn(0); 58517ab2063SBarry Smith } 58619bcc07fSBarry Smith 5874a2ae208SSatish Balay #undef __FUNCT__ 5884a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ" 5898f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 59017ab2063SBarry Smith { 591416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 59241c01911SSatish Balay int fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax,ierr; 593bfeeae90SHong Zhang int m = A->m,*ip,N,*ailen = a->ilen,rmax = 0; 59487828ca2SBarry Smith PetscScalar *aa = a->a,*ap; 59517ab2063SBarry Smith 5963a40ed3dSBarry Smith PetscFunctionBegin; 5973a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 59817ab2063SBarry Smith 59943ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 60017ab2063SBarry Smith for (i=1; i<m; i++) { 601416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 60217ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 60394a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 60417ab2063SBarry Smith if (fshift) { 605bfeeae90SHong Zhang ip = aj + ai[i] ; 606bfeeae90SHong Zhang ap = aa + ai[i] ; 60717ab2063SBarry Smith N = ailen[i]; 60817ab2063SBarry Smith for (j=0; j<N; j++) { 60917ab2063SBarry Smith ip[j-fshift] = ip[j]; 61017ab2063SBarry Smith ap[j-fshift] = ap[j]; 61117ab2063SBarry Smith } 61217ab2063SBarry Smith } 61317ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 61417ab2063SBarry Smith } 61517ab2063SBarry Smith if (m) { 61617ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 61717ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 61817ab2063SBarry Smith } 61917ab2063SBarry Smith /* reset ilen and imax for each row */ 62017ab2063SBarry Smith for (i=0; i<m; i++) { 62117ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 62217ab2063SBarry Smith } 623bfeeae90SHong Zhang a->nz = ai[m]; 62417ab2063SBarry Smith 62517ab2063SBarry Smith /* diagonals may have moved, so kill the diagonal pointers */ 626416022c9SBarry Smith if (fshift && a->diag) { 627606d414cSSatish Balay ierr = PetscFree(a->diag);CHKERRQ(ierr); 628b0a32e0cSBarry Smith PetscLogObjectMemory(A,-(m+1)*sizeof(int)); 629416022c9SBarry Smith a->diag = 0; 63017ab2063SBarry Smith } 631b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded,%d used\n",m,A->n,fshift,a->nz); 632b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues() is %d\n",a->reallocs); 633b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Most nonzeros in any row is %d\n",rmax); 634dd5f02e7SSatish Balay a->reallocs = 0; 6354e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift; 63636db0b34SBarry Smith a->rmax = rmax; 6374e220ebcSLois Curfman McInnes 63876dd722bSSatish Balay /* check out for identical nodes. If found, use inode functions */ 6393a7fca6bSBarry Smith ierr = Mat_AIJ_CheckInode(A,(PetscTruth)(!fshift));CHKERRQ(ierr); 640cfef3cccSHong Zhang 6413a40ed3dSBarry Smith PetscFunctionReturn(0); 64217ab2063SBarry Smith } 64317ab2063SBarry Smith 6444a2ae208SSatish Balay #undef __FUNCT__ 6454a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ" 6468f6be9afSLois Curfman McInnes int MatZeroEntries_SeqAIJ(Mat A) 64717ab2063SBarry Smith { 648416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 649549d3d68SSatish Balay int ierr; 6503a40ed3dSBarry Smith 6513a40ed3dSBarry Smith PetscFunctionBegin; 652bfeeae90SHong Zhang ierr = PetscMemzero(a->a,(a->i[A->m])*sizeof(PetscScalar));CHKERRQ(ierr); 6533a40ed3dSBarry Smith PetscFunctionReturn(0); 65417ab2063SBarry Smith } 655416022c9SBarry Smith 6564a2ae208SSatish Balay #undef __FUNCT__ 6574a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ" 658e1311b90SBarry Smith int MatDestroy_SeqAIJ(Mat A) 65917ab2063SBarry Smith { 660416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 66182bf6240SBarry Smith int ierr; 662d5d45c9bSBarry Smith 6633a40ed3dSBarry Smith PetscFunctionBegin; 664aa482453SBarry Smith #if defined(PETSC_USE_LOG) 665b0a32e0cSBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz); 66617ab2063SBarry Smith #endif 66736db0b34SBarry Smith if (a->freedata) { 668606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 669606d414cSSatish Balay if (!a->singlemalloc) { 670606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 671606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 672606d414cSSatish Balay } 67336db0b34SBarry Smith } 674c38d4ed2SBarry Smith if (a->row) { 675c38d4ed2SBarry Smith ierr = ISDestroy(a->row);CHKERRQ(ierr); 676c38d4ed2SBarry Smith } 677c38d4ed2SBarry Smith if (a->col) { 678c38d4ed2SBarry Smith ierr = ISDestroy(a->col);CHKERRQ(ierr); 679c38d4ed2SBarry Smith } 680606d414cSSatish Balay if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);} 681606d414cSSatish Balay if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);} 682606d414cSSatish Balay if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);} 683273d9f13SBarry Smith if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);} 684606d414cSSatish Balay if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);} 685606d414cSSatish Balay if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);} 68682bf6240SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 687606d414cSSatish Balay if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);} 688cc8ba8e1SBarry Smith if (a->coloring) {ierr = ISColoringDestroy(a->coloring);CHKERRQ(ierr);} 689a30b2313SHong Zhang if (a->xtoy) {ierr = PetscFree(a->xtoy);CHKERRQ(ierr);} 690a30b2313SHong Zhang 691606d414cSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 6923a40ed3dSBarry Smith PetscFunctionReturn(0); 69317ab2063SBarry Smith } 69417ab2063SBarry Smith 6954a2ae208SSatish Balay #undef __FUNCT__ 6964a2ae208SSatish Balay #define __FUNCT__ "MatCompress_SeqAIJ" 6978f6be9afSLois Curfman McInnes int MatCompress_SeqAIJ(Mat A) 69817ab2063SBarry Smith { 6993a40ed3dSBarry Smith PetscFunctionBegin; 7003a40ed3dSBarry Smith PetscFunctionReturn(0); 70117ab2063SBarry Smith } 70217ab2063SBarry Smith 7034a2ae208SSatish Balay #undef __FUNCT__ 7044a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ" 7058f6be9afSLois Curfman McInnes int MatSetOption_SeqAIJ(Mat A,MatOption op) 70617ab2063SBarry Smith { 707416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 7083a40ed3dSBarry Smith 7093a40ed3dSBarry Smith PetscFunctionBegin; 710a65d3064SKris Buschelman switch (op) { 711a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 712a65d3064SKris Buschelman a->roworiented = PETSC_TRUE; 713a65d3064SKris Buschelman break; 714a65d3064SKris Buschelman case MAT_KEEP_ZEROED_ROWS: 715a65d3064SKris Buschelman a->keepzeroedrows = PETSC_TRUE; 716a65d3064SKris Buschelman break; 717a65d3064SKris Buschelman case MAT_COLUMN_ORIENTED: 718a65d3064SKris Buschelman a->roworiented = PETSC_FALSE; 719a65d3064SKris Buschelman break; 720a65d3064SKris Buschelman case MAT_COLUMNS_SORTED: 721a65d3064SKris Buschelman a->sorted = PETSC_TRUE; 722a65d3064SKris Buschelman break; 723a65d3064SKris Buschelman case MAT_COLUMNS_UNSORTED: 724a65d3064SKris Buschelman a->sorted = PETSC_FALSE; 725a65d3064SKris Buschelman break; 726a65d3064SKris Buschelman case MAT_NO_NEW_NONZERO_LOCATIONS: 727a65d3064SKris Buschelman a->nonew = 1; 728a65d3064SKris Buschelman break; 729a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 730a65d3064SKris Buschelman a->nonew = -1; 731a65d3064SKris Buschelman break; 732a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 733a65d3064SKris Buschelman a->nonew = -2; 734a65d3064SKris Buschelman break; 735a65d3064SKris Buschelman case MAT_YES_NEW_NONZERO_LOCATIONS: 736a65d3064SKris Buschelman a->nonew = 0; 737a65d3064SKris Buschelman break; 738a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 739a65d3064SKris Buschelman a->ignorezeroentries = PETSC_TRUE; 740a65d3064SKris Buschelman break; 741a65d3064SKris Buschelman case MAT_USE_INODES: 742a65d3064SKris Buschelman a->inode.use = PETSC_TRUE; 743a65d3064SKris Buschelman break; 744a65d3064SKris Buschelman case MAT_DO_NOT_USE_INODES: 745a65d3064SKris Buschelman a->inode.use = PETSC_FALSE; 746a65d3064SKris Buschelman break; 747a65d3064SKris Buschelman case MAT_ROWS_SORTED: 748a65d3064SKris Buschelman case MAT_ROWS_UNSORTED: 749a65d3064SKris Buschelman case MAT_YES_NEW_DIAGONALS: 750a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 751a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 752b0a32e0cSBarry Smith PetscLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n"); 753a65d3064SKris Buschelman break; 754a65d3064SKris Buschelman case MAT_NO_NEW_DIAGONALS: 75529bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS"); 756a65d3064SKris Buschelman case MAT_INODE_LIMIT_1: 757a65d3064SKris Buschelman a->inode.limit = 1; 758a65d3064SKris Buschelman break; 759a65d3064SKris Buschelman case MAT_INODE_LIMIT_2: 760a65d3064SKris Buschelman a->inode.limit = 2; 761a65d3064SKris Buschelman break; 762a65d3064SKris Buschelman case MAT_INODE_LIMIT_3: 763a65d3064SKris Buschelman a->inode.limit = 3; 764a65d3064SKris Buschelman break; 765a65d3064SKris Buschelman case MAT_INODE_LIMIT_4: 766a65d3064SKris Buschelman a->inode.limit = 4; 767a65d3064SKris Buschelman break; 768a65d3064SKris Buschelman case MAT_INODE_LIMIT_5: 769a65d3064SKris Buschelman a->inode.limit = 5; 770a65d3064SKris Buschelman break; 77177e54ba9SKris Buschelman case MAT_SYMMETRIC: 77277e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 773*9a4540c5SBarry Smith case MAT_NOT_SYMMETRIC: 774*9a4540c5SBarry Smith case MAT_NOT_STRUCTURALLY_SYMMETRIC: 775*9a4540c5SBarry Smith case MAT_HERMITIAN: 776*9a4540c5SBarry Smith case MAT_NOT_HERMITIAN: 777*9a4540c5SBarry Smith case MAT_SYMMETRY_ETERNAL: 778*9a4540c5SBarry Smith case MAT_NOT_SYMMETRY_ETERNAL: 77977e54ba9SKris Buschelman break; 780a65d3064SKris Buschelman default: 781a65d3064SKris Buschelman SETERRQ(PETSC_ERR_SUP,"unknown option"); 782a65d3064SKris Buschelman } 7833a40ed3dSBarry Smith PetscFunctionReturn(0); 78417ab2063SBarry Smith } 78517ab2063SBarry Smith 7864a2ae208SSatish Balay #undef __FUNCT__ 7874a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ" 7888f6be9afSLois Curfman McInnes int MatGetDiagonal_SeqAIJ(Mat A,Vec v) 78917ab2063SBarry Smith { 790416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 791bfeeae90SHong Zhang int i,j,n,ierr; 79287828ca2SBarry Smith PetscScalar *x,zero = 0.0; 79317ab2063SBarry Smith 7943a40ed3dSBarry Smith PetscFunctionBegin; 7953a40ed3dSBarry Smith ierr = VecSet(&zero,v);CHKERRQ(ierr); 796ed480e8bSBarry Smith ierr = VecGetArrayFast(v,&x);CHKERRQ(ierr); 79736db0b34SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 798273d9f13SBarry Smith if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 799273d9f13SBarry Smith for (i=0; i<A->m; i++) { 800bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 801bfeeae90SHong Zhang if (a->j[j] == i) { 802416022c9SBarry Smith x[i] = a->a[j]; 80317ab2063SBarry Smith break; 80417ab2063SBarry Smith } 80517ab2063SBarry Smith } 80617ab2063SBarry Smith } 807ed480e8bSBarry Smith ierr = VecRestoreArrayFast(v,&x);CHKERRQ(ierr); 8083a40ed3dSBarry Smith PetscFunctionReturn(0); 80917ab2063SBarry Smith } 81017ab2063SBarry Smith 811d5d45c9bSBarry Smith 8124a2ae208SSatish Balay #undef __FUNCT__ 8134a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ" 8147c922b88SBarry Smith int MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 81517ab2063SBarry Smith { 816416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 8175c897100SBarry Smith PetscScalar *x,*y; 818bfeeae90SHong Zhang int ierr,m = A->m; 8195c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 8205c897100SBarry Smith PetscScalar *v,alpha; 8215c897100SBarry Smith int n,i,*idx; 8225c897100SBarry Smith #endif 82317ab2063SBarry Smith 8243a40ed3dSBarry Smith PetscFunctionBegin; 8252e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 826ed480e8bSBarry Smith ierr = VecGetArrayFast(xx,&x);CHKERRQ(ierr); 827ed480e8bSBarry Smith ierr = VecGetArrayFast(yy,&y);CHKERRQ(ierr); 8285c897100SBarry Smith 8295c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 830bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 8315c897100SBarry Smith #else 83217ab2063SBarry Smith for (i=0; i<m; i++) { 833bfeeae90SHong Zhang idx = a->j + a->i[i] ; 834bfeeae90SHong Zhang v = a->a + a->i[i] ; 835416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 83617ab2063SBarry Smith alpha = x[i]; 83717ab2063SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 83817ab2063SBarry Smith } 8395c897100SBarry Smith #endif 840b0a32e0cSBarry Smith PetscLogFlops(2*a->nz); 841ed480e8bSBarry Smith ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr); 842ed480e8bSBarry Smith ierr = VecRestoreArrayFast(yy,&y);CHKERRQ(ierr); 8433a40ed3dSBarry Smith PetscFunctionReturn(0); 84417ab2063SBarry Smith } 84517ab2063SBarry Smith 8464a2ae208SSatish Balay #undef __FUNCT__ 8475c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ" 8485c897100SBarry Smith int MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 8495c897100SBarry Smith { 8508d5b0100SBarry Smith PetscScalar zero = 0.0; 8515c897100SBarry Smith int ierr; 8525c897100SBarry Smith 8535c897100SBarry Smith PetscFunctionBegin; 8545c897100SBarry Smith ierr = VecSet(&zero,yy);CHKERRQ(ierr); 8555c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 8565c897100SBarry Smith PetscFunctionReturn(0); 8575c897100SBarry Smith } 8585c897100SBarry Smith 8595c897100SBarry Smith 8605c897100SBarry Smith #undef __FUNCT__ 8614a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ" 86244cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 86317ab2063SBarry Smith { 864416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 865362ced78SSatish Balay PetscScalar *x,*y,*v; 866bfeeae90SHong Zhang int ierr,m = A->m,*idx,*ii; 867aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 868e36a17ebSSatish Balay int n,i,jrow,j; 869362ced78SSatish Balay PetscScalar sum; 870e36a17ebSSatish Balay #endif 87117ab2063SBarry Smith 872b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 873fee21e36SBarry Smith #pragma disjoint(*x,*y,*v) 874fee21e36SBarry Smith #endif 875fee21e36SBarry Smith 8763a40ed3dSBarry Smith PetscFunctionBegin; 877ed480e8bSBarry Smith ierr = VecGetArrayFast(xx,&x);CHKERRQ(ierr); 878ed480e8bSBarry Smith ierr = VecGetArrayFast(yy,&y);CHKERRQ(ierr); 879416022c9SBarry Smith idx = a->j; 880d64ed03dSBarry Smith v = a->a; 881416022c9SBarry Smith ii = a->i; 882aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 883bfeeae90SHong Zhang fortranmultaij_(&m,x,ii,idx,v,y); 8848d195f9aSBarry Smith #else 88517ab2063SBarry Smith for (i=0; i<m; i++) { 8869ea0dfa2SSatish Balay jrow = ii[i]; 8879ea0dfa2SSatish Balay n = ii[i+1] - jrow; 88817ab2063SBarry Smith sum = 0.0; 8899ea0dfa2SSatish Balay for (j=0; j<n; j++) { 8909ea0dfa2SSatish Balay sum += v[jrow]*x[idx[jrow]]; jrow++; 8919ea0dfa2SSatish Balay } 89217ab2063SBarry Smith y[i] = sum; 89317ab2063SBarry Smith } 8948d195f9aSBarry Smith #endif 895b0a32e0cSBarry Smith PetscLogFlops(2*a->nz - m); 896ed480e8bSBarry Smith ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr); 897ed480e8bSBarry Smith ierr = VecRestoreArrayFast(yy,&y);CHKERRQ(ierr); 8983a40ed3dSBarry Smith PetscFunctionReturn(0); 89917ab2063SBarry Smith } 90017ab2063SBarry Smith 9014a2ae208SSatish Balay #undef __FUNCT__ 9024a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ" 90344cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 90417ab2063SBarry Smith { 905416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 906362ced78SSatish Balay PetscScalar *x,*y,*z,*v; 907bfeeae90SHong Zhang int ierr,m = A->m,*idx,*ii; 908aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 909e36a17ebSSatish Balay int n,i,jrow,j; 910362ced78SSatish Balay PetscScalar sum; 911e36a17ebSSatish Balay #endif 9129ea0dfa2SSatish Balay 9133a40ed3dSBarry Smith PetscFunctionBegin; 914ed480e8bSBarry Smith ierr = VecGetArrayFast(xx,&x);CHKERRQ(ierr); 915ed480e8bSBarry Smith ierr = VecGetArrayFast(yy,&y);CHKERRQ(ierr); 9162e8a6d31SBarry Smith if (zz != yy) { 917ed480e8bSBarry Smith ierr = VecGetArrayFast(zz,&z);CHKERRQ(ierr); 9182e8a6d31SBarry Smith } else { 9192e8a6d31SBarry Smith z = y; 9202e8a6d31SBarry Smith } 921bfeeae90SHong Zhang 922cddf8d76SBarry Smith idx = a->j; 923d64ed03dSBarry Smith v = a->a; 924cddf8d76SBarry Smith ii = a->i; 925aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 926bfeeae90SHong Zhang fortranmultaddaij_(&m,x,ii,idx,v,y,z); 92702ab625aSSatish Balay #else 92817ab2063SBarry Smith for (i=0; i<m; i++) { 9299ea0dfa2SSatish Balay jrow = ii[i]; 9309ea0dfa2SSatish Balay n = ii[i+1] - jrow; 93117ab2063SBarry Smith sum = y[i]; 9329ea0dfa2SSatish Balay for (j=0; j<n; j++) { 9339ea0dfa2SSatish Balay sum += v[jrow]*x[idx[jrow]]; jrow++; 9349ea0dfa2SSatish Balay } 93517ab2063SBarry Smith z[i] = sum; 93617ab2063SBarry Smith } 93702ab625aSSatish Balay #endif 938b0a32e0cSBarry Smith PetscLogFlops(2*a->nz); 939ed480e8bSBarry Smith ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr); 940ed480e8bSBarry Smith ierr = VecRestoreArrayFast(yy,&y);CHKERRQ(ierr); 9412e8a6d31SBarry Smith if (zz != yy) { 942ed480e8bSBarry Smith ierr = VecRestoreArrayFast(zz,&z);CHKERRQ(ierr); 9432e8a6d31SBarry Smith } 9443a40ed3dSBarry Smith PetscFunctionReturn(0); 94517ab2063SBarry Smith } 94617ab2063SBarry Smith 94717ab2063SBarry Smith /* 94817ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 94917ab2063SBarry Smith */ 9504a2ae208SSatish Balay #undef __FUNCT__ 9514a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ" 952f1e2ffcdSBarry Smith int MatMarkDiagonal_SeqAIJ(Mat A) 95317ab2063SBarry Smith { 954416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 955bfeeae90SHong Zhang int i,j,*diag,m = A->m,ierr; 95617ab2063SBarry Smith 9573a40ed3dSBarry Smith PetscFunctionBegin; 958f1e2ffcdSBarry Smith if (a->diag) PetscFunctionReturn(0); 959f1e2ffcdSBarry Smith 960b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&diag);CHKERRQ(ierr); 961b0a32e0cSBarry Smith PetscLogObjectMemory(A,(m+1)*sizeof(int)); 962273d9f13SBarry Smith for (i=0; i<A->m; i++) { 96335b0346bSBarry Smith diag[i] = a->i[i+1]; 964bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 965bfeeae90SHong Zhang if (a->j[j] == i) { 966bfeeae90SHong Zhang diag[i] = j; 96717ab2063SBarry Smith break; 96817ab2063SBarry Smith } 96917ab2063SBarry Smith } 97017ab2063SBarry Smith } 971416022c9SBarry Smith a->diag = diag; 9723a40ed3dSBarry Smith PetscFunctionReturn(0); 97317ab2063SBarry Smith } 97417ab2063SBarry Smith 975be5855fcSBarry Smith /* 976be5855fcSBarry Smith Checks for missing diagonals 977be5855fcSBarry Smith */ 9784a2ae208SSatish Balay #undef __FUNCT__ 9794a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ" 980f1e2ffcdSBarry Smith int MatMissingDiagonal_SeqAIJ(Mat A) 981be5855fcSBarry Smith { 982be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 983bfeeae90SHong Zhang int *diag,*jj = a->j,i,ierr; 984be5855fcSBarry Smith 985be5855fcSBarry Smith PetscFunctionBegin; 986f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 987f1e2ffcdSBarry Smith diag = a->diag; 988273d9f13SBarry Smith for (i=0; i<A->m; i++) { 989bfeeae90SHong Zhang if (jj[diag[i]] != i) { 99029bbc08cSBarry Smith SETERRQ1(1,"Matrix is missing diagonal number %d",i); 991be5855fcSBarry Smith } 992be5855fcSBarry Smith } 993be5855fcSBarry Smith PetscFunctionReturn(0); 994be5855fcSBarry Smith } 995be5855fcSBarry Smith 9964a2ae208SSatish Balay #undef __FUNCT__ 9974a2ae208SSatish Balay #define __FUNCT__ "MatRelax_SeqAIJ" 998c14dc6b6SHong Zhang int MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,int its,int lits,Vec xx) 99917ab2063SBarry Smith { 1000416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1001beeb8507SBarry Smith PetscScalar *x,d,*xs,sum,*t,scale,*idiag=0,*mdiag; 1002beeb8507SBarry Smith const PetscScalar *v = a->a, *b, *bs,*xb, *ts; 1003beeb8507SBarry Smith int ierr,n = A->n,m = A->m,i; 1004beeb8507SBarry Smith const int *idx,*diag; 100517ab2063SBarry Smith 10063a40ed3dSBarry Smith PetscFunctionBegin; 1007b965ef7fSBarry Smith its = its*lits; 100891723122SBarry Smith if (its <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %d and local its %d both positive",its,lits); 100991723122SBarry Smith 1010ed480e8bSBarry Smith if (!a->diag) {ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);} 1011ed480e8bSBarry Smith diag = a->diag; 1012ed480e8bSBarry Smith if (!a->idiag) { 1013ed480e8bSBarry Smith ierr = PetscMalloc(3*m*sizeof(PetscScalar),&a->idiag);CHKERRQ(ierr); 1014ed480e8bSBarry Smith a->ssor = a->idiag + m; 1015ed480e8bSBarry Smith mdiag = a->ssor + m; 1016ed480e8bSBarry Smith 1017ed480e8bSBarry Smith v = a->a; 1018ed480e8bSBarry Smith 1019ed480e8bSBarry Smith /* this is wrong when fshift omega changes each iteration */ 1020ed480e8bSBarry Smith if (omega == 1.0 && fshift == 0.0) { 1021ed480e8bSBarry Smith for (i=0; i<m; i++) { 1022ed480e8bSBarry Smith mdiag[i] = v[diag[i]]; 1023ed480e8bSBarry Smith a->idiag[i] = 1.0/v[diag[i]]; 1024ed480e8bSBarry Smith } 1025beeb8507SBarry Smith PetscLogFlops(m); 1026ed480e8bSBarry Smith } else { 1027ed480e8bSBarry Smith for (i=0; i<m; i++) { 1028ed480e8bSBarry Smith mdiag[i] = v[diag[i]]; 1029beeb8507SBarry Smith a->idiag[i] = omega/(fshift + v[diag[i]]); 1030ed480e8bSBarry Smith } 1031beeb8507SBarry Smith PetscLogFlops(2*m); 1032beeb8507SBarry Smith } 1033ed480e8bSBarry Smith } 1034ed480e8bSBarry Smith t = a->ssor; 1035ed480e8bSBarry Smith idiag = a->idiag; 1036ed480e8bSBarry Smith mdiag = a->idiag + 2*m; 1037ed480e8bSBarry Smith 1038ed480e8bSBarry Smith ierr = VecGetArrayFast(xx,&x);CHKERRQ(ierr); 1039fb2e594dSBarry Smith if (xx != bb) { 1040beeb8507SBarry Smith ierr = VecGetArrayFast(bb,(PetscScalar**)&b);CHKERRQ(ierr); 1041fb2e594dSBarry Smith } else { 1042fb2e594dSBarry Smith b = x; 1043fb2e594dSBarry Smith } 1044fb2e594dSBarry Smith 1045ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 1046ed480e8bSBarry Smith xs = x; 104717ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 104817ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1049ed480e8bSBarry Smith bs = b; 105017ab2063SBarry Smith for (i=0; i<m; i++) { 1051ed480e8bSBarry Smith d = fshift + a->a[diag[i]]; 1052416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1053ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1054ed480e8bSBarry Smith v = a->a + diag[i] + 1; 105517ab2063SBarry Smith sum = b[i]*d/omega; 105617ab2063SBarry Smith SPARSEDENSEDOT(sum,bs,v,idx,n); 105717ab2063SBarry Smith x[i] = sum; 105817ab2063SBarry Smith } 1059ed480e8bSBarry Smith ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr); 1060beeb8507SBarry Smith if (bb != xx) {ierr = VecRestoreArrayFast(bb,(PetscScalar**)&b);CHKERRQ(ierr);} 1061ed480e8bSBarry Smith PetscLogFlops(a->nz); 10623a40ed3dSBarry Smith PetscFunctionReturn(0); 106317ab2063SBarry Smith } 1064c783ea89SBarry Smith 1065ed480e8bSBarry Smith 1066fc3d8934SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1067fc3d8934SBarry Smith U is upper triangular, E is diagonal; This routine applies 1068fc3d8934SBarry Smith 1069fc3d8934SBarry Smith (L + E)^{-1} A (U + E)^{-1} 1070fc3d8934SBarry Smith 1071fc3d8934SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 1072fc3d8934SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 107348af12d7SBarry Smith is the relaxation factor. 1074fc3d8934SBarry Smith */ 1075fc3d8934SBarry Smith 107648af12d7SBarry Smith if (flag == SOR_APPLY_LOWER) { 107729bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 10783a40ed3dSBarry Smith } else if (flag & SOR_EISENSTAT) { 107917ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 108017ab2063SBarry Smith U is upper triangular, E is diagonal; This routine applies 108117ab2063SBarry Smith 108217ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 108317ab2063SBarry Smith 108417ab2063SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 108517ab2063SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 108617ab2063SBarry Smith is the relaxation factor. 108717ab2063SBarry Smith */ 108817ab2063SBarry Smith scale = (2.0/omega) - 1.0; 108917ab2063SBarry Smith 109017ab2063SBarry Smith /* x = (E + U)^{-1} b */ 109117ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1092416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1093ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1094ed480e8bSBarry Smith v = a->a + diag[i] + 1; 109517ab2063SBarry Smith sum = b[i]; 109617ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1097ed480e8bSBarry Smith x[i] = sum*idiag[i]; 109817ab2063SBarry Smith } 109917ab2063SBarry Smith 110017ab2063SBarry Smith /* t = b - (2*E - D)x */ 1101416022c9SBarry Smith v = a->a; 1102ed480e8bSBarry Smith for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; } 110317ab2063SBarry Smith 110417ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1105ed480e8bSBarry Smith ts = t; 1106416022c9SBarry Smith diag = a->diag; 110717ab2063SBarry Smith for (i=0; i<m; i++) { 1108416022c9SBarry Smith n = diag[i] - a->i[i]; 1109ed480e8bSBarry Smith idx = a->j + a->i[i]; 1110ed480e8bSBarry Smith v = a->a + a->i[i]; 111117ab2063SBarry Smith sum = t[i]; 111217ab2063SBarry Smith SPARSEDENSEMDOT(sum,ts,v,idx,n); 1113ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1114733d66baSBarry Smith /* x = x + t */ 1115733d66baSBarry Smith x[i] += t[i]; 111617ab2063SBarry Smith } 111717ab2063SBarry Smith 1118b0a32e0cSBarry Smith PetscLogFlops(6*m-1 + 2*a->nz); 1119ed480e8bSBarry Smith ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr); 1120beeb8507SBarry Smith if (bb != xx) {ierr = VecRestoreArrayFast(bb,(PetscScalar**)&b);CHKERRQ(ierr);} 11213a40ed3dSBarry Smith PetscFunctionReturn(0); 112217ab2063SBarry Smith } 112317ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 112417ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 112577d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 11260c559628SSatish Balay fortranrelaxaijforwardzero_(&m,&omega,x,a->i,a->j,(int *)diag,idiag,a->a,(void*)b); 112777d8c4bbSBarry Smith #else 112817ab2063SBarry Smith for (i=0; i<m; i++) { 1129416022c9SBarry Smith n = diag[i] - a->i[i]; 1130ed480e8bSBarry Smith idx = a->j + a->i[i]; 1131ed480e8bSBarry Smith v = a->a + a->i[i]; 113217ab2063SBarry Smith sum = b[i]; 113317ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1134ed480e8bSBarry Smith x[i] = sum*idiag[i]; 113517ab2063SBarry Smith } 113677d8c4bbSBarry Smith #endif 113717ab2063SBarry Smith xb = x; 1138ed480e8bSBarry Smith PetscLogFlops(a->nz); 11393a40ed3dSBarry Smith } else xb = b; 114017ab2063SBarry Smith if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) && 114117ab2063SBarry Smith (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) { 114217ab2063SBarry Smith for (i=0; i<m; i++) { 1143ed480e8bSBarry Smith x[i] *= mdiag[i]; 114417ab2063SBarry Smith } 1145b0a32e0cSBarry Smith PetscLogFlops(m); 114617ab2063SBarry Smith } 114717ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 114877d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 11490c559628SSatish Balay fortranrelaxaijbackwardzero_(&m,&omega,x,a->i,a->j,(int*)diag,idiag,a->a,(void*)xb); 115077d8c4bbSBarry Smith #else 115117ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1152416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1153ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1154ed480e8bSBarry Smith v = a->a + diag[i] + 1; 115517ab2063SBarry Smith sum = xb[i]; 115617ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1157ed480e8bSBarry Smith x[i] = sum*idiag[i]; 115817ab2063SBarry Smith } 115977d8c4bbSBarry Smith #endif 1160ed480e8bSBarry Smith PetscLogFlops(a->nz); 116117ab2063SBarry Smith } 116217ab2063SBarry Smith its--; 116317ab2063SBarry Smith } 116417ab2063SBarry Smith while (its--) { 116517ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 116677d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 11670c559628SSatish Balay fortranrelaxaijforward_(&m,&omega,x,a->i,a->j,(int*)diag,a->a,(void*)b); 116877d8c4bbSBarry Smith #else 116917ab2063SBarry Smith for (i=0; i<m; i++) { 1170ed480e8bSBarry Smith d = fshift + a->a[diag[i]]; 1171416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1172ed480e8bSBarry Smith idx = a->j + a->i[i]; 1173ed480e8bSBarry Smith v = a->a + a->i[i]; 117417ab2063SBarry Smith sum = b[i]; 117517ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1176ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 117717ab2063SBarry Smith } 117877d8c4bbSBarry Smith #endif 1179ed480e8bSBarry Smith PetscLogFlops(a->nz); 118017ab2063SBarry Smith } 118117ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 118277d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 11830c559628SSatish Balay fortranrelaxaijbackward_(&m,&omega,x,a->i,a->j,(int*)diag,a->a,(void*)b); 118477d8c4bbSBarry Smith #else 118517ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1186ed480e8bSBarry Smith d = fshift + a->a[diag[i]]; 1187416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1188ed480e8bSBarry Smith idx = a->j + a->i[i]; 1189ed480e8bSBarry Smith v = a->a + a->i[i]; 119017ab2063SBarry Smith sum = b[i]; 119117ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1192ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 119317ab2063SBarry Smith } 119477d8c4bbSBarry Smith #endif 1195ed480e8bSBarry Smith PetscLogFlops(a->nz); 119617ab2063SBarry Smith } 119717ab2063SBarry Smith } 1198ed480e8bSBarry Smith ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr); 1199beeb8507SBarry Smith if (bb != xx) {ierr = VecRestoreArrayFast(bb,(PetscScalar**)&b);CHKERRQ(ierr);} 12003a40ed3dSBarry Smith PetscFunctionReturn(0); 120117ab2063SBarry Smith } 120217ab2063SBarry Smith 12034a2ae208SSatish Balay #undef __FUNCT__ 12044a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ" 12058f6be9afSLois Curfman McInnes int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 120617ab2063SBarry Smith { 1207416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 12084e220ebcSLois Curfman McInnes 12093a40ed3dSBarry Smith PetscFunctionBegin; 1210273d9f13SBarry Smith info->rows_global = (double)A->m; 1211273d9f13SBarry Smith info->columns_global = (double)A->n; 1212273d9f13SBarry Smith info->rows_local = (double)A->m; 1213273d9f13SBarry Smith info->columns_local = (double)A->n; 12144e220ebcSLois Curfman McInnes info->block_size = 1.0; 12154e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 12164e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 12174e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 12184e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 12194e220ebcSLois Curfman McInnes info->mallocs = (double)a->reallocs; 12204e220ebcSLois Curfman McInnes info->memory = A->mem; 12214e220ebcSLois Curfman McInnes if (A->factor) { 12224e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 12234e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 12244e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 12254e220ebcSLois Curfman McInnes } else { 12264e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 12274e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 12284e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 12294e220ebcSLois Curfman McInnes } 12303a40ed3dSBarry Smith PetscFunctionReturn(0); 123117ab2063SBarry Smith } 123217ab2063SBarry Smith 12334a2ae208SSatish Balay #undef __FUNCT__ 12344a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ" 1235268466fbSBarry Smith int MatZeroRows_SeqAIJ(Mat A,IS is,const PetscScalar *diag) 123617ab2063SBarry Smith { 1237416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1238bfeeae90SHong Zhang int i,ierr,N,*rows,m = A->m - 1; 123917ab2063SBarry Smith 12403a40ed3dSBarry Smith PetscFunctionBegin; 1241b9b97703SBarry Smith ierr = ISGetLocalSize(is,&N);CHKERRQ(ierr); 124217ab2063SBarry Smith ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 1243f1e2ffcdSBarry Smith if (a->keepzeroedrows) { 1244f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1245a45adfd6SMatthew Knepley if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range", rows[i]); 1246bfeeae90SHong Zhang ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 1247f1e2ffcdSBarry Smith } 1248f1e2ffcdSBarry Smith if (diag) { 1249f1e2ffcdSBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1250f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1251f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1252f1e2ffcdSBarry Smith a->a[a->diag[rows[i]]] = *diag; 1253f1e2ffcdSBarry Smith } 1254f1e2ffcdSBarry Smith } 1255f1e2ffcdSBarry Smith } else { 125617ab2063SBarry Smith if (diag) { 125717ab2063SBarry Smith for (i=0; i<N; i++) { 1258a45adfd6SMatthew Knepley if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range", rows[i]); 12597ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1260416022c9SBarry Smith a->ilen[rows[i]] = 1; 1261bfeeae90SHong Zhang a->a[a->i[rows[i]]] = *diag; 1262bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 12637ae801bdSBarry Smith } else { /* in case row was completely empty */ 1264d64ed03dSBarry Smith ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr); 126517ab2063SBarry Smith } 126617ab2063SBarry Smith } 12673a40ed3dSBarry Smith } else { 126817ab2063SBarry Smith for (i=0; i<N; i++) { 1269a45adfd6SMatthew Knepley if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range", rows[i]); 1270416022c9SBarry Smith a->ilen[rows[i]] = 0; 127117ab2063SBarry Smith } 127217ab2063SBarry Smith } 1273f1e2ffcdSBarry Smith } 12747ae801bdSBarry Smith ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 127543a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 12763a40ed3dSBarry Smith PetscFunctionReturn(0); 127717ab2063SBarry Smith } 127817ab2063SBarry Smith 12794a2ae208SSatish Balay #undef __FUNCT__ 12804a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ" 128187828ca2SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v) 128217ab2063SBarry Smith { 1283416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1284b3fb0a6cSMatthew Knepley int *itmp; 128517ab2063SBarry Smith 12863a40ed3dSBarry Smith PetscFunctionBegin; 1287273d9f13SBarry Smith if (row < 0 || row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %d out of range",row); 128817ab2063SBarry Smith 1289416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1290bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 129117ab2063SBarry Smith if (idx) { 1292bfeeae90SHong Zhang itmp = a->j + a->i[row]; 1293bfeeae90SHong Zhang if (*nz) { 12944e093b46SBarry Smith *idx = itmp; 129517ab2063SBarry Smith } 129617ab2063SBarry Smith else *idx = 0; 129717ab2063SBarry Smith } 12983a40ed3dSBarry Smith PetscFunctionReturn(0); 129917ab2063SBarry Smith } 130017ab2063SBarry Smith 1301bfeeae90SHong Zhang /* remove this function? */ 13024a2ae208SSatish Balay #undef __FUNCT__ 13034a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ" 130487828ca2SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v) 130517ab2063SBarry Smith { 1306bfeeae90SHong Zhang /* Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1307bfeeae90SHong Zhang int ierr; */ 13083a40ed3dSBarry Smith 13093a40ed3dSBarry Smith PetscFunctionBegin; 1310bfeeae90SHong Zhang /* if (idx) {if (*idx && a->indexshift) {ierr = PetscFree(*idx);CHKERRQ(ierr);}} */ 13113a40ed3dSBarry Smith PetscFunctionReturn(0); 131217ab2063SBarry Smith } 131317ab2063SBarry Smith 13144a2ae208SSatish Balay #undef __FUNCT__ 13154a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ" 1316064f8208SBarry Smith int MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 131717ab2063SBarry Smith { 1318416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 131987828ca2SBarry Smith PetscScalar *v = a->a; 132036db0b34SBarry Smith PetscReal sum = 0.0; 1321bfeeae90SHong Zhang int i,j,ierr; 132217ab2063SBarry Smith 13233a40ed3dSBarry Smith PetscFunctionBegin; 132417ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1325416022c9SBarry Smith for (i=0; i<a->nz; i++) { 1326aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 132736db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 132817ab2063SBarry Smith #else 132917ab2063SBarry Smith sum += (*v)*(*v); v++; 133017ab2063SBarry Smith #endif 133117ab2063SBarry Smith } 1332064f8208SBarry Smith *nrm = sqrt(sum); 13333a40ed3dSBarry Smith } else if (type == NORM_1) { 133436db0b34SBarry Smith PetscReal *tmp; 1335416022c9SBarry Smith int *jj = a->j; 1336b0a32e0cSBarry Smith ierr = PetscMalloc((A->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr); 1337273d9f13SBarry Smith ierr = PetscMemzero(tmp,A->n*sizeof(PetscReal));CHKERRQ(ierr); 1338064f8208SBarry Smith *nrm = 0.0; 1339416022c9SBarry Smith for (j=0; j<a->nz; j++) { 1340bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 134117ab2063SBarry Smith } 1342273d9f13SBarry Smith for (j=0; j<A->n; j++) { 1343064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 134417ab2063SBarry Smith } 1345606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 13463a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1347064f8208SBarry Smith *nrm = 0.0; 1348273d9f13SBarry Smith for (j=0; j<A->m; j++) { 1349bfeeae90SHong Zhang v = a->a + a->i[j]; 135017ab2063SBarry Smith sum = 0.0; 1351416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 1352cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 135317ab2063SBarry Smith } 1354064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 135517ab2063SBarry Smith } 13563a40ed3dSBarry Smith } else { 135729bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"No support for two norm"); 135817ab2063SBarry Smith } 13593a40ed3dSBarry Smith PetscFunctionReturn(0); 136017ab2063SBarry Smith } 136117ab2063SBarry Smith 13624a2ae208SSatish Balay #undef __FUNCT__ 13634a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ" 13648f6be9afSLois Curfman McInnes int MatTranspose_SeqAIJ(Mat A,Mat *B) 136517ab2063SBarry Smith { 1366416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1367416022c9SBarry Smith Mat C; 1368273d9f13SBarry Smith int i,ierr,*aj = a->j,*ai = a->i,m = A->m,len,*col; 136987828ca2SBarry Smith PetscScalar *array = a->a; 137017ab2063SBarry Smith 13713a40ed3dSBarry Smith PetscFunctionBegin; 1372273d9f13SBarry Smith if (!B && m != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Square matrix only for in-place"); 1373b0a32e0cSBarry Smith ierr = PetscMalloc((1+A->n)*sizeof(int),&col);CHKERRQ(ierr); 1374273d9f13SBarry Smith ierr = PetscMemzero(col,(1+A->n)*sizeof(int));CHKERRQ(ierr); 1375bfeeae90SHong Zhang 1376bfeeae90SHong Zhang for (i=0; i<ai[m]; i++) col[aj[i]] += 1; 1377273d9f13SBarry Smith ierr = MatCreateSeqAIJ(A->comm,A->n,m,0,col,&C);CHKERRQ(ierr); 1378606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 137917ab2063SBarry Smith for (i=0; i<m; i++) { 138017ab2063SBarry Smith len = ai[i+1]-ai[i]; 1381416022c9SBarry Smith ierr = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 1382b9b97703SBarry Smith array += len; 1383b9b97703SBarry Smith aj += len; 138417ab2063SBarry Smith } 138517ab2063SBarry Smith 13866d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13876d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 138817ab2063SBarry Smith 1389f1e2ffcdSBarry Smith if (B) { 1390416022c9SBarry Smith *B = C; 139117ab2063SBarry Smith } else { 1392273d9f13SBarry Smith ierr = MatHeaderCopy(A,C);CHKERRQ(ierr); 139317ab2063SBarry Smith } 13943a40ed3dSBarry Smith PetscFunctionReturn(0); 139517ab2063SBarry Smith } 139617ab2063SBarry Smith 1397cd0d46ebSvictorle EXTERN_C_BEGIN 1398cd0d46ebSvictorle #undef __FUNCT__ 13995fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ" 14005fbd3699SBarry Smith int MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscTruth *f) 1401cd0d46ebSvictorle { 1402cd0d46ebSvictorle Mat_SeqAIJ *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data; 1403cd0d46ebSvictorle int *adx,*bdx,*aii,*bii,*aptr,*bptr; PetscScalar *va,*vb; 1404cd0d46ebSvictorle int ma,na,mb,nb, i,ierr; 1405cd0d46ebSvictorle 1406cd0d46ebSvictorle PetscFunctionBegin; 1407cd0d46ebSvictorle bij = (Mat_SeqAIJ *) B->data; 1408cd0d46ebSvictorle 1409cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na); CHKERRQ(ierr); 1410cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb); CHKERRQ(ierr); 1411cd0d46ebSvictorle if (ma!=nb || na!=mb) 1412cd0d46ebSvictorle SETERRQ(1,"Incompatible A/B sizes for symmetry test"); 1413cd0d46ebSvictorle aii = aij->i; bii = bij->i; 1414cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 1415cd0d46ebSvictorle va = aij->a; vb = bij->a; 1416cd0d46ebSvictorle ierr = PetscMalloc(ma*sizeof(int),&aptr); CHKERRQ(ierr); 1417cd0d46ebSvictorle ierr = PetscMalloc(mb*sizeof(int),&bptr); CHKERRQ(ierr); 1418cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 1419cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 1420cd0d46ebSvictorle 1421cd0d46ebSvictorle *f = PETSC_TRUE; 1422cd0d46ebSvictorle for (i=0; i<ma; i++) { 1423cd0d46ebSvictorle /*printf("row %d spans %d--%d; we start @ %d\n", 1424cd0d46ebSvictorle i,idx[ii[i]],idx[ii[i+1]-1],idx[aptr[i]]);*/ 1425cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 1426cd0d46ebSvictorle int idc,idr; PetscScalar vc,vr; 1427cd0d46ebSvictorle /* column/row index/value */ 1428cd0d46ebSvictorle idc = adx[aptr[i]]; idr = bdx[bptr[idc]]; 1429cd0d46ebSvictorle vc = va[aptr[i]]; vr = vb[bptr[idc]]; 1430cd0d46ebSvictorle /*printf("comparing %d: (%d,%d)=%e to (%d,%d)=%e\n", 1431cd0d46ebSvictorle aptr[i],i,idc,vc,idc,idr,vr);*/ 1432cd0d46ebSvictorle if (i!=idr || vc!=vr) { 1433cd0d46ebSvictorle *f = PETSC_FALSE; goto done; 1434cd0d46ebSvictorle } else { 14353aeef889SHong Zhang aptr[i]++; if (B || i!=idc) bptr[idc]++; 1436cd0d46ebSvictorle } 1437cd0d46ebSvictorle } 1438cd0d46ebSvictorle } 1439cd0d46ebSvictorle done: 1440cd0d46ebSvictorle ierr = PetscFree(aptr); CHKERRQ(ierr); 14413aeef889SHong Zhang if (B) { 14423aeef889SHong Zhang ierr = PetscFree(bptr); CHKERRQ(ierr); 14433aeef889SHong Zhang } 1444cd0d46ebSvictorle 1445cd0d46ebSvictorle PetscFunctionReturn(0); 1446cd0d46ebSvictorle } 1447cd0d46ebSvictorle EXTERN_C_END 1448cd0d46ebSvictorle 14494a2ae208SSatish Balay #undef __FUNCT__ 14504a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ" 14518f6be9afSLois Curfman McInnes int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 145217ab2063SBarry Smith { 1453416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 145487828ca2SBarry Smith PetscScalar *l,*r,x,*v; 1455bfeeae90SHong Zhang int ierr,i,j,m = A->m,n = A->n,M,nz = a->nz,*jj; 145617ab2063SBarry Smith 14573a40ed3dSBarry Smith PetscFunctionBegin; 145817ab2063SBarry Smith if (ll) { 14593ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 14603ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 1461e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 1462273d9f13SBarry Smith if (m != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 1463ed480e8bSBarry Smith ierr = VecGetArrayFast(ll,&l);CHKERRQ(ierr); 1464416022c9SBarry Smith v = a->a; 146517ab2063SBarry Smith for (i=0; i<m; i++) { 146617ab2063SBarry Smith x = l[i]; 1467416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 146817ab2063SBarry Smith for (j=0; j<M; j++) { (*v++) *= x;} 146917ab2063SBarry Smith } 1470ed480e8bSBarry Smith ierr = VecRestoreArrayFast(ll,&l);CHKERRQ(ierr); 1471b0a32e0cSBarry Smith PetscLogFlops(nz); 147217ab2063SBarry Smith } 147317ab2063SBarry Smith if (rr) { 1474e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 1475273d9f13SBarry Smith if (n != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 1476ed480e8bSBarry Smith ierr = VecGetArrayFast(rr,&r);CHKERRQ(ierr); 1477416022c9SBarry Smith v = a->a; jj = a->j; 147817ab2063SBarry Smith for (i=0; i<nz; i++) { 1479bfeeae90SHong Zhang (*v++) *= r[*jj++]; 148017ab2063SBarry Smith } 1481ed480e8bSBarry Smith ierr = VecRestoreArrayFast(rr,&r);CHKERRQ(ierr); 1482b0a32e0cSBarry Smith PetscLogFlops(nz); 148317ab2063SBarry Smith } 14843a40ed3dSBarry Smith PetscFunctionReturn(0); 148517ab2063SBarry Smith } 148617ab2063SBarry Smith 14874a2ae208SSatish Balay #undef __FUNCT__ 14884a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ" 14897b2a1423SBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatReuse scall,Mat *B) 149017ab2063SBarry Smith { 1491db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 1492273d9f13SBarry Smith int *smap,i,k,kstart,kend,ierr,oldcols = A->n,*lens; 149336db0b34SBarry Smith int row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 1494bfeeae90SHong Zhang int *irow,*icol,nrows,ncols; 149599141d43SSatish Balay int *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 149687828ca2SBarry Smith PetscScalar *a_new,*mat_a; 1497416022c9SBarry Smith Mat C; 1498fee21e36SBarry Smith PetscTruth stride; 149917ab2063SBarry Smith 15003a40ed3dSBarry Smith PetscFunctionBegin; 1501d64ed03dSBarry Smith ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr); 150229bbc08cSBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted"); 1503d64ed03dSBarry Smith ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr); 150429bbc08cSBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted"); 150599141d43SSatish Balay 150617ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 1507b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 1508b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 150917ab2063SBarry Smith 1510fee21e36SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 1511fee21e36SBarry Smith ierr = ISStride(iscol,&stride);CHKERRQ(ierr); 1512fee21e36SBarry Smith if (stride && step == 1) { 151302834360SBarry Smith /* special case of contiguous rows */ 151431ebf83bSSatish Balay ierr = PetscMalloc((2*nrows+1)*sizeof(int),&lens);CHKERRQ(ierr); 151531ebf83bSSatish Balay starts = lens + nrows; 151602834360SBarry Smith /* loop over new rows determining lens and starting points */ 151702834360SBarry Smith for (i=0; i<nrows; i++) { 1518bfeeae90SHong Zhang kstart = ai[irow[i]]; 1519a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 152002834360SBarry Smith for (k=kstart; k<kend; k++) { 1521bfeeae90SHong Zhang if (aj[k] >= first) { 152202834360SBarry Smith starts[i] = k; 152302834360SBarry Smith break; 152402834360SBarry Smith } 152502834360SBarry Smith } 1526a2744918SBarry Smith sum = 0; 152702834360SBarry Smith while (k < kend) { 1528bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 1529a2744918SBarry Smith sum++; 153002834360SBarry Smith } 1531a2744918SBarry Smith lens[i] = sum; 153202834360SBarry Smith } 153302834360SBarry Smith /* create submatrix */ 1534cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 153508480c60SBarry Smith int n_cols,n_rows; 153608480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 153729bbc08cSBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 1538d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 153908480c60SBarry Smith C = *B; 15403a40ed3dSBarry Smith } else { 154102834360SBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 154208480c60SBarry Smith } 1543db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 1544db02288aSLois Curfman McInnes 154502834360SBarry Smith /* loop over rows inserting into submatrix */ 1546db02288aSLois Curfman McInnes a_new = c->a; 1547db02288aSLois Curfman McInnes j_new = c->j; 1548db02288aSLois Curfman McInnes i_new = c->i; 1549bfeeae90SHong Zhang 155002834360SBarry Smith for (i=0; i<nrows; i++) { 1551a2744918SBarry Smith ii = starts[i]; 1552a2744918SBarry Smith lensi = lens[i]; 1553a2744918SBarry Smith for (k=0; k<lensi; k++) { 1554a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 155502834360SBarry Smith } 155687828ca2SBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr); 1557a2744918SBarry Smith a_new += lensi; 1558a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 1559a2744918SBarry Smith c->ilen[i] = lensi; 156002834360SBarry Smith } 1561606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 15623a40ed3dSBarry Smith } else { 156302834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 1564b0a32e0cSBarry Smith ierr = PetscMalloc((1+oldcols)*sizeof(int),&smap);CHKERRQ(ierr); 1565bfeeae90SHong Zhang 1566b0a32e0cSBarry Smith ierr = PetscMalloc((1+nrows)*sizeof(int),&lens);CHKERRQ(ierr); 1567549d3d68SSatish Balay ierr = PetscMemzero(smap,oldcols*sizeof(int));CHKERRQ(ierr); 156817ab2063SBarry Smith for (i=0; i<ncols; i++) smap[icol[i]] = i+1; 156902834360SBarry Smith /* determine lens of each row */ 157002834360SBarry Smith for (i=0; i<nrows; i++) { 1571bfeeae90SHong Zhang kstart = ai[irow[i]]; 157202834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 157302834360SBarry Smith lens[i] = 0; 157402834360SBarry Smith for (k=kstart; k<kend; k++) { 1575bfeeae90SHong Zhang if (smap[aj[k]]) { 157602834360SBarry Smith lens[i]++; 157702834360SBarry Smith } 157802834360SBarry Smith } 157902834360SBarry Smith } 158017ab2063SBarry Smith /* Create and fill new matrix */ 1581a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 15820f5bd95cSBarry Smith PetscTruth equal; 15830f5bd95cSBarry Smith 158499141d43SSatish Balay c = (Mat_SeqAIJ *)((*B)->data); 1585273d9f13SBarry Smith if ((*B)->m != nrows || (*B)->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 1586273d9f13SBarry Smith ierr = PetscMemcmp(c->ilen,lens,(*B)->m*sizeof(int),&equal);CHKERRQ(ierr); 15870f5bd95cSBarry Smith if (!equal) { 158829bbc08cSBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 158999141d43SSatish Balay } 1590273d9f13SBarry Smith ierr = PetscMemzero(c->ilen,(*B)->m*sizeof(int));CHKERRQ(ierr); 159108480c60SBarry Smith C = *B; 15923a40ed3dSBarry Smith } else { 159302834360SBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 159408480c60SBarry Smith } 159599141d43SSatish Balay c = (Mat_SeqAIJ *)(C->data); 159617ab2063SBarry Smith for (i=0; i<nrows; i++) { 159799141d43SSatish Balay row = irow[i]; 1598bfeeae90SHong Zhang kstart = ai[row]; 159999141d43SSatish Balay kend = kstart + a->ilen[row]; 1600bfeeae90SHong Zhang mat_i = c->i[i]; 160199141d43SSatish Balay mat_j = c->j + mat_i; 160299141d43SSatish Balay mat_a = c->a + mat_i; 160399141d43SSatish Balay mat_ilen = c->ilen + i; 160417ab2063SBarry Smith for (k=kstart; k<kend; k++) { 1605bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 1606ed480e8bSBarry Smith *mat_j++ = tcol - 1; 160799141d43SSatish Balay *mat_a++ = a->a[k]; 160899141d43SSatish Balay (*mat_ilen)++; 160999141d43SSatish Balay 161017ab2063SBarry Smith } 161117ab2063SBarry Smith } 161217ab2063SBarry Smith } 161302834360SBarry Smith /* Free work space */ 161402834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 1615606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 1616606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 161702834360SBarry Smith } 16186d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16196d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 162017ab2063SBarry Smith 162117ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 1622416022c9SBarry Smith *B = C; 16233a40ed3dSBarry Smith PetscFunctionReturn(0); 162417ab2063SBarry Smith } 162517ab2063SBarry Smith 1626a871dcd8SBarry Smith /* 1627a871dcd8SBarry Smith */ 16284a2ae208SSatish Balay #undef __FUNCT__ 16294a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ" 1630b380c88cSHong Zhang int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatFactorInfo *info) 1631a871dcd8SBarry Smith { 163263b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 163308480c60SBarry Smith int ierr; 163463b91edcSBarry Smith Mat outA; 1635b8a78c4aSBarry Smith PetscTruth row_identity,col_identity; 163663b91edcSBarry Smith 16373a40ed3dSBarry Smith PetscFunctionBegin; 1638d3d32019SBarry Smith if (info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 1639b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 1640b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 1641b8a78c4aSBarry Smith if (!row_identity || !col_identity) { 164229bbc08cSBarry Smith SETERRQ(1,"Row and column permutations must be identity for in-place ILU"); 1643b8a78c4aSBarry Smith } 1644a871dcd8SBarry Smith 164563b91edcSBarry Smith outA = inA; 164663b91edcSBarry Smith inA->factor = FACTOR_LU; 164763b91edcSBarry Smith a->row = row; 164863b91edcSBarry Smith a->col = col; 1649c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1650c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 165163b91edcSBarry Smith 165236db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 1653b9b97703SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */ 16544c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 1655b0a32e0cSBarry Smith PetscLogObjectParent(inA,a->icol); 1656f0ec6fceSSatish Balay 165794a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 165887828ca2SBarry Smith ierr = PetscMalloc((inA->m+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr); 165994a9d846SBarry Smith } 166063b91edcSBarry Smith 166108480c60SBarry Smith if (!a->diag) { 1662f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 166363b91edcSBarry Smith } 166463b91edcSBarry Smith ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA);CHKERRQ(ierr); 16653a40ed3dSBarry Smith PetscFunctionReturn(0); 1666a871dcd8SBarry Smith } 1667a871dcd8SBarry Smith 1668d9eff348SSatish Balay #include "petscblaslapack.h" 16694a2ae208SSatish Balay #undef __FUNCT__ 16704a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ" 1671268466fbSBarry Smith int MatScale_SeqAIJ(const PetscScalar *alpha,Mat inA) 1672f0b747eeSBarry Smith { 1673f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 1674f0b747eeSBarry Smith int one = 1; 16753a40ed3dSBarry Smith 16763a40ed3dSBarry Smith PetscFunctionBegin; 1677268466fbSBarry Smith BLscal_(&a->nz,(PetscScalar*)alpha,a->a,&one); 1678b0a32e0cSBarry Smith PetscLogFlops(a->nz); 16793a40ed3dSBarry Smith PetscFunctionReturn(0); 1680f0b747eeSBarry Smith } 1681f0b747eeSBarry Smith 16824a2ae208SSatish Balay #undef __FUNCT__ 16834a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ" 1684268466fbSBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 1685cddf8d76SBarry Smith { 1686cddf8d76SBarry Smith int ierr,i; 1687cddf8d76SBarry Smith 16883a40ed3dSBarry Smith PetscFunctionBegin; 1689cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 1690b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr); 1691cddf8d76SBarry Smith } 1692cddf8d76SBarry Smith 1693cddf8d76SBarry Smith for (i=0; i<n; i++) { 16946a6a5d1dSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 1695cddf8d76SBarry Smith } 16963a40ed3dSBarry Smith PetscFunctionReturn(0); 1697cddf8d76SBarry Smith } 1698cddf8d76SBarry Smith 16994a2ae208SSatish Balay #undef __FUNCT__ 17004a2ae208SSatish Balay #define __FUNCT__ "MatGetBlockSize_SeqAIJ" 17018f6be9afSLois Curfman McInnes int MatGetBlockSize_SeqAIJ(Mat A,int *bs) 17025a838052SSatish Balay { 1703f830108cSBarry Smith PetscFunctionBegin; 17045a838052SSatish Balay *bs = 1; 17053a40ed3dSBarry Smith PetscFunctionReturn(0); 17065a838052SSatish Balay } 17075a838052SSatish Balay 17084a2ae208SSatish Balay #undef __FUNCT__ 17094a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ" 1710268466fbSBarry Smith int MatIncreaseOverlap_SeqAIJ(Mat A,int is_max,IS is[],int ov) 17114dcbc457SBarry Smith { 1712e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1713efb16452SHong Zhang int row,i,j,k,l,m,n,*idx,ierr,*nidx,isz,val; 17148a047759SSatish Balay int start,end,*ai,*aj; 1715f1af5d2fSBarry Smith PetscBT table; 1716bbd702dbSSatish Balay 17173a40ed3dSBarry Smith PetscFunctionBegin; 1718273d9f13SBarry Smith m = A->m; 1719e4d965acSSatish Balay ai = a->i; 1720bfeeae90SHong Zhang aj = a->j; 17218a047759SSatish Balay 1722a45adfd6SMatthew Knepley if (ov < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 172306763907SSatish Balay 1724b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&nidx);CHKERRQ(ierr); 17256831982aSBarry Smith ierr = PetscBTCreate(m,table);CHKERRQ(ierr); 172606763907SSatish Balay 1727e4d965acSSatish Balay for (i=0; i<is_max; i++) { 1728b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 1729e4d965acSSatish Balay isz = 0; 17306831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 1731e4d965acSSatish Balay 1732e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 17334dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 1734b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 1735e4d965acSSatish Balay 1736dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 1737e4d965acSSatish Balay for (j=0; j<n ; ++j){ 1738f1af5d2fSBarry Smith if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];} 17394dcbc457SBarry Smith } 174006763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 174106763907SSatish Balay ierr = ISDestroy(is[i]);CHKERRQ(ierr); 1742e4d965acSSatish Balay 174304a348a9SBarry Smith k = 0; 174404a348a9SBarry Smith for (j=0; j<ov; j++){ /* for each overlap */ 174504a348a9SBarry Smith n = isz; 174606763907SSatish Balay for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */ 1747e4d965acSSatish Balay row = nidx[k]; 1748e4d965acSSatish Balay start = ai[row]; 1749e4d965acSSatish Balay end = ai[row+1]; 175004a348a9SBarry Smith for (l = start; l<end ; l++){ 1751efb16452SHong Zhang val = aj[l] ; 1752f1af5d2fSBarry Smith if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;} 1753e4d965acSSatish Balay } 1754e4d965acSSatish Balay } 1755e4d965acSSatish Balay } 1756029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr); 1757e4d965acSSatish Balay } 17586831982aSBarry Smith ierr = PetscBTDestroy(table);CHKERRQ(ierr); 1759606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 17603a40ed3dSBarry Smith PetscFunctionReturn(0); 17614dcbc457SBarry Smith } 176217ab2063SBarry Smith 17630513a670SBarry Smith /* -------------------------------------------------------------- */ 17644a2ae208SSatish Balay #undef __FUNCT__ 17654a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ" 17660513a670SBarry Smith int MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 17670513a670SBarry Smith { 17680513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 176987828ca2SBarry Smith PetscScalar *vwork; 1770273d9f13SBarry Smith int i,ierr,nz,m = A->m,n = A->n,*cwork; 17710513a670SBarry Smith int *row,*col,*cnew,j,*lens; 177256cd22aeSBarry Smith IS icolp,irowp; 17730513a670SBarry Smith 17743a40ed3dSBarry Smith PetscFunctionBegin; 17754c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 177656cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 17774c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 177856cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 17790513a670SBarry Smith 17800513a670SBarry Smith /* determine lengths of permuted rows */ 1781b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&lens);CHKERRQ(ierr); 17820513a670SBarry Smith for (i=0; i<m; i++) { 17830513a670SBarry Smith lens[row[i]] = a->i[i+1] - a->i[i]; 17840513a670SBarry Smith } 17850513a670SBarry Smith ierr = MatCreateSeqAIJ(A->comm,m,n,0,lens,B);CHKERRQ(ierr); 1786606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 17870513a670SBarry Smith 1788b0a32e0cSBarry Smith ierr = PetscMalloc(n*sizeof(int),&cnew);CHKERRQ(ierr); 17890513a670SBarry Smith for (i=0; i<m; i++) { 17900513a670SBarry Smith ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 17910513a670SBarry Smith for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];} 17920513a670SBarry Smith ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 17930513a670SBarry Smith ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 17940513a670SBarry Smith } 1795606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 17960513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17970513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 179856cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 179956cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 180056cd22aeSBarry Smith ierr = ISDestroy(irowp);CHKERRQ(ierr); 180156cd22aeSBarry Smith ierr = ISDestroy(icolp);CHKERRQ(ierr); 18023a40ed3dSBarry Smith PetscFunctionReturn(0); 18030513a670SBarry Smith } 18040513a670SBarry Smith 18054a2ae208SSatish Balay #undef __FUNCT__ 18064a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqAIJ" 1807682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A) 1808682d7d0cSBarry Smith { 1809c38d4ed2SBarry Smith static PetscTruth called = PETSC_FALSE; 1810682d7d0cSBarry Smith MPI_Comm comm = A->comm; 1811d132466eSBarry Smith int ierr; 1812682d7d0cSBarry Smith 18133a40ed3dSBarry Smith PetscFunctionBegin; 1814c38d4ed2SBarry Smith if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE; 1815d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr); 1816d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr); 1817d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr); 1818d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_no_inode: Do not use inodes\n");CHKERRQ(ierr); 1819d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");CHKERRQ(ierr); 182016ce804cSBarry Smith #if defined(PETSC_HAVE_MATLAB) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) 1821ca44d042SBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_matlab: Use Matlab engine sparse LU factorization and solve.\n");CHKERRQ(ierr); 1822ca44d042SBarry Smith #endif 18233a40ed3dSBarry Smith PetscFunctionReturn(0); 1824682d7d0cSBarry Smith } 182597304618SKris Buschelman 18264a2ae208SSatish Balay #undef __FUNCT__ 18274a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ" 1828cb5b572fSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 1829cb5b572fSBarry Smith { 1830be6bf707SBarry Smith int ierr; 1831cb5b572fSBarry Smith 1832cb5b572fSBarry Smith PetscFunctionBegin; 183333f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 183433f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 1835be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1836be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 1837be6bf707SBarry Smith 1838bfeeae90SHong Zhang if (a->i[A->m] != b->i[B->m]) { 183929bbc08cSBarry Smith SETERRQ(1,"Number of nonzeros in two matrices are different"); 1840cb5b572fSBarry Smith } 1841bfeeae90SHong Zhang ierr = PetscMemcpy(b->a,a->a,(a->i[A->m])*sizeof(PetscScalar));CHKERRQ(ierr); 1842cb5b572fSBarry Smith } else { 1843cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1844cb5b572fSBarry Smith } 1845cb5b572fSBarry Smith PetscFunctionReturn(0); 1846cb5b572fSBarry Smith } 1847cb5b572fSBarry Smith 18484a2ae208SSatish Balay #undef __FUNCT__ 18494a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ" 1850273d9f13SBarry Smith int MatSetUpPreallocation_SeqAIJ(Mat A) 1851273d9f13SBarry Smith { 1852273d9f13SBarry Smith int ierr; 1853273d9f13SBarry Smith 1854273d9f13SBarry Smith PetscFunctionBegin; 1855273d9f13SBarry Smith ierr = MatSeqAIJSetPreallocation(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 1856273d9f13SBarry Smith PetscFunctionReturn(0); 1857273d9f13SBarry Smith } 1858273d9f13SBarry Smith 18594a2ae208SSatish Balay #undef __FUNCT__ 18604a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ" 18614e7234bfSBarry Smith int MatGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 18626c0721eeSBarry Smith { 18636c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18646c0721eeSBarry Smith PetscFunctionBegin; 18656c0721eeSBarry Smith *array = a->a; 18666c0721eeSBarry Smith PetscFunctionReturn(0); 18676c0721eeSBarry Smith } 18686c0721eeSBarry Smith 18694a2ae208SSatish Balay #undef __FUNCT__ 18704a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ" 18714e7234bfSBarry Smith int MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 18726c0721eeSBarry Smith { 18736c0721eeSBarry Smith PetscFunctionBegin; 18746c0721eeSBarry Smith PetscFunctionReturn(0); 18756c0721eeSBarry Smith } 1876273d9f13SBarry Smith 1877ee4f033dSBarry Smith #undef __FUNCT__ 1878ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ" 1879ee4f033dSBarry Smith int MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 1880ee4f033dSBarry Smith { 1881ee4f033dSBarry Smith int (*f)(void *,Vec,Vec,void*) = (int (*)(void *,Vec,Vec,void *))coloring->f; 1882ee4f033dSBarry Smith int k,ierr,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2; 188387828ca2SBarry Smith PetscScalar dx,mone = -1.0,*y,*xx,*w3_array; 188487828ca2SBarry Smith PetscScalar *vscale_array; 1885ee4f033dSBarry Smith PetscReal epsilon = coloring->error_rel,umin = coloring->umin; 1886ee4f033dSBarry Smith Vec w1,w2,w3; 1887ee4f033dSBarry Smith void *fctx = coloring->fctx; 1888ee4f033dSBarry Smith PetscTruth flg; 1889ee4f033dSBarry Smith 1890ee4f033dSBarry Smith PetscFunctionBegin; 1891ee4f033dSBarry Smith if (!coloring->w1) { 1892ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr); 1893ee4f033dSBarry Smith PetscLogObjectParent(coloring,coloring->w1); 1894ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr); 1895ee4f033dSBarry Smith PetscLogObjectParent(coloring,coloring->w2); 1896ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr); 1897ee4f033dSBarry Smith PetscLogObjectParent(coloring,coloring->w3); 1898ee4f033dSBarry Smith } 1899ee4f033dSBarry Smith w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3; 1900ee4f033dSBarry Smith 1901ee4f033dSBarry Smith ierr = MatSetUnfactored(J);CHKERRQ(ierr); 1902e82a3eeeSBarry Smith ierr = PetscOptionsHasName(coloring->prefix,"-mat_fd_coloring_dont_rezero",&flg);CHKERRQ(ierr); 1903ee4f033dSBarry Smith if (flg) { 1904ee4f033dSBarry Smith PetscLogInfo(coloring,"MatFDColoringApply_SeqAIJ: Not calling MatZeroEntries()\n"); 1905ee4f033dSBarry Smith } else { 1906ee4f033dSBarry Smith ierr = MatZeroEntries(J);CHKERRQ(ierr); 1907ee4f033dSBarry Smith } 1908ee4f033dSBarry Smith 1909ee4f033dSBarry Smith ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr); 1910ee4f033dSBarry Smith ierr = VecGetSize(x1,&N);CHKERRQ(ierr); 1911ee4f033dSBarry Smith 1912ee4f033dSBarry Smith /* 1913ee4f033dSBarry Smith This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets 1914ee4f033dSBarry Smith coloring->F for the coarser grids from the finest 1915ee4f033dSBarry Smith */ 1916ee4f033dSBarry Smith if (coloring->F) { 1917ee4f033dSBarry Smith ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr); 1918ee4f033dSBarry Smith ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr); 1919ee4f033dSBarry Smith if (m1 != m2) { 1920ee4f033dSBarry Smith coloring->F = 0; 1921ee4f033dSBarry Smith } 1922ee4f033dSBarry Smith } 1923ee4f033dSBarry Smith 1924ee4f033dSBarry Smith if (coloring->F) { 1925ee4f033dSBarry Smith w1 = coloring->F; 1926ee4f033dSBarry Smith coloring->F = 0; 1927ee4f033dSBarry Smith } else { 192866f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 1929ee4f033dSBarry Smith ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr); 193066f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 1931ee4f033dSBarry Smith } 1932ee4f033dSBarry Smith 1933ee4f033dSBarry Smith /* 1934ee4f033dSBarry Smith Compute all the scale factors and share with other processors 1935ee4f033dSBarry Smith */ 1936ed480e8bSBarry Smith ierr = VecGetArrayFast(x1,&xx);CHKERRQ(ierr);xx = xx - start; 1937ed480e8bSBarry Smith ierr = VecGetArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start; 1938ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 1939ee4f033dSBarry Smith /* 1940ee4f033dSBarry Smith Loop over each column associated with color adding the 1941ee4f033dSBarry Smith perturbation to the vector w3. 1942ee4f033dSBarry Smith */ 1943ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 1944ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 1945ee4f033dSBarry Smith dx = xx[col]; 1946ee4f033dSBarry Smith if (dx == 0.0) dx = 1.0; 1947ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 1948ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 1949ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 1950ee4f033dSBarry Smith #else 1951ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 1952ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 1953ee4f033dSBarry Smith #endif 1954ee4f033dSBarry Smith dx *= epsilon; 1955ee4f033dSBarry Smith vscale_array[col] = 1.0/dx; 1956ee4f033dSBarry Smith } 1957ee4f033dSBarry Smith } 1958ed480e8bSBarry Smith vscale_array = vscale_array + start;ierr = VecRestoreArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr); 1959ee4f033dSBarry Smith ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1960ee4f033dSBarry Smith ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1961ee4f033dSBarry Smith 1962ee4f033dSBarry Smith /* ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD); 1963ee4f033dSBarry Smith ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/ 1964ee4f033dSBarry Smith 1965ee4f033dSBarry Smith if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow; 1966ee4f033dSBarry Smith else vscaleforrow = coloring->columnsforrow; 1967ee4f033dSBarry Smith 1968ed480e8bSBarry Smith ierr = VecGetArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr); 1969ee4f033dSBarry Smith /* 1970ee4f033dSBarry Smith Loop over each color 1971ee4f033dSBarry Smith */ 1972ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 197349b058dcSBarry Smith coloring->currentcolor = k; 1974ee4f033dSBarry Smith ierr = VecCopy(x1,w3);CHKERRQ(ierr); 1975ed480e8bSBarry Smith ierr = VecGetArrayFast(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start; 1976ee4f033dSBarry Smith /* 1977ee4f033dSBarry Smith Loop over each column associated with color adding the 1978ee4f033dSBarry Smith perturbation to the vector w3. 1979ee4f033dSBarry Smith */ 1980ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 1981ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 1982ee4f033dSBarry Smith dx = xx[col]; 1983ee4f033dSBarry Smith if (dx == 0.0) dx = 1.0; 1984ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 1985ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 1986ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 1987ee4f033dSBarry Smith #else 1988ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 1989ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 1990ee4f033dSBarry Smith #endif 1991ee4f033dSBarry Smith dx *= epsilon; 1992ee4f033dSBarry Smith if (!PetscAbsScalar(dx)) SETERRQ(1,"Computed 0 differencing parameter"); 1993ee4f033dSBarry Smith w3_array[col] += dx; 1994ee4f033dSBarry Smith } 1995ed480e8bSBarry Smith w3_array = w3_array + start; ierr = VecRestoreArrayFast(w3,&w3_array);CHKERRQ(ierr); 1996ee4f033dSBarry Smith 1997ee4f033dSBarry Smith /* 1998ee4f033dSBarry Smith Evaluate function at x1 + dx (here dx is a vector of perturbations) 1999ee4f033dSBarry Smith */ 2000ee4f033dSBarry Smith 200166f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2002ee4f033dSBarry Smith ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr); 200366f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2004ee4f033dSBarry Smith ierr = VecAXPY(&mone,w1,w2);CHKERRQ(ierr); 2005ee4f033dSBarry Smith 2006ee4f033dSBarry Smith /* 2007ee4f033dSBarry Smith Loop over rows of vector, putting results into Jacobian matrix 2008ee4f033dSBarry Smith */ 2009ed480e8bSBarry Smith ierr = VecGetArrayFast(w2,&y);CHKERRQ(ierr); 2010ee4f033dSBarry Smith for (l=0; l<coloring->nrows[k]; l++) { 2011ee4f033dSBarry Smith row = coloring->rows[k][l]; 2012ee4f033dSBarry Smith col = coloring->columnsforrow[k][l]; 2013ee4f033dSBarry Smith y[row] *= vscale_array[vscaleforrow[k][l]]; 2014ee4f033dSBarry Smith srow = row + start; 2015ee4f033dSBarry Smith ierr = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr); 2016ee4f033dSBarry Smith } 2017ed480e8bSBarry Smith ierr = VecRestoreArrayFast(w2,&y);CHKERRQ(ierr); 2018ee4f033dSBarry Smith } 201949b058dcSBarry Smith coloring->currentcolor = k; 2020ed480e8bSBarry Smith ierr = VecRestoreArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2021ed480e8bSBarry Smith xx = xx + start; ierr = VecRestoreArrayFast(x1,&xx);CHKERRQ(ierr); 2022ee4f033dSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2023ee4f033dSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2024ee4f033dSBarry Smith PetscFunctionReturn(0); 2025ee4f033dSBarry Smith } 2026ee4f033dSBarry Smith 2027ac90fabeSBarry Smith #include "petscblaslapack.h" 2028ac90fabeSBarry Smith #undef __FUNCT__ 2029ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ" 20307cff1425SSatish Balay int MatAXPY_SeqAIJ(const PetscScalar a[],Mat X,Mat Y,MatStructure str) 2031ac90fabeSBarry Smith { 2032c537a176SHong Zhang int ierr,one=1,i; 2033ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data; 2034ac90fabeSBarry Smith 2035ac90fabeSBarry Smith PetscFunctionBegin; 2036ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 2037268466fbSBarry Smith BLaxpy_(&x->nz,(PetscScalar*)a,x->a,&one,y->a,&one); 2038c537a176SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 2039a30b2313SHong Zhang if (y->xtoy && y->XtoY != X) { 2040a30b2313SHong Zhang ierr = PetscFree(y->xtoy);CHKERRQ(ierr); 2041a30b2313SHong Zhang ierr = MatDestroy(y->XtoY);CHKERRQ(ierr); 2042a30b2313SHong Zhang } 2043a30b2313SHong Zhang if (!y->xtoy) { /* get xtoy */ 204424f910e3SHong Zhang ierr = MatAXPYGetxtoy_Private(X->m,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr); 2045a30b2313SHong Zhang y->XtoY = X; 2046c537a176SHong Zhang } 2047a30b2313SHong Zhang for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += (*a)*(x->a[i]); 2048e2dd4fc4Svictorle PetscLogInfo(0,"MatAXPY_SeqAIJ: ratio of nnz(X)/nnz(Y): %d/%d = %g\n",x->nz,y->nz,(PetscReal)(x->nz)/y->nz); 2049ac90fabeSBarry Smith } else { 2050ac90fabeSBarry Smith ierr = MatAXPY_Basic(a,X,Y,str);CHKERRQ(ierr); 2051ac90fabeSBarry Smith } 2052ac90fabeSBarry Smith PetscFunctionReturn(0); 2053ac90fabeSBarry Smith } 2054ac90fabeSBarry Smith 2055682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 20560a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ, 2057cb5b572fSBarry Smith MatGetRow_SeqAIJ, 2058cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 2059cb5b572fSBarry Smith MatMult_SeqAIJ, 206097304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 20617c922b88SBarry Smith MatMultTranspose_SeqAIJ, 20627c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 2063cb5b572fSBarry Smith MatSolve_SeqAIJ, 2064cb5b572fSBarry Smith MatSolveAdd_SeqAIJ, 20657c922b88SBarry Smith MatSolveTranspose_SeqAIJ, 206697304618SKris Buschelman /*10*/ MatSolveTransposeAdd_SeqAIJ, 2067cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 2068cb5b572fSBarry Smith 0, 206917ab2063SBarry Smith MatRelax_SeqAIJ, 207017ab2063SBarry Smith MatTranspose_SeqAIJ, 207197304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ, 2072cb5b572fSBarry Smith MatEqual_SeqAIJ, 2073cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 2074cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 2075cb5b572fSBarry Smith MatNorm_SeqAIJ, 207697304618SKris Buschelman /*20*/ 0, 2077cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 207817ab2063SBarry Smith MatCompress_SeqAIJ, 2079cb5b572fSBarry Smith MatSetOption_SeqAIJ, 2080cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 208197304618SKris Buschelman /*25*/ MatZeroRows_SeqAIJ, 2082cb5b572fSBarry Smith MatLUFactorSymbolic_SeqAIJ, 2083cb5b572fSBarry Smith MatLUFactorNumeric_SeqAIJ, 2084f76d2b81SHong Zhang MatCholeskyFactorSymbolic_SeqAIJ, 2085a6175056SHong Zhang MatCholeskyFactorNumeric_SeqAIJ, 208697304618SKris Buschelman /*30*/ MatSetUpPreallocation_SeqAIJ, 2087cb5b572fSBarry Smith MatILUFactorSymbolic_SeqAIJ, 2088861ba921SHong Zhang MatICCFactorSymbolic_SeqAIJ, 20896c0721eeSBarry Smith MatGetArray_SeqAIJ, 20906c0721eeSBarry Smith MatRestoreArray_SeqAIJ, 209197304618SKris Buschelman /*35*/ MatDuplicate_SeqAIJ, 2092cb5b572fSBarry Smith 0, 2093cb5b572fSBarry Smith 0, 2094cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 2095cb5b572fSBarry Smith 0, 209697304618SKris Buschelman /*40*/ MatAXPY_SeqAIJ, 2097cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 2098cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 2099cb5b572fSBarry Smith MatGetValues_SeqAIJ, 2100cb5b572fSBarry Smith MatCopy_SeqAIJ, 210197304618SKris Buschelman /*45*/ MatPrintHelp_SeqAIJ, 2102cb5b572fSBarry Smith MatScale_SeqAIJ, 2103cb5b572fSBarry Smith 0, 2104cb5b572fSBarry Smith 0, 21056945ee14SBarry Smith MatILUDTFactor_SeqAIJ, 210697304618SKris Buschelman /*50*/ MatGetBlockSize_SeqAIJ, 21073b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 21083b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 21093b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 2110a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 211197304618SKris Buschelman /*55*/ MatFDColoringCreate_SeqAIJ, 2112b9617806SBarry Smith 0, 21130513a670SBarry Smith 0, 2114cda55fadSBarry Smith MatPermute_SeqAIJ, 2115cda55fadSBarry Smith 0, 211697304618SKris Buschelman /*60*/ 0, 2117b9b97703SBarry Smith MatDestroy_SeqAIJ, 2118b9b97703SBarry Smith MatView_SeqAIJ, 21198a124369SBarry Smith MatGetPetscMaps_Petsc, 2120ee4f033dSBarry Smith 0, 212197304618SKris Buschelman /*65*/ 0, 2122ee4f033dSBarry Smith 0, 2123ee4f033dSBarry Smith 0, 2124ee4f033dSBarry Smith 0, 2125ee4f033dSBarry Smith 0, 212697304618SKris Buschelman /*70*/ 0, 2127ee4f033dSBarry Smith 0, 2128ee4f033dSBarry Smith MatSetColoring_SeqAIJ, 2129ee4f033dSBarry Smith MatSetValuesAdic_SeqAIJ, 2130ee4f033dSBarry Smith MatSetValuesAdifor_SeqAIJ, 213197304618SKris Buschelman /*75*/ MatFDColoringApply_SeqAIJ, 213297304618SKris Buschelman 0, 213397304618SKris Buschelman 0, 213497304618SKris Buschelman 0, 213597304618SKris Buschelman 0, 213697304618SKris Buschelman /*80*/ 0, 213797304618SKris Buschelman 0, 213897304618SKris Buschelman 0, 213997304618SKris Buschelman 0, 214097304618SKris Buschelman 0, 214197304618SKris Buschelman /*85*/ MatLoad_SeqAIJ}; 214217ab2063SBarry Smith 2143fb2e594dSBarry Smith EXTERN_C_BEGIN 21444a2ae208SSatish Balay #undef __FUNCT__ 21454a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ" 214615091d37SBarry Smith 2147bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices) 2148bef8e0ddSBarry Smith { 2149bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2150bef8e0ddSBarry Smith int i,nz,n; 2151bef8e0ddSBarry Smith 2152bef8e0ddSBarry Smith PetscFunctionBegin; 2153bef8e0ddSBarry Smith 2154bef8e0ddSBarry Smith nz = aij->maxnz; 2155273d9f13SBarry Smith n = mat->n; 2156bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 2157bef8e0ddSBarry Smith aij->j[i] = indices[i]; 2158bef8e0ddSBarry Smith } 2159bef8e0ddSBarry Smith aij->nz = nz; 2160bef8e0ddSBarry Smith for (i=0; i<n; i++) { 2161bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 2162bef8e0ddSBarry Smith } 2163bef8e0ddSBarry Smith 2164bef8e0ddSBarry Smith PetscFunctionReturn(0); 2165bef8e0ddSBarry Smith } 2166fb2e594dSBarry Smith EXTERN_C_END 2167bef8e0ddSBarry Smith 21684a2ae208SSatish Balay #undef __FUNCT__ 21694a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices" 2170bef8e0ddSBarry Smith /*@ 2171bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 2172bef8e0ddSBarry Smith in the matrix. 2173bef8e0ddSBarry Smith 2174bef8e0ddSBarry Smith Input Parameters: 2175bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 2176bef8e0ddSBarry Smith - indices - the column indices 2177bef8e0ddSBarry Smith 217815091d37SBarry Smith Level: advanced 217915091d37SBarry Smith 2180bef8e0ddSBarry Smith Notes: 2181bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 2182bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 2183bef8e0ddSBarry Smith of the MatSetValues() operation. 2184bef8e0ddSBarry Smith 2185bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 2186bef8e0ddSBarry Smith MatCreateSeqAIJ(). 2187bef8e0ddSBarry Smith 2188bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 2189bef8e0ddSBarry Smith 2190b9617806SBarry Smith The indices should start with zero, not one. 2191b9617806SBarry Smith 2192bef8e0ddSBarry Smith @*/ 2193bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices) 2194bef8e0ddSBarry Smith { 2195bef8e0ddSBarry Smith int ierr,(*f)(Mat,int *); 2196bef8e0ddSBarry Smith 2197bef8e0ddSBarry Smith PetscFunctionBegin; 2198bef8e0ddSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 2199c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr); 2200bef8e0ddSBarry Smith if (f) { 2201bef8e0ddSBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 2202bef8e0ddSBarry Smith } else { 220329bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to set column indices"); 2204bef8e0ddSBarry Smith } 2205bef8e0ddSBarry Smith PetscFunctionReturn(0); 2206bef8e0ddSBarry Smith } 2207bef8e0ddSBarry Smith 2208be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 2209be6bf707SBarry Smith 2210fb2e594dSBarry Smith EXTERN_C_BEGIN 22114a2ae208SSatish Balay #undef __FUNCT__ 22124a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ" 2213be6bf707SBarry Smith int MatStoreValues_SeqAIJ(Mat mat) 2214be6bf707SBarry Smith { 2215be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2216bfeeae90SHong Zhang size_t nz = aij->i[mat->m],ierr; 2217be6bf707SBarry Smith 2218be6bf707SBarry Smith PetscFunctionBegin; 2219be6bf707SBarry Smith if (aij->nonew != 1) { 222029bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2221be6bf707SBarry Smith } 2222be6bf707SBarry Smith 2223be6bf707SBarry Smith /* allocate space for values if not already there */ 2224be6bf707SBarry Smith if (!aij->saved_values) { 222587828ca2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr); 2226be6bf707SBarry Smith } 2227be6bf707SBarry Smith 2228be6bf707SBarry Smith /* copy values over */ 222987828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 2230be6bf707SBarry Smith PetscFunctionReturn(0); 2231be6bf707SBarry Smith } 2232fb2e594dSBarry Smith EXTERN_C_END 2233be6bf707SBarry Smith 22344a2ae208SSatish Balay #undef __FUNCT__ 2235b9617806SBarry Smith #define __FUNCT__ "MatStoreValues" 2236be6bf707SBarry Smith /*@ 2237be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 2238be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2239be6bf707SBarry Smith nonlinear portion. 2240be6bf707SBarry Smith 2241be6bf707SBarry Smith Collect on Mat 2242be6bf707SBarry Smith 2243be6bf707SBarry Smith Input Parameters: 2244be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2245be6bf707SBarry Smith 224615091d37SBarry Smith Level: advanced 224715091d37SBarry Smith 2248be6bf707SBarry Smith Common Usage, with SNESSolve(): 2249be6bf707SBarry Smith $ Create Jacobian matrix 2250be6bf707SBarry Smith $ Set linear terms into matrix 2251be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 2252be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 2253be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 2254be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2255be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2256be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 2257be6bf707SBarry Smith $ In your Jacobian routine 2258be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2259be6bf707SBarry Smith $ Set nonlinear terms in matrix 2260be6bf707SBarry Smith 2261be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 2262be6bf707SBarry Smith $ // build linear portion of Jacobian 2263be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2264be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2265be6bf707SBarry Smith $ loop over nonlinear iterations 2266be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2267be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 2268be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 2269be6bf707SBarry Smith $ Solve linear system with Jacobian 2270be6bf707SBarry Smith $ endloop 2271be6bf707SBarry Smith 2272be6bf707SBarry Smith Notes: 2273be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 2274be6bf707SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before 2275be6bf707SBarry Smith calling this routine. 2276be6bf707SBarry Smith 2277be6bf707SBarry Smith .seealso: MatRetrieveValues() 2278be6bf707SBarry Smith 2279be6bf707SBarry Smith @*/ 2280be6bf707SBarry Smith int MatStoreValues(Mat mat) 2281be6bf707SBarry Smith { 2282be6bf707SBarry Smith int ierr,(*f)(Mat); 2283be6bf707SBarry Smith 2284be6bf707SBarry Smith PetscFunctionBegin; 2285be6bf707SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 228629bbc08cSBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 228729bbc08cSBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2288be6bf707SBarry Smith 2289c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void (**)(void))&f);CHKERRQ(ierr); 2290be6bf707SBarry Smith if (f) { 2291be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2292be6bf707SBarry Smith } else { 229329bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to store values"); 2294be6bf707SBarry Smith } 2295be6bf707SBarry Smith PetscFunctionReturn(0); 2296be6bf707SBarry Smith } 2297be6bf707SBarry Smith 2298fb2e594dSBarry Smith EXTERN_C_BEGIN 22994a2ae208SSatish Balay #undef __FUNCT__ 23004a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ" 2301be6bf707SBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat) 2302be6bf707SBarry Smith { 2303be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2304bfeeae90SHong Zhang int nz = aij->i[mat->m],ierr; 2305be6bf707SBarry Smith 2306be6bf707SBarry Smith PetscFunctionBegin; 2307be6bf707SBarry Smith if (aij->nonew != 1) { 230829bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2309be6bf707SBarry Smith } 2310be6bf707SBarry Smith if (!aij->saved_values) { 231129bbc08cSBarry Smith SETERRQ(1,"Must call MatStoreValues(A);first"); 2312be6bf707SBarry Smith } 2313be6bf707SBarry Smith 2314be6bf707SBarry Smith /* copy values over */ 231587828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 2316be6bf707SBarry Smith PetscFunctionReturn(0); 2317be6bf707SBarry Smith } 2318fb2e594dSBarry Smith EXTERN_C_END 2319be6bf707SBarry Smith 23204a2ae208SSatish Balay #undef __FUNCT__ 23214a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues" 2322be6bf707SBarry Smith /*@ 2323be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 2324be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2325be6bf707SBarry Smith nonlinear portion. 2326be6bf707SBarry Smith 2327be6bf707SBarry Smith Collect on Mat 2328be6bf707SBarry Smith 2329be6bf707SBarry Smith Input Parameters: 2330be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2331be6bf707SBarry Smith 233215091d37SBarry Smith Level: advanced 233315091d37SBarry Smith 2334be6bf707SBarry Smith .seealso: MatStoreValues() 2335be6bf707SBarry Smith 2336be6bf707SBarry Smith @*/ 2337be6bf707SBarry Smith int MatRetrieveValues(Mat mat) 2338be6bf707SBarry Smith { 2339be6bf707SBarry Smith int ierr,(*f)(Mat); 2340be6bf707SBarry Smith 2341be6bf707SBarry Smith PetscFunctionBegin; 2342be6bf707SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 234329bbc08cSBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 234429bbc08cSBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2345be6bf707SBarry Smith 2346c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void (**)(void))&f);CHKERRQ(ierr); 2347be6bf707SBarry Smith if (f) { 2348be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2349be6bf707SBarry Smith } else { 235029bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to retrieve values"); 2351be6bf707SBarry Smith } 2352be6bf707SBarry Smith PetscFunctionReturn(0); 2353be6bf707SBarry Smith } 2354be6bf707SBarry Smith 2355f83d6046SBarry Smith /* 2356f83d6046SBarry Smith This allows SeqAIJ matrices to be passed to the matlab engine 2357f83d6046SBarry Smith */ 235816ce804cSBarry Smith #if defined(PETSC_HAVE_MATLAB) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) 2359f83d6046SBarry Smith #include "engine.h" /* Matlab include file */ 2360f83d6046SBarry Smith #include "mex.h" /* Matlab include file */ 2361f83d6046SBarry Smith EXTERN_C_BEGIN 23624a2ae208SSatish Balay #undef __FUNCT__ 23634a2ae208SSatish Balay #define __FUNCT__ "MatMatlabEnginePut_SeqAIJ" 236462aa7f4eSBarry Smith int MatMatlabEnginePut_SeqAIJ(PetscObject obj,void *mengine) 2365f83d6046SBarry Smith { 236625922d2bSSatish Balay int ierr; 2367f83d6046SBarry Smith Mat B = (Mat)obj; 2368f83d6046SBarry Smith mxArray *mat; 2369d79a51d8SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)B->data; 2370d79a51d8SBarry Smith 2371f83d6046SBarry Smith PetscFunctionBegin; 237201820c62SBarry Smith mat = mxCreateSparse(B->n,B->m,aij->nz,mxREAL); 237387828ca2SBarry Smith ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 2374d79a51d8SBarry Smith /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 237566826eb6SBarry Smith ierr = PetscMemcpy(mxGetIr(mat),aij->j,aij->nz*sizeof(int));CHKERRQ(ierr); 237666826eb6SBarry Smith ierr = PetscMemcpy(mxGetJc(mat),aij->i,(B->m+1)*sizeof(int));CHKERRQ(ierr); 2377f83d6046SBarry Smith 237801820c62SBarry Smith /* Matlab indices start at 0 for sparse (what a surprise) */ 2379bfeeae90SHong Zhang 2380ca44d042SBarry Smith ierr = PetscObjectName(obj);CHKERRQ(ierr); 238116ce804cSBarry Smith engPutVariable((Engine *)mengine,obj->name,mat); 2382f83d6046SBarry Smith PetscFunctionReturn(0); 2383f83d6046SBarry Smith } 2384f83d6046SBarry Smith EXTERN_C_END 238566826eb6SBarry Smith 238666826eb6SBarry Smith EXTERN_C_BEGIN 23874a2ae208SSatish Balay #undef __FUNCT__ 23884a2ae208SSatish Balay #define __FUNCT__ "MatMatlabEngineGet_SeqAIJ" 238962aa7f4eSBarry Smith int MatMatlabEngineGet_SeqAIJ(PetscObject obj,void *mengine) 239066826eb6SBarry Smith { 239166826eb6SBarry Smith int ierr,ii; 239266826eb6SBarry Smith Mat mat = (Mat)obj; 239366826eb6SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 239466826eb6SBarry Smith mxArray *mmat; 239566826eb6SBarry Smith 23966c0721eeSBarry Smith PetscFunctionBegin; 239766826eb6SBarry Smith ierr = PetscFree(aij->a);CHKERRQ(ierr); 239866826eb6SBarry Smith 239916ce804cSBarry Smith mmat = engGetVariable((Engine *)mengine,obj->name); 240066826eb6SBarry Smith 2401a65776f3SBarry Smith aij->nz = (mxGetJc(mmat))[mat->m]; 2402a7ed9263SMatthew Knepley ierr = PetscMalloc(((size_t) aij->nz)*(sizeof(int)+sizeof(PetscScalar))+(mat->m+1)*sizeof(int),&aij->a);CHKERRQ(ierr); 240366826eb6SBarry Smith aij->j = (int*)(aij->a + aij->nz); 240466826eb6SBarry Smith aij->i = aij->j + aij->nz; 240566826eb6SBarry Smith aij->singlemalloc = PETSC_TRUE; 240666826eb6SBarry Smith aij->freedata = PETSC_TRUE; 240766826eb6SBarry Smith 240887828ca2SBarry Smith ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 240966826eb6SBarry Smith /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 241066826eb6SBarry Smith ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr); 241166826eb6SBarry Smith ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->m+1)*sizeof(int));CHKERRQ(ierr); 241266826eb6SBarry Smith 241366826eb6SBarry Smith for (ii=0; ii<mat->m; ii++) { 241466826eb6SBarry Smith aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii]; 241566826eb6SBarry Smith } 241666826eb6SBarry Smith 241766826eb6SBarry Smith ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 241866826eb6SBarry Smith ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 241966826eb6SBarry Smith 242066826eb6SBarry Smith PetscFunctionReturn(0); 242166826eb6SBarry Smith } 242266826eb6SBarry Smith EXTERN_C_END 2423f83d6046SBarry Smith #endif 2424f83d6046SBarry Smith 2425be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 24264a2ae208SSatish Balay #undef __FUNCT__ 24274a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ" 242817ab2063SBarry Smith /*@C 2429682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 24300d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 24316e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 243251c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 24332bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 243417ab2063SBarry Smith 2435db81eaa0SLois Curfman McInnes Collective on MPI_Comm 2436db81eaa0SLois Curfman McInnes 243717ab2063SBarry Smith Input Parameters: 2438db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 243917ab2063SBarry Smith . m - number of rows 244017ab2063SBarry Smith . n - number of columns 244117ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 244251c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 24432bd5e0b2SLois Curfman McInnes (possibly different for each row) or PETSC_NULL 244417ab2063SBarry Smith 244517ab2063SBarry Smith Output Parameter: 2446416022c9SBarry Smith . A - the matrix 244717ab2063SBarry Smith 2448b259b22eSLois Curfman McInnes Notes: 244917ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 245017ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 24510002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 245244cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 245317ab2063SBarry Smith 245417ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2455a40aa06bSLois Curfman McInnes Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 24563d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 24576da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 245817ab2063SBarry Smith 2459682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 24604fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 2461682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 24626c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 24636c7ebb05SLois Curfman McInnes 24646c7ebb05SLois Curfman McInnes Options Database Keys: 2465db81eaa0SLois Curfman McInnes + -mat_aij_no_inode - Do not use inodes 2466db81eaa0SLois Curfman McInnes . -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5) 2467db81eaa0SLois Curfman McInnes - -mat_aij_oneindex - Internally use indexing starting at 1 2468db81eaa0SLois Curfman McInnes rather than 0. Note that when calling MatSetValues(), 2469db81eaa0SLois Curfman McInnes the user still MUST index entries starting at 0! 247017ab2063SBarry Smith 2471027ccd11SLois Curfman McInnes Level: intermediate 2472027ccd11SLois Curfman McInnes 247336db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 247436db0b34SBarry Smith 247517ab2063SBarry Smith @*/ 2476ca01db9bSBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,const int nnz[],Mat *A) 247717ab2063SBarry Smith { 2478273d9f13SBarry Smith int ierr; 24796945ee14SBarry Smith 24803a40ed3dSBarry Smith PetscFunctionBegin; 2481273d9f13SBarry Smith ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr); 2482273d9f13SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 2483273d9f13SBarry Smith ierr = MatSeqAIJSetPreallocation(*A,nz,nnz);CHKERRQ(ierr); 2484273d9f13SBarry Smith PetscFunctionReturn(0); 2485273d9f13SBarry Smith } 2486273d9f13SBarry Smith 24875da197adSKris Buschelman #define SKIP_ALLOCATION -4 24885da197adSKris Buschelman 24894a2ae208SSatish Balay #undef __FUNCT__ 24904a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation" 2491273d9f13SBarry Smith /*@C 2492273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 2493273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 2494273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 2495273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 2496273d9f13SBarry Smith 2497273d9f13SBarry Smith Collective on MPI_Comm 2498273d9f13SBarry Smith 2499273d9f13SBarry Smith Input Parameters: 2500273d9f13SBarry Smith + comm - MPI communicator, set to PETSC_COMM_SELF 2501273d9f13SBarry Smith . m - number of rows 2502273d9f13SBarry Smith . n - number of columns 2503273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 2504273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 2505273d9f13SBarry Smith (possibly different for each row) or PETSC_NULL 2506273d9f13SBarry Smith 2507273d9f13SBarry Smith Output Parameter: 2508273d9f13SBarry Smith . A - the matrix 2509273d9f13SBarry Smith 2510273d9f13SBarry Smith Notes: 2511273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 2512273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 2513273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 2514273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 2515273d9f13SBarry Smith 2516273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2517273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 2518273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 2519273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 2520273d9f13SBarry Smith 2521273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 2522273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 2523273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 2524273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 2525273d9f13SBarry Smith 2526273d9f13SBarry Smith Options Database Keys: 2527273d9f13SBarry Smith + -mat_aij_no_inode - Do not use inodes 2528273d9f13SBarry Smith . -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5) 2529273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 2530273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 2531273d9f13SBarry Smith the user still MUST index entries starting at 0! 2532273d9f13SBarry Smith 2533273d9f13SBarry Smith Level: intermediate 2534273d9f13SBarry Smith 2535273d9f13SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 2536273d9f13SBarry Smith 2537273d9f13SBarry Smith @*/ 2538ca01db9bSBarry Smith int MatSeqAIJSetPreallocation(Mat B,int nz,const int nnz[]) 2539273d9f13SBarry Smith { 2540ca01db9bSBarry Smith int ierr,(*f)(Mat,int,const int[]); 2541a23d5eceSKris Buschelman 2542a23d5eceSKris Buschelman PetscFunctionBegin; 2543a23d5eceSKris Buschelman ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",(void (**)(void))&f);CHKERRQ(ierr); 2544a23d5eceSKris Buschelman if (f) { 2545a23d5eceSKris Buschelman ierr = (*f)(B,nz,nnz);CHKERRQ(ierr); 2546a23d5eceSKris Buschelman } 2547a23d5eceSKris Buschelman PetscFunctionReturn(0); 2548a23d5eceSKris Buschelman } 2549a23d5eceSKris Buschelman 2550a23d5eceSKris Buschelman EXTERN_C_BEGIN 2551a23d5eceSKris Buschelman #undef __FUNCT__ 2552a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ" 2553a23d5eceSKris Buschelman int MatSeqAIJSetPreallocation_SeqAIJ(Mat B,int nz,int *nnz) 2554a23d5eceSKris Buschelman { 2555273d9f13SBarry Smith Mat_SeqAIJ *b; 2556a7ed9263SMatthew Knepley size_t len = 0; 2557a43ee2ecSKris Buschelman PetscTruth skipallocation = PETSC_FALSE; 2558a7ed9263SMatthew Knepley int i,ierr; 2559273d9f13SBarry Smith 2560273d9f13SBarry Smith PetscFunctionBegin; 2561d5d45c9bSBarry Smith 2562c461c341SBarry Smith if (nz == SKIP_ALLOCATION) { 2563c461c341SBarry Smith skipallocation = PETSC_TRUE; 2564c461c341SBarry Smith nz = 0; 2565c461c341SBarry Smith } 2566c461c341SBarry Smith 2567435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 2568435da068SBarry Smith if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 2569b73539f3SBarry Smith if (nnz) { 2570273d9f13SBarry Smith for (i=0; i<B->m; i++) { 257129bbc08cSBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 25723a7fca6bSBarry 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); 2573b73539f3SBarry Smith } 2574b73539f3SBarry Smith } 2575b73539f3SBarry Smith 2576273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 2577273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 2578273d9f13SBarry Smith 2579b0a32e0cSBarry Smith ierr = PetscMalloc((B->m+1)*sizeof(int),&b->imax);CHKERRQ(ierr); 2580273d9f13SBarry Smith if (!nnz) { 2581435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 2582273d9f13SBarry Smith else if (nz <= 0) nz = 1; 2583273d9f13SBarry Smith for (i=0; i<B->m; i++) b->imax[i] = nz; 2584273d9f13SBarry Smith nz = nz*B->m; 2585273d9f13SBarry Smith } else { 2586273d9f13SBarry Smith nz = 0; 2587273d9f13SBarry Smith for (i=0; i<B->m; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 2588273d9f13SBarry Smith } 2589273d9f13SBarry Smith 2590c461c341SBarry Smith if (!skipallocation) { 2591273d9f13SBarry Smith /* allocate the matrix space */ 2592a7ed9263SMatthew Knepley len = ((size_t) nz)*(sizeof(int) + sizeof(PetscScalar)) + (B->m+1)*sizeof(int); 2593b0a32e0cSBarry Smith ierr = PetscMalloc(len,&b->a);CHKERRQ(ierr); 2594273d9f13SBarry Smith b->j = (int*)(b->a + nz); 2595273d9f13SBarry Smith ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr); 2596273d9f13SBarry Smith b->i = b->j + nz; 2597bfeeae90SHong Zhang b->i[0] = 0; 25985da197adSKris Buschelman for (i=1; i<B->m+1; i++) { 25995da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 26005da197adSKris Buschelman } 2601273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 2602273d9f13SBarry Smith b->freedata = PETSC_TRUE; 2603c461c341SBarry Smith } else { 2604c461c341SBarry Smith b->freedata = PETSC_FALSE; 2605c461c341SBarry Smith } 2606273d9f13SBarry Smith 2607273d9f13SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 2608b0a32e0cSBarry Smith ierr = PetscMalloc((B->m+1)*sizeof(int),&b->ilen);CHKERRQ(ierr); 2609b0a32e0cSBarry Smith PetscLogObjectMemory(B,len+2*(B->m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2610273d9f13SBarry Smith for (i=0; i<B->m; i++) { b->ilen[i] = 0;} 2611273d9f13SBarry Smith 2612273d9f13SBarry Smith b->nz = 0; 2613273d9f13SBarry Smith b->maxnz = nz; 2614273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 2615273d9f13SBarry Smith PetscFunctionReturn(0); 2616273d9f13SBarry Smith } 2617a23d5eceSKris Buschelman EXTERN_C_END 2618273d9f13SBarry Smith 26190bad9183SKris Buschelman /*MC 2620fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 26210bad9183SKris Buschelman based on compressed sparse row format. 26220bad9183SKris Buschelman 26230bad9183SKris Buschelman Options Database Keys: 26240bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 26250bad9183SKris Buschelman 26260bad9183SKris Buschelman Level: beginner 26270bad9183SKris Buschelman 26280bad9183SKris Buschelman .seealso: MatCreateSeqAIJ 26290bad9183SKris Buschelman M*/ 26300bad9183SKris Buschelman 2631a6175056SHong Zhang EXTERN_C_BEGIN 26324a2ae208SSatish Balay #undef __FUNCT__ 26334a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ" 2634273d9f13SBarry Smith int MatCreate_SeqAIJ(Mat B) 2635273d9f13SBarry Smith { 2636273d9f13SBarry Smith Mat_SeqAIJ *b; 2637273d9f13SBarry Smith int ierr,size; 2638273d9f13SBarry Smith PetscTruth flg; 2639273d9f13SBarry Smith 2640273d9f13SBarry Smith PetscFunctionBegin; 2641273d9f13SBarry Smith ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr); 2642273d9f13SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 2643273d9f13SBarry Smith 2644273d9f13SBarry Smith B->m = B->M = PetscMax(B->m,B->M); 2645273d9f13SBarry Smith B->n = B->N = PetscMax(B->n,B->N); 2646273d9f13SBarry Smith 2647b0a32e0cSBarry Smith ierr = PetscNew(Mat_SeqAIJ,&b);CHKERRQ(ierr); 2648b0a32e0cSBarry Smith B->data = (void*)b; 2649549d3d68SSatish Balay ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr); 2650549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 2651416022c9SBarry Smith B->factor = 0; 2652416022c9SBarry Smith B->lupivotthreshold = 1.0; 265390f02eecSBarry Smith B->mapping = 0; 2654e82a3eeeSBarry Smith ierr = PetscOptionsGetReal(B->prefix,"-mat_lu_pivotthreshold",&B->lupivotthreshold,PETSC_NULL);CHKERRQ(ierr); 2655e82a3eeeSBarry Smith ierr = PetscOptionsHasName(B->prefix,"-pc_ilu_preserve_row_sums",&b->ilu_preserve_row_sums);CHKERRQ(ierr); 2656416022c9SBarry Smith b->row = 0; 2657416022c9SBarry Smith b->col = 0; 265882bf6240SBarry Smith b->icol = 0; 2659b810aeb4SBarry Smith b->reallocs = 0; 266017ab2063SBarry Smith 26618a124369SBarry Smith ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr); 26628a124369SBarry Smith ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr); 2663a5ae1ecdSBarry Smith 2664f1e2ffcdSBarry Smith b->sorted = PETSC_FALSE; 266536db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 2666f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 2667416022c9SBarry Smith b->nonew = 0; 2668416022c9SBarry Smith b->diag = 0; 2669416022c9SBarry Smith b->solve_work = 0; 26702a1b7f2aSHong Zhang B->spptr = 0; 2671b65db4caSBarry Smith b->inode.use = PETSC_TRUE; 2672754ec7b1SSatish Balay b->inode.node_count = 0; 2673754ec7b1SSatish Balay b->inode.size = 0; 26746c7ebb05SLois Curfman McInnes b->inode.limit = 5; 26756c7ebb05SLois Curfman McInnes b->inode.max_limit = 5; 2676be6bf707SBarry Smith b->saved_values = 0; 2677d7f994e1SBarry Smith b->idiag = 0; 2678d7f994e1SBarry Smith b->ssor = 0; 2679f1e2ffcdSBarry Smith b->keepzeroedrows = PETSC_FALSE; 2680a30b2313SHong Zhang b->xtoy = 0; 2681a30b2313SHong Zhang b->XtoY = 0; 268217ab2063SBarry Smith 268335d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 268435d8aa7fSBarry Smith 2685e82a3eeeSBarry Smith ierr = PetscOptionsHasName(B->prefix,"-mat_aij_matlab",&flg);CHKERRQ(ierr); 2686ca44d042SBarry Smith if (flg) {ierr = MatUseMatlab_SeqAIJ(B);CHKERRQ(ierr);} 2687f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C", 2688bef8e0ddSBarry Smith "MatSeqAIJSetColumnIndices_SeqAIJ", 2689bc4b532fSSatish Balay MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 2690f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 2691be6bf707SBarry Smith "MatStoreValues_SeqAIJ", 2692bc4b532fSSatish Balay MatStoreValues_SeqAIJ);CHKERRQ(ierr); 2693f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 2694be6bf707SBarry Smith "MatRetrieveValues_SeqAIJ", 2695bc4b532fSSatish Balay MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 2696a6175056SHong Zhang ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C", 2697a6175056SHong Zhang "MatConvert_SeqAIJ_SeqSBAIJ", 2698a6175056SHong Zhang MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 269985fc7724SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C", 270085fc7724SBarry Smith "MatConvert_SeqAIJ_SeqBAIJ", 270185fc7724SBarry Smith MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 27025fbd3699SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C", 27035fbd3699SBarry Smith "MatIsTranspose_SeqAIJ", 27045fbd3699SBarry Smith MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 2705a23d5eceSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C", 2706a23d5eceSKris Buschelman "MatSeqAIJSetPreallocation_SeqAIJ", 2707a23d5eceSKris Buschelman MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 270805b94e36SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C", 270905b94e36SKris Buschelman "MatReorderForNonzeroDiagonal_SeqAIJ", 271005b94e36SKris Buschelman MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 27110a99d0a2SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatAdjustForInodes_C", 27120a99d0a2SKris Buschelman "MatAdjustForInodes_SeqAIJ", 27130a99d0a2SKris Buschelman MatAdjustForInodes_SeqAIJ);CHKERRQ(ierr); 2714d758967fSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJGetInodeSizes_C", 2715d758967fSKris Buschelman "MatSeqAIJGetInodeSizes_SeqAIJ", 2716d758967fSKris Buschelman MatSeqAIJGetInodeSizes_SeqAIJ);CHKERRQ(ierr); 271716ce804cSBarry Smith #if defined(PETSC_HAVE_MATLAB) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) 2718f83d6046SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatMatlabEnginePut_SeqAIJ",MatMatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 271966826eb6SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatMatlabEngineGet_SeqAIJ",MatMatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 2720f83d6046SBarry Smith #endif 2721eb9c0419SKris Buschelman ierr = RegisterApplyPtAPRoutines_Private(B);CHKERRQ(ierr); 27223a40ed3dSBarry Smith PetscFunctionReturn(0); 272317ab2063SBarry Smith } 2724273d9f13SBarry Smith EXTERN_C_END 272517ab2063SBarry Smith 27264a2ae208SSatish Balay #undef __FUNCT__ 27274a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqAIJ" 2728be6bf707SBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 272917ab2063SBarry Smith { 2730416022c9SBarry Smith Mat C; 2731416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 2732bfeeae90SHong Zhang int i,m = A->m,ierr; 2733a7ed9263SMatthew Knepley size_t len; 273417ab2063SBarry Smith 27353a40ed3dSBarry Smith PetscFunctionBegin; 27364043dd9cSLois Curfman McInnes *B = 0; 2737273d9f13SBarry Smith ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr); 2738273d9f13SBarry Smith ierr = MatSetType(C,MATSEQAIJ);CHKERRQ(ierr); 2739273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 2740273d9f13SBarry Smith 2741416022c9SBarry Smith C->factor = A->factor; 2742416022c9SBarry Smith c->row = 0; 2743416022c9SBarry Smith c->col = 0; 274482bf6240SBarry Smith c->icol = 0; 2745f1e2ffcdSBarry Smith c->keepzeroedrows = a->keepzeroedrows; 2746c456f294SBarry Smith C->assembled = PETSC_TRUE; 274717ab2063SBarry Smith 2748273d9f13SBarry Smith C->M = A->m; 2749273d9f13SBarry Smith C->N = A->n; 275017ab2063SBarry Smith 2751b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&c->imax);CHKERRQ(ierr); 2752b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&c->ilen);CHKERRQ(ierr); 275317ab2063SBarry Smith for (i=0; i<m; i++) { 2754416022c9SBarry Smith c->imax[i] = a->imax[i]; 2755416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 275617ab2063SBarry Smith } 275717ab2063SBarry Smith 275817ab2063SBarry Smith /* allocate the matrix space */ 2759f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 2760a7ed9263SMatthew Knepley len = ((size_t) (m+1))*sizeof(int)+(a->i[m])*(sizeof(PetscScalar)+sizeof(int)); 2761b0a32e0cSBarry Smith ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr); 2762bfeeae90SHong Zhang c->j = (int*)(c->a + a->i[m] ); 2763bfeeae90SHong Zhang c->i = c->j + a->i[m]; 2764549d3d68SSatish Balay ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));CHKERRQ(ierr); 276517ab2063SBarry Smith if (m > 0) { 2766bfeeae90SHong Zhang ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(int));CHKERRQ(ierr); 2767be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 2768bfeeae90SHong Zhang ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 2769be6bf707SBarry Smith } else { 2770bfeeae90SHong Zhang ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 277117ab2063SBarry Smith } 277208480c60SBarry Smith } 277317ab2063SBarry Smith 2774b0a32e0cSBarry Smith PetscLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2775416022c9SBarry Smith c->sorted = a->sorted; 2776416022c9SBarry Smith c->roworiented = a->roworiented; 2777416022c9SBarry Smith c->nonew = a->nonew; 27787a743949SBarry Smith c->ilu_preserve_row_sums = a->ilu_preserve_row_sums; 2779be6bf707SBarry Smith c->saved_values = 0; 2780d7f994e1SBarry Smith c->idiag = 0; 2781d7f994e1SBarry Smith c->ssor = 0; 278236db0b34SBarry Smith c->ignorezeroentries = a->ignorezeroentries; 278336db0b34SBarry Smith c->freedata = PETSC_TRUE; 278417ab2063SBarry Smith 2785416022c9SBarry Smith if (a->diag) { 2786b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&c->diag);CHKERRQ(ierr); 2787b0a32e0cSBarry Smith PetscLogObjectMemory(C,(m+1)*sizeof(int)); 278817ab2063SBarry Smith for (i=0; i<m; i++) { 2789416022c9SBarry Smith c->diag[i] = a->diag[i]; 279017ab2063SBarry Smith } 27913a40ed3dSBarry Smith } else c->diag = 0; 2792b65db4caSBarry Smith c->inode.use = a->inode.use; 27936c7ebb05SLois Curfman McInnes c->inode.limit = a->inode.limit; 27946c7ebb05SLois Curfman McInnes c->inode.max_limit = a->inode.max_limit; 2795754ec7b1SSatish Balay if (a->inode.size){ 2796b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&c->inode.size);CHKERRQ(ierr); 2797754ec7b1SSatish Balay c->inode.node_count = a->inode.node_count; 2798549d3d68SSatish Balay ierr = PetscMemcpy(c->inode.size,a->inode.size,(m+1)*sizeof(int));CHKERRQ(ierr); 2799754ec7b1SSatish Balay } else { 2800754ec7b1SSatish Balay c->inode.size = 0; 2801754ec7b1SSatish Balay c->inode.node_count = 0; 2802754ec7b1SSatish Balay } 2803416022c9SBarry Smith c->nz = a->nz; 2804416022c9SBarry Smith c->maxnz = a->maxnz; 2805416022c9SBarry Smith c->solve_work = 0; 28062a1b7f2aSHong Zhang C->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 2807273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 2808754ec7b1SSatish Balay 2809416022c9SBarry Smith *B = C; 2810b0a32e0cSBarry Smith ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 28113a40ed3dSBarry Smith PetscFunctionReturn(0); 281217ab2063SBarry Smith } 281317ab2063SBarry Smith 28144a2ae208SSatish Balay #undef __FUNCT__ 28154a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ" 2816b0a32e0cSBarry Smith int MatLoad_SeqAIJ(PetscViewer viewer,MatType type,Mat *A) 281717ab2063SBarry Smith { 2818416022c9SBarry Smith Mat_SeqAIJ *a; 2819416022c9SBarry Smith Mat B; 2820efb16452SHong Zhang int i,nz,ierr,fd,header[4],size,*rowlengths = 0,M,N; 2821bcd2baecSBarry Smith MPI_Comm comm; 282217ab2063SBarry Smith 28233a40ed3dSBarry Smith PetscFunctionBegin; 2824e864ced6SBarry Smith ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 2825d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 282629bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,"view must have one processor"); 2827b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 28280752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 2829552e946dSBarry Smith if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 283017ab2063SBarry Smith M = header[1]; N = header[2]; nz = header[3]; 283117ab2063SBarry Smith 2832d64ed03dSBarry Smith if (nz < 0) { 283329bbc08cSBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 2834d64ed03dSBarry Smith } 2835d64ed03dSBarry Smith 283617ab2063SBarry Smith /* read in row lengths */ 2837b0a32e0cSBarry Smith ierr = PetscMalloc(M*sizeof(int),&rowlengths);CHKERRQ(ierr); 28380752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 283917ab2063SBarry Smith 284017ab2063SBarry Smith /* create our matrix */ 2841b3a1e11cSKris Buschelman ierr = MatCreate(comm,PETSC_DECIDE,PETSC_DECIDE,M,N,&B);CHKERRQ(ierr); 2842b3a1e11cSKris Buschelman ierr = MatSetType(B,type);CHKERRQ(ierr); 2843b3a1e11cSKris Buschelman ierr = MatSeqAIJSetPreallocation(B,0,rowlengths);CHKERRQ(ierr); 2844416022c9SBarry Smith a = (Mat_SeqAIJ*)B->data; 284517ab2063SBarry Smith 284617ab2063SBarry Smith /* read in column indices and adjust for Fortran indexing*/ 28470752156aSBarry Smith ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 284817ab2063SBarry Smith 284917ab2063SBarry Smith /* read in nonzero values */ 28500752156aSBarry Smith ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 285117ab2063SBarry Smith 285217ab2063SBarry Smith /* set matrix "i" values */ 2853efb16452SHong Zhang a->i[0] = 0; 285417ab2063SBarry Smith for (i=1; i<= M; i++) { 2855416022c9SBarry Smith a->i[i] = a->i[i-1] + rowlengths[i-1]; 2856416022c9SBarry Smith a->ilen[i-1] = rowlengths[i-1]; 285717ab2063SBarry Smith } 2858606d414cSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 285917ab2063SBarry Smith 28606d4a8577SBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 28616d4a8577SBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2862b3a1e11cSKris Buschelman *A = B; 28633a40ed3dSBarry Smith PetscFunctionReturn(0); 286417ab2063SBarry Smith } 286517ab2063SBarry Smith 28664a2ae208SSatish Balay #undef __FUNCT__ 2867b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ" 28688f6be9afSLois Curfman McInnes int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg) 28697264ac53SSatish Balay { 28707264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data; 28710f5bd95cSBarry Smith int ierr; 28727264ac53SSatish Balay 28733a40ed3dSBarry Smith PetscFunctionBegin; 2874bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 2875bfeeae90SHong Zhang if ((A->m != B->m) || (A->n != B->n) ||(a->nz != b->nz)) { 2876ca44d042SBarry Smith *flg = PETSC_FALSE; 2877ca44d042SBarry Smith PetscFunctionReturn(0); 2878bcd2baecSBarry Smith } 28797264ac53SSatish Balay 28807264ac53SSatish Balay /* if the a->i are the same */ 2881273d9f13SBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->m+1)*sizeof(int),flg);CHKERRQ(ierr); 28820f5bd95cSBarry Smith if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 28837264ac53SSatish Balay 28847264ac53SSatish Balay /* if a->j are the same */ 28850f5bd95cSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(int),flg);CHKERRQ(ierr); 28860f5bd95cSBarry Smith if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 2887bcd2baecSBarry Smith 2888bcd2baecSBarry Smith /* if a->a are the same */ 288987828ca2SBarry Smith ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 28900f5bd95cSBarry Smith 28913a40ed3dSBarry Smith PetscFunctionReturn(0); 28927264ac53SSatish Balay 28937264ac53SSatish Balay } 289436db0b34SBarry Smith 28954a2ae208SSatish Balay #undef __FUNCT__ 28964a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays" 289736db0b34SBarry Smith /*@C 289836db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 289936db0b34SBarry Smith provided by the user. 290036db0b34SBarry Smith 290136db0b34SBarry Smith Coolective on MPI_Comm 290236db0b34SBarry Smith 290336db0b34SBarry Smith Input Parameters: 290436db0b34SBarry Smith + comm - must be an MPI communicator of size 1 290536db0b34SBarry Smith . m - number of rows 290636db0b34SBarry Smith . n - number of columns 290736db0b34SBarry Smith . i - row indices 290836db0b34SBarry Smith . j - column indices 290936db0b34SBarry Smith - a - matrix values 291036db0b34SBarry Smith 291136db0b34SBarry Smith Output Parameter: 291236db0b34SBarry Smith . mat - the matrix 291336db0b34SBarry Smith 291436db0b34SBarry Smith Level: intermediate 291536db0b34SBarry Smith 291636db0b34SBarry Smith Notes: 29170551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 291836db0b34SBarry Smith once the matrix is destroyed 291936db0b34SBarry Smith 292036db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 292136db0b34SBarry Smith 2922bfeeae90SHong Zhang The i and j indices are 0 based 292336db0b34SBarry Smith 292436db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ() 292536db0b34SBarry Smith 292636db0b34SBarry Smith @*/ 292787828ca2SBarry Smith int MatCreateSeqAIJWithArrays(MPI_Comm comm,int m,int n,int* i,int*j,PetscScalar *a,Mat *mat) 292836db0b34SBarry Smith { 292936db0b34SBarry Smith int ierr,ii; 293036db0b34SBarry Smith Mat_SeqAIJ *aij; 293136db0b34SBarry Smith 293236db0b34SBarry Smith PetscFunctionBegin; 2933c461c341SBarry Smith ierr = MatCreateSeqAIJ(comm,m,n,SKIP_ALLOCATION,0,mat);CHKERRQ(ierr); 293436db0b34SBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 293536db0b34SBarry Smith 2936bfeeae90SHong Zhang if (i[0] != 0) { 2937bfeeae90SHong Zhang SETERRQ(1,"i (row indices) must start with 0"); 293836db0b34SBarry Smith } 293936db0b34SBarry Smith aij->i = i; 294036db0b34SBarry Smith aij->j = j; 294136db0b34SBarry Smith aij->a = a; 294236db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 294336db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 294436db0b34SBarry Smith aij->freedata = PETSC_FALSE; 294536db0b34SBarry Smith 294636db0b34SBarry Smith for (ii=0; ii<m; ii++) { 294736db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 29489860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g) 294929bbc08cSBarry Smith if (i[ii+1] - i[ii] < 0) SETERRQ2(1,"Negative row length in i (row indices) row = %d length = %d",ii,i[ii+1] - i[ii]); 295036db0b34SBarry Smith #endif 295136db0b34SBarry Smith } 29529860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g) 295336db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 2954bfeeae90SHong Zhang if (j[ii] < 0) SETERRQ2(1,"Negative column index at location = %d index = %d",ii,j[ii]); 2955bfeeae90SHong Zhang if (j[ii] > n - 1) SETERRQ2(1,"Column index to large at location = %d index = %d",ii,j[ii]); 295636db0b34SBarry Smith } 295736db0b34SBarry Smith #endif 295836db0b34SBarry Smith 2959b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2960b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 296136db0b34SBarry Smith PetscFunctionReturn(0); 296236db0b34SBarry Smith } 296336db0b34SBarry Smith 2964cc8ba8e1SBarry Smith #undef __FUNCT__ 2965ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ" 2966ee4f033dSBarry Smith int MatSetColoring_SeqAIJ(Mat A,ISColoring coloring) 2967cc8ba8e1SBarry Smith { 2968cc8ba8e1SBarry Smith int ierr; 2969cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 297036db0b34SBarry Smith 2971cc8ba8e1SBarry Smith PetscFunctionBegin; 297212c595b3SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 2973cc8ba8e1SBarry Smith ierr = ISColoringReference(coloring);CHKERRQ(ierr); 2974cc8ba8e1SBarry Smith a->coloring = coloring; 297512c595b3SBarry Smith } else if (coloring->ctype == IS_COLORING_GHOSTED) { 297608b6dcc0SBarry Smith int i,*larray; 297712c595b3SBarry Smith ISColoring ocoloring; 297808b6dcc0SBarry Smith ISColoringValue *colors; 297912c595b3SBarry Smith 298012c595b3SBarry Smith /* set coloring for diagonal portion */ 298112c595b3SBarry Smith ierr = PetscMalloc((A->n+1)*sizeof(int),&larray);CHKERRQ(ierr); 298212c595b3SBarry Smith for (i=0; i<A->n; i++) { 298312c595b3SBarry Smith larray[i] = i; 298412c595b3SBarry Smith } 298512c595b3SBarry Smith ierr = ISGlobalToLocalMappingApply(A->mapping,IS_GTOLM_MASK,A->n,larray,PETSC_NULL,larray);CHKERRQ(ierr); 298608b6dcc0SBarry Smith ierr = PetscMalloc((A->n+1)*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); 298712c595b3SBarry Smith for (i=0; i<A->n; i++) { 298812c595b3SBarry Smith colors[i] = coloring->colors[larray[i]]; 298912c595b3SBarry Smith } 299012c595b3SBarry Smith ierr = PetscFree(larray);CHKERRQ(ierr); 299112c595b3SBarry Smith ierr = ISColoringCreate(PETSC_COMM_SELF,A->n,colors,&ocoloring);CHKERRQ(ierr); 299212c595b3SBarry Smith a->coloring = ocoloring; 299312c595b3SBarry Smith } 2994cc8ba8e1SBarry Smith PetscFunctionReturn(0); 2995cc8ba8e1SBarry Smith } 2996cc8ba8e1SBarry Smith 299787828ca2SBarry Smith #if defined(PETSC_HAVE_ADIC) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) 2998ee4f033dSBarry Smith EXTERN_C_BEGIN 299929c1e371SBarry Smith #include "adic/ad_utils.h" 3000ee4f033dSBarry Smith EXTERN_C_END 3001cc8ba8e1SBarry Smith 3002cc8ba8e1SBarry Smith #undef __FUNCT__ 3003ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ" 3004ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues) 3005cc8ba8e1SBarry Smith { 3006cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 300708b6dcc0SBarry Smith int m = A->m,*ii = a->i,*jj = a->j,nz,i,j,nlen; 30084440f671SBarry Smith PetscScalar *v = a->a,*values = ((PetscScalar*)advalues)+1; 300908b6dcc0SBarry Smith ISColoringValue *color; 3010cc8ba8e1SBarry Smith 3011cc8ba8e1SBarry Smith PetscFunctionBegin; 3012cc8ba8e1SBarry Smith if (!a->coloring) SETERRQ(1,"Coloring not set for matrix"); 30134440f671SBarry Smith nlen = PetscADGetDerivTypeSize()/sizeof(PetscScalar); 3014cc8ba8e1SBarry Smith color = a->coloring->colors; 3015cc8ba8e1SBarry Smith /* loop over rows */ 3016cc8ba8e1SBarry Smith for (i=0; i<m; i++) { 3017cc8ba8e1SBarry Smith nz = ii[i+1] - ii[i]; 3018cc8ba8e1SBarry Smith /* loop over columns putting computed value into matrix */ 3019cc8ba8e1SBarry Smith for (j=0; j<nz; j++) { 3020cc8ba8e1SBarry Smith *v++ = values[color[*jj++]]; 3021cc8ba8e1SBarry Smith } 30224440f671SBarry Smith values += nlen; /* jump to next row of derivatives */ 3023ee4f033dSBarry Smith } 3024ee4f033dSBarry Smith PetscFunctionReturn(0); 3025ee4f033dSBarry Smith } 3026ee4f033dSBarry Smith 3027ee4f033dSBarry Smith #else 3028ee4f033dSBarry Smith 3029ee4f033dSBarry Smith #undef __FUNCT__ 3030ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ" 3031ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues) 3032ee4f033dSBarry Smith { 3033ee4f033dSBarry Smith PetscFunctionBegin; 3034ee4f033dSBarry Smith SETERRQ(1,"PETSc installed without ADIC"); 3035ee4f033dSBarry Smith } 3036ee4f033dSBarry Smith 3037ee4f033dSBarry Smith #endif 3038ee4f033dSBarry Smith 3039ee4f033dSBarry Smith #undef __FUNCT__ 3040ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ" 3041ee4f033dSBarry Smith int MatSetValuesAdifor_SeqAIJ(Mat A,int nl,void *advalues) 3042ee4f033dSBarry Smith { 3043ee4f033dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 304408b6dcc0SBarry Smith int m = A->m,*ii = a->i,*jj = a->j,nz,i,j; 304587828ca2SBarry Smith PetscScalar *v = a->a,*values = (PetscScalar *)advalues; 304608b6dcc0SBarry Smith ISColoringValue *color; 3047ee4f033dSBarry Smith 3048ee4f033dSBarry Smith PetscFunctionBegin; 3049ee4f033dSBarry Smith if (!a->coloring) SETERRQ(1,"Coloring not set for matrix"); 3050ee4f033dSBarry Smith color = a->coloring->colors; 3051ee4f033dSBarry Smith /* loop over rows */ 3052ee4f033dSBarry Smith for (i=0; i<m; i++) { 3053ee4f033dSBarry Smith nz = ii[i+1] - ii[i]; 3054ee4f033dSBarry Smith /* loop over columns putting computed value into matrix */ 3055ee4f033dSBarry Smith for (j=0; j<nz; j++) { 3056ee4f033dSBarry Smith *v++ = values[color[*jj++]]; 3057ee4f033dSBarry Smith } 3058ee4f033dSBarry Smith values += nl; /* jump to next row of derivatives */ 3059cc8ba8e1SBarry Smith } 3060cc8ba8e1SBarry Smith PetscFunctionReturn(0); 3061cc8ba8e1SBarry Smith } 306236db0b34SBarry Smith 3063