1be1d678aSKris Buschelman #define PETSCMAT_DLL 2b3cc6726SBarry Smith 3d5d45c9bSBarry Smith /* 43369ce9aSBarry Smith Defines the basic matrix operations for the AIJ (compressed row) 5d5d45c9bSBarry Smith matrix storage format. 6d5d45c9bSBarry Smith */ 73369ce9aSBarry Smith 89e070d67SMatthew Knepley #include "src/mat/impls/aij/seq/aij.h" /*I "petscmat.h" I*/ 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__ 1479299369SBarry Smith #define __FUNCT__ "MatDiagonalSet_SeqAIJ" 1579299369SBarry Smith /* only works if matrix has a full set of diagonal entries */ 1679299369SBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is) 1779299369SBarry Smith { 1879299369SBarry Smith PetscErrorCode ierr; 1979299369SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) Y->data; 2079299369SBarry Smith PetscInt i,*diag, m = Y->m; 2179299369SBarry Smith PetscScalar *v,*aa = aij->a; 2279299369SBarry Smith 2379299369SBarry Smith PetscFunctionBegin; 2479299369SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(Y);CHKERRQ(ierr); 2579299369SBarry Smith diag = aij->diag; 2679299369SBarry Smith ierr = VecGetArray(D,&v);CHKERRQ(ierr); 2779299369SBarry Smith if (is == INSERT_VALUES) { 2879299369SBarry Smith for (i=0; i<m; i++) { 2979299369SBarry Smith aa[diag[i]] = v[i]; 3079299369SBarry Smith } 3179299369SBarry Smith } else { 3279299369SBarry Smith for (i=0; i<m; i++) { 3379299369SBarry Smith aa[diag[i]] += v[i]; 3479299369SBarry Smith } 3579299369SBarry Smith } 3679299369SBarry Smith ierr = VecRestoreArray(D,&v);CHKERRQ(ierr); 3779299369SBarry Smith PetscFunctionReturn(0); 3879299369SBarry Smith } 3979299369SBarry Smith 4079299369SBarry Smith #undef __FUNCT__ 414a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ" 4297f1f81fSBarry Smith PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscInt *m,PetscInt *ia[],PetscInt *ja[],PetscTruth *done) 4317ab2063SBarry Smith { 44416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 45dfbe8321SBarry Smith PetscErrorCode ierr; 4697f1f81fSBarry Smith PetscInt i,ishift; 4717ab2063SBarry Smith 483a40ed3dSBarry Smith PetscFunctionBegin; 4931625ec5SSatish Balay *m = A->m; 503a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 51bfeeae90SHong Zhang ishift = 0; 5253e63a63SBarry Smith if (symmetric && !A->structurally_symmetric) { 53273d9f13SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr); 54bfeeae90SHong Zhang } else if (oshift == 1) { 5597f1f81fSBarry Smith PetscInt nz = a->i[A->m]; 563b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 5797f1f81fSBarry Smith ierr = PetscMalloc((A->m+1)*sizeof(PetscInt),ia);CHKERRQ(ierr); 5897f1f81fSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscInt),ja);CHKERRQ(ierr); 593b2fbd54SBarry Smith for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1; 60273d9f13SBarry Smith for (i=0; i<A->m+1; i++) (*ia)[i] = a->i[i] + 1; 616945ee14SBarry Smith } else { 626945ee14SBarry Smith *ia = a->i; *ja = a->j; 63a2ce50c7SBarry Smith } 643a40ed3dSBarry Smith PetscFunctionReturn(0); 65a2744918SBarry Smith } 66a2744918SBarry Smith 674a2ae208SSatish Balay #undef __FUNCT__ 684a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ" 6997f1f81fSBarry Smith PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscTruth *done) 706945ee14SBarry Smith { 71dfbe8321SBarry Smith PetscErrorCode ierr; 726945ee14SBarry Smith 733a40ed3dSBarry Smith PetscFunctionBegin; 743a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 75bfeeae90SHong Zhang if ((symmetric && !A->structurally_symmetric) || oshift == 1) { 76606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 77606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 78bcd2baecSBarry Smith } 793a40ed3dSBarry Smith PetscFunctionReturn(0); 8017ab2063SBarry Smith } 8117ab2063SBarry Smith 824a2ae208SSatish Balay #undef __FUNCT__ 834a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ" 8497f1f81fSBarry Smith PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscInt *nn,PetscInt *ia[],PetscInt *ja[],PetscTruth *done) 853b2fbd54SBarry Smith { 863b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 87dfbe8321SBarry Smith PetscErrorCode ierr; 8897f1f81fSBarry Smith PetscInt i,*collengths,*cia,*cja,n = A->n,m = A->m; 8997f1f81fSBarry Smith PetscInt nz = a->i[m],row,*jj,mr,col; 903b2fbd54SBarry Smith 913a40ed3dSBarry Smith PetscFunctionBegin; 923b2fbd54SBarry Smith *nn = A->n; 933a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 943b2fbd54SBarry Smith if (symmetric) { 95bfeeae90SHong Zhang ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr); 963b2fbd54SBarry Smith } else { 9797f1f81fSBarry Smith ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr); 9897f1f81fSBarry Smith ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 9997f1f81fSBarry Smith ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr); 10097f1f81fSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr); 1013b2fbd54SBarry Smith jj = a->j; 1023b2fbd54SBarry Smith for (i=0; i<nz; i++) { 103bfeeae90SHong Zhang collengths[jj[i]]++; 1043b2fbd54SBarry Smith } 1053b2fbd54SBarry Smith cia[0] = oshift; 1063b2fbd54SBarry Smith for (i=0; i<n; i++) { 1073b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 1083b2fbd54SBarry Smith } 10997f1f81fSBarry Smith ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 1103b2fbd54SBarry Smith jj = a->j; 111a93ec695SBarry Smith for (row=0; row<m; row++) { 112a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 113a93ec695SBarry Smith for (i=0; i<mr; i++) { 114bfeeae90SHong Zhang col = *jj++; 1153b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 1163b2fbd54SBarry Smith } 1173b2fbd54SBarry Smith } 118606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 1193b2fbd54SBarry Smith *ia = cia; *ja = cja; 1203b2fbd54SBarry Smith } 1213a40ed3dSBarry Smith PetscFunctionReturn(0); 1223b2fbd54SBarry Smith } 1233b2fbd54SBarry Smith 1244a2ae208SSatish Balay #undef __FUNCT__ 1254a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ" 12697f1f81fSBarry Smith PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscTruth *done) 1273b2fbd54SBarry Smith { 128dfbe8321SBarry Smith PetscErrorCode ierr; 129606d414cSSatish Balay 1303a40ed3dSBarry Smith PetscFunctionBegin; 1313a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 1323b2fbd54SBarry Smith 133606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 134606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 1353b2fbd54SBarry Smith 1363a40ed3dSBarry Smith PetscFunctionReturn(0); 1373b2fbd54SBarry Smith } 1383b2fbd54SBarry Smith 139227d817aSBarry Smith #define CHUNKSIZE 15 14017ab2063SBarry Smith 1414a2ae208SSatish Balay #undef __FUNCT__ 1424a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ" 14397f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 14417ab2063SBarry Smith { 145416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 146e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 14797f1f81fSBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 1486849ba73SBarry Smith PetscErrorCode ierr; 149e2ee6c50SBarry Smith PetscInt *aj = a->j,nonew = a->nonew,lastcol = -1; 15087828ca2SBarry Smith PetscScalar *ap,value,*aa = a->a; 15136db0b34SBarry Smith PetscTruth ignorezeroentries = ((a->ignorezeroentries && is == ADD_VALUES) ? PETSC_TRUE:PETSC_FALSE); 152273d9f13SBarry Smith PetscTruth roworiented = a->roworiented; 15317ab2063SBarry Smith 1543a40ed3dSBarry Smith PetscFunctionBegin; 15517ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 156416022c9SBarry Smith row = im[k]; 1575ef9f2a5SBarry Smith if (row < 0) continue; 1582515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 15977431f27SBarry Smith if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->m-1); 1603b2fbd54SBarry Smith #endif 161bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 16217ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 163416022c9SBarry Smith low = 0; 164c71e6ed7SBarry Smith high = nrow; 16517ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 1665ef9f2a5SBarry Smith if (in[l] < 0) continue; 1672515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 16877431f27SBarry Smith if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->n-1); 1693b2fbd54SBarry Smith #endif 170bfeeae90SHong Zhang col = in[l]; 1714b0e389bSBarry Smith if (roworiented) { 1725ef9f2a5SBarry Smith value = v[l + k*n]; 173bef8e0ddSBarry Smith } else { 1744b0e389bSBarry Smith value = v[k + l*m]; 1754b0e389bSBarry Smith } 176abc0a331SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 17736db0b34SBarry Smith 1787cd84e04SBarry Smith if (col <= lastcol) low = 0; else high = nrow; 179e2ee6c50SBarry Smith lastcol = col; 180416022c9SBarry Smith while (high-low > 5) { 181416022c9SBarry Smith t = (low+high)/2; 182416022c9SBarry Smith if (rp[t] > col) high = t; 183416022c9SBarry Smith else low = t; 18417ab2063SBarry Smith } 185416022c9SBarry Smith for (i=low; i<high; i++) { 18617ab2063SBarry Smith if (rp[i] > col) break; 18717ab2063SBarry Smith if (rp[i] == col) { 188416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 18917ab2063SBarry Smith else ap[i] = value; 19017ab2063SBarry Smith goto noinsert; 19117ab2063SBarry Smith } 19217ab2063SBarry Smith } 193abc0a331SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 194c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 195cc72174dSBarry Smith if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 196ed1caa07SMatthew Knepley MatSeqXAIJReallocateAIJ(a,1,nrow,row,col,rmax,aa,ai,aj,A->m,rp,ap,imax,nonew); 197416022c9SBarry Smith N = nrow++ - 1; a->nz++; 198416022c9SBarry Smith /* shift up all the later entries in this row */ 199416022c9SBarry Smith for (ii=N; ii>=i; ii--) { 20017ab2063SBarry Smith rp[ii+1] = rp[ii]; 20117ab2063SBarry Smith ap[ii+1] = ap[ii]; 20217ab2063SBarry Smith } 20317ab2063SBarry Smith rp[i] = col; 20417ab2063SBarry Smith ap[i] = value; 20517ab2063SBarry Smith noinsert:; 206416022c9SBarry Smith low = i + 1; 20717ab2063SBarry Smith } 20817ab2063SBarry Smith ailen[row] = nrow; 20917ab2063SBarry Smith } 21088e51ccdSHong Zhang A->same_nonzero = PETSC_FALSE; 2113a40ed3dSBarry Smith PetscFunctionReturn(0); 21217ab2063SBarry Smith } 21317ab2063SBarry Smith 2144a2ae208SSatish Balay #undef __FUNCT__ 2154a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ" 21697f1f81fSBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 2177eb43aa7SLois Curfman McInnes { 2187eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 21997f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 22097f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 22187828ca2SBarry Smith PetscScalar *ap,*aa = a->a,zero = 0.0; 2227eb43aa7SLois Curfman McInnes 2233a40ed3dSBarry Smith PetscFunctionBegin; 2247eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 2257eb43aa7SLois Curfman McInnes row = im[k]; 22677431f27SBarry Smith if (row < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); 22777431f27SBarry Smith if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->m-1); 228bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 2297eb43aa7SLois Curfman McInnes nrow = ailen[row]; 2307eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 23177431f27SBarry Smith if (in[l] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); 23277431f27SBarry Smith if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->n-1); 233bfeeae90SHong Zhang col = in[l] ; 2347eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 2357eb43aa7SLois Curfman McInnes while (high-low > 5) { 2367eb43aa7SLois Curfman McInnes t = (low+high)/2; 2377eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 2387eb43aa7SLois Curfman McInnes else low = t; 2397eb43aa7SLois Curfman McInnes } 2407eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 2417eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 2427eb43aa7SLois Curfman McInnes if (rp[i] == col) { 243b49de8d1SLois Curfman McInnes *v++ = ap[i]; 2447eb43aa7SLois Curfman McInnes goto finished; 2457eb43aa7SLois Curfman McInnes } 2467eb43aa7SLois Curfman McInnes } 247b49de8d1SLois Curfman McInnes *v++ = zero; 2487eb43aa7SLois Curfman McInnes finished:; 2497eb43aa7SLois Curfman McInnes } 2507eb43aa7SLois Curfman McInnes } 2513a40ed3dSBarry Smith PetscFunctionReturn(0); 2527eb43aa7SLois Curfman McInnes } 2537eb43aa7SLois Curfman McInnes 25417ab2063SBarry Smith 2554a2ae208SSatish Balay #undef __FUNCT__ 2564a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary" 257dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer) 25817ab2063SBarry Smith { 259416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2606849ba73SBarry Smith PetscErrorCode ierr; 2616f69ff64SBarry Smith PetscInt i,*col_lens; 2626f69ff64SBarry Smith int fd; 26317ab2063SBarry Smith 2643a40ed3dSBarry Smith PetscFunctionBegin; 265b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 26697f1f81fSBarry Smith ierr = PetscMalloc((4+A->m)*sizeof(PetscInt),&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 } 2766f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 277606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 278416022c9SBarry Smith 279416022c9SBarry Smith /* store column indices (zero start index) */ 2806f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 281416022c9SBarry Smith 282416022c9SBarry Smith /* store nonzero values */ 2836f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 2843a40ed3dSBarry Smith PetscFunctionReturn(0); 28517ab2063SBarry Smith } 286416022c9SBarry Smith 287dfbe8321SBarry Smith EXTERN PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 288cd155464SBarry Smith 2894a2ae208SSatish Balay #undef __FUNCT__ 2904a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII" 291dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 292416022c9SBarry Smith { 293416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 294dfbe8321SBarry Smith PetscErrorCode ierr; 29597f1f81fSBarry Smith PetscInt i,j,m = A->m,shift=0; 296e060cb09SBarry Smith const char *name; 297f3ef73ceSBarry Smith PetscViewerFormat format; 29817ab2063SBarry Smith 2993a40ed3dSBarry Smith PetscFunctionBegin; 300435da068SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 301b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 30271c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 30397f1f81fSBarry Smith PetscInt nofinalvalue = 0; 304273d9f13SBarry Smith if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->n-!shift)) { 305d00d2cf4SBarry Smith nofinalvalue = 1; 306d00d2cf4SBarry Smith } 307b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 30877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->n);CHKERRQ(ierr); 30977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 31077431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 311b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 31217ab2063SBarry Smith 31317ab2063SBarry Smith for (i=0; i<m; i++) { 314416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 315aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 31677431f27SBarry 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); 31717ab2063SBarry Smith #else 31877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr); 31917ab2063SBarry Smith #endif 32017ab2063SBarry Smith } 32117ab2063SBarry Smith } 322d00d2cf4SBarry Smith if (nofinalvalue) { 32377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->n,0.0);CHKERRQ(ierr); 324d00d2cf4SBarry Smith } 325fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 326b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 32768369a75SKris Buschelman } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) { 328cd155464SBarry Smith PetscFunctionReturn(0); 329fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 330b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 33144cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 33277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 33344cd7ae7SLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 334aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 33536db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 33677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 33736db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 33877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 33936db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 34077431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 3416831982aSBarry Smith } 34244cd7ae7SLois Curfman McInnes #else 34377431f27SBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);} 34444cd7ae7SLois Curfman McInnes #endif 34544cd7ae7SLois Curfman McInnes } 346b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 34744cd7ae7SLois Curfman McInnes } 348b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 349fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 35097f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 351b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 35297f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&sptr);CHKERRQ(ierr); 353496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 354496be53dSLois Curfman McInnes sptr[i] = nzd+1; 355496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 356496be53dSLois Curfman McInnes if (a->j[j] >= i) { 357aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 35836db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 359496be53dSLois Curfman McInnes #else 360496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 361496be53dSLois Curfman McInnes #endif 362496be53dSLois Curfman McInnes } 363496be53dSLois Curfman McInnes } 364496be53dSLois Curfman McInnes } 3652e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 36677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 3672e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 36877431f27SBarry 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);} 36977431f27SBarry 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);} 37077431f27SBarry 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);} 37177431f27SBarry Smith else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);} 37277431f27SBarry Smith else if (i<m) {ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);} 37377431f27SBarry Smith else {ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);} 374496be53dSLois Curfman McInnes } 375b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 376606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 377496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 378496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 37977431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 380496be53dSLois Curfman McInnes } 381b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 382496be53dSLois Curfman McInnes } 383b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 384496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 385496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 386496be53dSLois Curfman McInnes if (a->j[j] >= i) { 387aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 38836db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 389b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 3906831982aSBarry Smith } 391496be53dSLois Curfman McInnes #else 392b0a32e0cSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);} 393496be53dSLois Curfman McInnes #endif 394496be53dSLois Curfman McInnes } 395496be53dSLois Curfman McInnes } 396b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 397496be53dSLois Curfman McInnes } 398b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 399fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 40097f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 40187828ca2SBarry Smith PetscScalar value; 40202594712SBarry Smith 403b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 40402594712SBarry Smith for (i=0; i<m; i++) { 40502594712SBarry Smith jcnt = 0; 406273d9f13SBarry Smith for (j=0; j<A->n; j++) { 407e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 40802594712SBarry Smith value = a->a[cnt++]; 409e24b481bSBarry Smith jcnt++; 41002594712SBarry Smith } else { 41102594712SBarry Smith value = 0.0; 41202594712SBarry Smith } 413aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 414b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr); 41502594712SBarry Smith #else 416b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr); 41702594712SBarry Smith #endif 41802594712SBarry Smith } 419b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 42002594712SBarry Smith } 421b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 4223a40ed3dSBarry Smith } else { 423b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 42417ab2063SBarry Smith for (i=0; i<m; i++) { 42577431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 426416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 427aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 42836db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 42977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 43036db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 43177431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 4323a40ed3dSBarry Smith } else { 43377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 43417ab2063SBarry Smith } 43517ab2063SBarry Smith #else 43677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 43717ab2063SBarry Smith #endif 43817ab2063SBarry Smith } 439b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 44017ab2063SBarry Smith } 441b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 44217ab2063SBarry Smith } 443b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 4443a40ed3dSBarry Smith PetscFunctionReturn(0); 445416022c9SBarry Smith } 446416022c9SBarry Smith 4474a2ae208SSatish Balay #undef __FUNCT__ 4484a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom" 449dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 450416022c9SBarry Smith { 451480ef9eaSBarry Smith Mat A = (Mat) Aa; 452416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 453dfbe8321SBarry Smith PetscErrorCode ierr; 45497f1f81fSBarry Smith PetscInt i,j,m = A->m,color; 45536db0b34SBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0; 456b0a32e0cSBarry Smith PetscViewer viewer; 457f3ef73ceSBarry Smith PetscViewerFormat format; 458cddf8d76SBarry Smith 4593a40ed3dSBarry Smith PetscFunctionBegin; 460480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 461b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 46219bcc07fSBarry Smith 463b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 464416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 4650513a670SBarry Smith 466fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 4670513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 468b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 469416022c9SBarry Smith for (i=0; i<m; i++) { 470cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 471bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 472bfeeae90SHong Zhang x_l = a->j[j] ; x_r = x_l + 1.0; 473aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 47436db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 475cddf8d76SBarry Smith #else 476cddf8d76SBarry Smith if (a->a[j] >= 0.) continue; 477cddf8d76SBarry Smith #endif 478b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 479cddf8d76SBarry Smith } 480cddf8d76SBarry Smith } 481b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 482cddf8d76SBarry Smith for (i=0; i<m; i++) { 483cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 484bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 485bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 486cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 487b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 488cddf8d76SBarry Smith } 489cddf8d76SBarry Smith } 490b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 491cddf8d76SBarry Smith for (i=0; i<m; i++) { 492cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 493bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 494bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 495aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 49636db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 497cddf8d76SBarry Smith #else 498cddf8d76SBarry Smith if (a->a[j] <= 0.) continue; 499cddf8d76SBarry Smith #endif 500b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 501416022c9SBarry Smith } 502416022c9SBarry Smith } 5030513a670SBarry Smith } else { 5040513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 5050513a670SBarry Smith /* first determine max of all nonzero values */ 50697f1f81fSBarry Smith PetscInt nz = a->nz,count; 507b0a32e0cSBarry Smith PetscDraw popup; 50836db0b34SBarry Smith PetscReal scale; 5090513a670SBarry Smith 5100513a670SBarry Smith for (i=0; i<nz; i++) { 5110513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 5120513a670SBarry Smith } 513b0a32e0cSBarry Smith scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv; 514b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 515b0a32e0cSBarry Smith if (popup) {ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);} 5160513a670SBarry Smith count = 0; 5170513a670SBarry Smith for (i=0; i<m; i++) { 5180513a670SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 519bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 520bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 52197f1f81fSBarry Smith color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count])); 522b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 5230513a670SBarry Smith count++; 5240513a670SBarry Smith } 5250513a670SBarry Smith } 5260513a670SBarry Smith } 527480ef9eaSBarry Smith PetscFunctionReturn(0); 528480ef9eaSBarry Smith } 529cddf8d76SBarry Smith 5304a2ae208SSatish Balay #undef __FUNCT__ 5314a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw" 532dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 533480ef9eaSBarry Smith { 534dfbe8321SBarry Smith PetscErrorCode ierr; 535b0a32e0cSBarry Smith PetscDraw draw; 53636db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 537480ef9eaSBarry Smith PetscTruth isnull; 538480ef9eaSBarry Smith 539480ef9eaSBarry Smith PetscFunctionBegin; 540b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 541b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 542480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 543480ef9eaSBarry Smith 544480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 545273d9f13SBarry Smith xr = A->n; yr = A->m; h = yr/10.0; w = xr/10.0; 546480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 547b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 548b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 549480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 5503a40ed3dSBarry Smith PetscFunctionReturn(0); 551416022c9SBarry Smith } 552416022c9SBarry Smith 5534a2ae208SSatish Balay #undef __FUNCT__ 5544a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ" 555dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 556416022c9SBarry Smith { 557dfbe8321SBarry Smith PetscErrorCode ierr; 55832077d6dSBarry Smith PetscTruth issocket,iascii,isbinary,isdraw; 559416022c9SBarry Smith 5603a40ed3dSBarry Smith PetscFunctionBegin; 561b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr); 56232077d6dSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 563fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr); 564fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr); 565c45a1595SBarry Smith if (iascii) { 5663a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 5674cf18111SSatish Balay #if defined(PETSC_USE_SOCKET_VIEWER) 568c45a1595SBarry Smith } else if (issocket) { 5694cf18111SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 570c45a1595SBarry Smith ierr = PetscViewerSocketPutSparse_Private(viewer,A->m,A->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr); 571c45a1595SBarry Smith #endif 5720f5bd95cSBarry Smith } else if (isbinary) { 5733a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 5740f5bd95cSBarry Smith } else if (isdraw) { 5753a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 5765cd90555SBarry Smith } else { 577958c9bccSBarry Smith SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name); 57817ab2063SBarry Smith } 5794846f1f5SKris Buschelman ierr = MatView_Inode(A,viewer);CHKERRQ(ierr); 5803a40ed3dSBarry Smith PetscFunctionReturn(0); 58117ab2063SBarry Smith } 58219bcc07fSBarry Smith 5834a2ae208SSatish Balay #undef __FUNCT__ 5844a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ" 585dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 58617ab2063SBarry Smith { 587416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 5886849ba73SBarry Smith PetscErrorCode ierr; 58997f1f81fSBarry Smith PetscInt fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 59097f1f81fSBarry Smith PetscInt m = A->m,*ip,N,*ailen = a->ilen,rmax = 0; 59187828ca2SBarry Smith PetscScalar *aa = a->a,*ap; 5923447b6efSHong Zhang PetscReal ratio=0.6; 59317ab2063SBarry Smith 5943a40ed3dSBarry Smith PetscFunctionBegin; 5953a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 59617ab2063SBarry Smith 59743ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 59817ab2063SBarry Smith for (i=1; i<m; i++) { 599416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 60017ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 60194a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 60217ab2063SBarry Smith if (fshift) { 603bfeeae90SHong Zhang ip = aj + ai[i] ; 604bfeeae90SHong Zhang ap = aa + ai[i] ; 60517ab2063SBarry Smith N = ailen[i]; 60617ab2063SBarry Smith for (j=0; j<N; j++) { 60717ab2063SBarry Smith ip[j-fshift] = ip[j]; 60817ab2063SBarry Smith ap[j-fshift] = ap[j]; 60917ab2063SBarry Smith } 61017ab2063SBarry Smith } 61117ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 61217ab2063SBarry Smith } 61317ab2063SBarry Smith if (m) { 61417ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 61517ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 61617ab2063SBarry Smith } 61717ab2063SBarry Smith /* reset ilen and imax for each row */ 61817ab2063SBarry Smith for (i=0; i<m; i++) { 61917ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 62017ab2063SBarry Smith } 621bfeeae90SHong Zhang a->nz = ai[m]; 62217ab2063SBarry Smith 62317ab2063SBarry Smith /* diagonals may have moved, so kill the diagonal pointers */ 624416022c9SBarry Smith if (fshift && a->diag) { 625606d414cSSatish Balay ierr = PetscFree(a->diag);CHKERRQ(ierr); 62652e6d16bSBarry Smith ierr = PetscLogObjectMemory(A,-(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 627416022c9SBarry Smith a->diag = 0; 62817ab2063SBarry Smith } 62963ba0a88SBarry Smith ierr = PetscLogInfo((A,"MatAssemblyEnd_SeqAIJ:Matrix size: %D X %D; storage space: %D unneeded,%D used\n",m,A->n,fshift,a->nz));CHKERRQ(ierr); 63063ba0a88SBarry Smith ierr = PetscLogInfo((A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues() is %D\n",a->reallocs));CHKERRQ(ierr); 63163ba0a88SBarry Smith ierr = PetscLogInfo((A,"MatAssemblyEnd_SeqAIJ:Maximum nonzeros in any row is %D\n",rmax));CHKERRQ(ierr); 632dd5f02e7SSatish Balay a->reallocs = 0; 6334e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift; 63436db0b34SBarry Smith a->rmax = rmax; 6354e220ebcSLois Curfman McInnes 636cb5d8e9eSHong Zhang /* check for zero rows. If found a large number of zero rows, use CompressedRow functions */ 637317fbc4cSHong Zhang ierr = Mat_CheckCompressedRow(A,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 63888e51ccdSHong Zhang A->same_nonzero = PETSC_TRUE; 63971c2f376SKris Buschelman 6404846f1f5SKris Buschelman ierr = MatAssemblyEnd_Inode(A,mode);CHKERRQ(ierr); 6413a40ed3dSBarry Smith PetscFunctionReturn(0); 64217ab2063SBarry Smith } 64317ab2063SBarry Smith 6444a2ae208SSatish Balay #undef __FUNCT__ 6454a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ" 646dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 64717ab2063SBarry Smith { 648416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 649dfbe8321SBarry Smith PetscErrorCode 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" 658dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 65917ab2063SBarry Smith { 660416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 661dfbe8321SBarry Smith PetscErrorCode ierr; 662d5d45c9bSBarry Smith 6633a40ed3dSBarry Smith PetscFunctionBegin; 664aa482453SBarry Smith #if defined(PETSC_USE_LOG) 66577431f27SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->m,A->n,a->nz); 66617ab2063SBarry Smith #endif 6673cbb7e54SHong Zhang if (a->freedata){ 668085a36d4SBarry Smith ierr = MatSeqXAIJFreeAIJ(a->singlemalloc,&a->a,&a->j,&a->i);CHKERRQ(ierr); 6693cbb7e54SHong Zhang } 670c38d4ed2SBarry Smith if (a->row) { 671c38d4ed2SBarry Smith ierr = ISDestroy(a->row);CHKERRQ(ierr); 672c38d4ed2SBarry Smith } 673c38d4ed2SBarry Smith if (a->col) { 674c38d4ed2SBarry Smith ierr = ISDestroy(a->col);CHKERRQ(ierr); 675c38d4ed2SBarry Smith } 676606d414cSSatish Balay if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);} 677ab93d7beSBarry Smith if (a->ilen) {ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);} 678273d9f13SBarry Smith if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);} 679606d414cSSatish Balay if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);} 68082bf6240SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 681606d414cSSatish Balay if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);} 682cc8ba8e1SBarry Smith if (a->coloring) {ierr = ISColoringDestroy(a->coloring);CHKERRQ(ierr);} 683a30b2313SHong Zhang if (a->xtoy) {ierr = PetscFree(a->xtoy);CHKERRQ(ierr);} 684d487561eSHong Zhang if (a->compressedrow.use){ierr = PetscFree(a->compressedrow.i);} 685a30b2313SHong Zhang 6864846f1f5SKris Buschelman ierr = MatDestroy_Inode(A);CHKERRQ(ierr); 6874846f1f5SKris Buschelman 688606d414cSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 689901853e0SKris Buschelman 690901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetColumnIndices_C","",PETSC_NULL);CHKERRQ(ierr); 691901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatStoreValues_C","",PETSC_NULL);CHKERRQ(ierr); 692901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatRetrieveValues_C","",PETSC_NULL);CHKERRQ(ierr); 693901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqsbaij_C","",PETSC_NULL);CHKERRQ(ierr); 694901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqbaij_C","",PETSC_NULL);CHKERRQ(ierr); 695901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatIsTranspose_C","",PETSC_NULL);CHKERRQ(ierr); 696901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocation_C","",PETSC_NULL);CHKERRQ(ierr); 697a1661176SMatthew Knepley ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C","",PETSC_NULL);CHKERRQ(ierr); 698901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatReorderForNonzeroDiagonal_C","",PETSC_NULL);CHKERRQ(ierr); 6993a40ed3dSBarry Smith PetscFunctionReturn(0); 70017ab2063SBarry Smith } 70117ab2063SBarry Smith 7024a2ae208SSatish Balay #undef __FUNCT__ 7034a2ae208SSatish Balay #define __FUNCT__ "MatCompress_SeqAIJ" 704dfbe8321SBarry Smith PetscErrorCode MatCompress_SeqAIJ(Mat A) 70517ab2063SBarry Smith { 7063a40ed3dSBarry Smith PetscFunctionBegin; 7073a40ed3dSBarry Smith PetscFunctionReturn(0); 70817ab2063SBarry Smith } 70917ab2063SBarry Smith 7104a2ae208SSatish Balay #undef __FUNCT__ 7114a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ" 712dfbe8321SBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op) 71317ab2063SBarry Smith { 714416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 7154846f1f5SKris Buschelman PetscErrorCode ierr; 7163a40ed3dSBarry Smith 7173a40ed3dSBarry Smith PetscFunctionBegin; 718a65d3064SKris Buschelman switch (op) { 719a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 720a65d3064SKris Buschelman a->roworiented = PETSC_TRUE; 721a65d3064SKris Buschelman break; 722a65d3064SKris Buschelman case MAT_KEEP_ZEROED_ROWS: 723a65d3064SKris Buschelman a->keepzeroedrows = PETSC_TRUE; 724a65d3064SKris Buschelman break; 725a65d3064SKris Buschelman case MAT_COLUMN_ORIENTED: 726a65d3064SKris Buschelman a->roworiented = PETSC_FALSE; 727a65d3064SKris Buschelman break; 728a65d3064SKris Buschelman case MAT_COLUMNS_SORTED: 729a65d3064SKris Buschelman a->sorted = PETSC_TRUE; 730a65d3064SKris Buschelman break; 731a65d3064SKris Buschelman case MAT_COLUMNS_UNSORTED: 732a65d3064SKris Buschelman a->sorted = PETSC_FALSE; 733a65d3064SKris Buschelman break; 734a65d3064SKris Buschelman case MAT_NO_NEW_NONZERO_LOCATIONS: 735a65d3064SKris Buschelman a->nonew = 1; 736a65d3064SKris Buschelman break; 737a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 738a65d3064SKris Buschelman a->nonew = -1; 739a65d3064SKris Buschelman break; 740a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 741a65d3064SKris Buschelman a->nonew = -2; 742a65d3064SKris Buschelman break; 743a65d3064SKris Buschelman case MAT_YES_NEW_NONZERO_LOCATIONS: 744a65d3064SKris Buschelman a->nonew = 0; 745a65d3064SKris Buschelman break; 746a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 747a65d3064SKris Buschelman a->ignorezeroentries = PETSC_TRUE; 748a65d3064SKris Buschelman break; 749d487561eSHong Zhang case MAT_USE_COMPRESSEDROW: 750d487561eSHong Zhang a->compressedrow.use = PETSC_TRUE; 751d487561eSHong Zhang break; 752d487561eSHong Zhang case MAT_DO_NOT_USE_COMPRESSEDROW: 753d487561eSHong Zhang a->compressedrow.use = PETSC_FALSE; 754d487561eSHong Zhang break; 755a65d3064SKris Buschelman case MAT_ROWS_SORTED: 756a65d3064SKris Buschelman case MAT_ROWS_UNSORTED: 757a65d3064SKris Buschelman case MAT_YES_NEW_DIAGONALS: 758a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 759a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 76063ba0a88SBarry Smith ierr = PetscLogInfo((A,"MatSetOption_SeqAIJ:Option ignored\n"));CHKERRQ(ierr); 761a65d3064SKris Buschelman break; 762a65d3064SKris Buschelman case MAT_NO_NEW_DIAGONALS: 76329bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS"); 764a65d3064SKris Buschelman default: 76571c2f376SKris Buschelman break; 766a65d3064SKris Buschelman } 7674846f1f5SKris Buschelman ierr = MatSetOption_Inode(A,op);CHKERRQ(ierr); 7683a40ed3dSBarry Smith PetscFunctionReturn(0); 76917ab2063SBarry Smith } 77017ab2063SBarry Smith 7714a2ae208SSatish Balay #undef __FUNCT__ 7724a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ" 773dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 77417ab2063SBarry Smith { 775416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 7766849ba73SBarry Smith PetscErrorCode ierr; 77797f1f81fSBarry Smith PetscInt i,j,n; 77887828ca2SBarry Smith PetscScalar *x,zero = 0.0; 77917ab2063SBarry Smith 7803a40ed3dSBarry Smith PetscFunctionBegin; 7812dcb1b2aSMatthew Knepley ierr = VecSet(v,zero);CHKERRQ(ierr); 7821ebc52fbSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 78336db0b34SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 784273d9f13SBarry Smith if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 785273d9f13SBarry Smith for (i=0; i<A->m; i++) { 786bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 787bfeeae90SHong Zhang if (a->j[j] == i) { 788416022c9SBarry Smith x[i] = a->a[j]; 78917ab2063SBarry Smith break; 79017ab2063SBarry Smith } 79117ab2063SBarry Smith } 79217ab2063SBarry Smith } 7931ebc52fbSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 7943a40ed3dSBarry Smith PetscFunctionReturn(0); 79517ab2063SBarry Smith } 79617ab2063SBarry Smith 7974a2ae208SSatish Balay #undef __FUNCT__ 7984a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ" 799dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 80017ab2063SBarry Smith { 801416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 8025c897100SBarry Smith PetscScalar *x,*y; 803dfbe8321SBarry Smith PetscErrorCode ierr; 80497f1f81fSBarry Smith PetscInt m = A->m; 8055c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 8065c897100SBarry Smith PetscScalar *v,alpha; 8077b2bb3b9SHong Zhang PetscInt n,i,*idx,*ii,*ridx=PETSC_NULL; 8083447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 8094eb6d288SHong Zhang PetscTruth usecprow = cprow.use; 8105c897100SBarry Smith #endif 81117ab2063SBarry Smith 8123a40ed3dSBarry Smith PetscFunctionBegin; 8132e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 8141ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 8151ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 8165c897100SBarry Smith 8175c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 818bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 8195c897100SBarry Smith #else 8203447b6efSHong Zhang if (usecprow){ 8213447b6efSHong Zhang m = cprow.nrows; 8223447b6efSHong Zhang ii = cprow.i; 8237b2bb3b9SHong Zhang ridx = cprow.rindex; 8243447b6efSHong Zhang } else { 8253447b6efSHong Zhang ii = a->i; 8263447b6efSHong Zhang } 82717ab2063SBarry Smith for (i=0; i<m; i++) { 8283447b6efSHong Zhang idx = a->j + ii[i] ; 8293447b6efSHong Zhang v = a->a + ii[i] ; 8303447b6efSHong Zhang n = ii[i+1] - ii[i]; 8313447b6efSHong Zhang if (usecprow){ 8327b2bb3b9SHong Zhang alpha = x[ridx[i]]; 8333447b6efSHong Zhang } else { 83417ab2063SBarry Smith alpha = x[i]; 8353447b6efSHong Zhang } 83617ab2063SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 83717ab2063SBarry Smith } 8385c897100SBarry Smith #endif 839efee365bSSatish Balay ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr); 8401ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 8411ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 8423a40ed3dSBarry Smith PetscFunctionReturn(0); 84317ab2063SBarry Smith } 84417ab2063SBarry Smith 8454a2ae208SSatish Balay #undef __FUNCT__ 8465c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ" 847dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 8485c897100SBarry Smith { 8498d5b0100SBarry Smith PetscScalar zero = 0.0; 850dfbe8321SBarry Smith PetscErrorCode ierr; 8515c897100SBarry Smith 8525c897100SBarry Smith PetscFunctionBegin; 8532dcb1b2aSMatthew Knepley ierr = VecSet(yy,zero);CHKERRQ(ierr); 8545c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 8555c897100SBarry Smith PetscFunctionReturn(0); 8565c897100SBarry Smith } 8575c897100SBarry Smith 8585c897100SBarry Smith 8595c897100SBarry Smith #undef __FUNCT__ 8604a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ" 861dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 86217ab2063SBarry Smith { 863416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 86497952fefSHong Zhang PetscScalar *x,*y,*aa; 865dfbe8321SBarry Smith PetscErrorCode ierr; 86697952fefSHong Zhang PetscInt m=A->m,*aj,*ii; 867*f2e71c43SSatish Balay PetscInt n,i,j,*ridx=PETSC_NULL; 868362ced78SSatish Balay PetscScalar sum; 86997952fefSHong Zhang PetscTruth usecprow=a->compressedrow.use; 870*f2e71c43SSatish Balay #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 871*f2e71c43SSatish Balay PetscInt jrow; 872e36a17ebSSatish Balay #endif 87317ab2063SBarry Smith 874b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 87597952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 876fee21e36SBarry Smith #endif 877fee21e36SBarry Smith 8783a40ed3dSBarry Smith PetscFunctionBegin; 8791ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 8801ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 88197952fefSHong Zhang aj = a->j; 88297952fefSHong Zhang aa = a->a; 883416022c9SBarry Smith ii = a->i; 8844eb6d288SHong Zhang if (usecprow){ /* use compressed row format */ 88597952fefSHong Zhang m = a->compressedrow.nrows; 88697952fefSHong Zhang ii = a->compressedrow.i; 88797952fefSHong Zhang ridx = a->compressedrow.rindex; 88897952fefSHong Zhang for (i=0; i<m; i++){ 88997952fefSHong Zhang n = ii[i+1] - ii[i]; 89097952fefSHong Zhang aj = a->j + ii[i]; 89197952fefSHong Zhang aa = a->a + ii[i]; 89297952fefSHong Zhang sum = 0.0; 89397952fefSHong Zhang for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; 89497952fefSHong Zhang y[*ridx++] = sum; 89597952fefSHong Zhang } 89697952fefSHong Zhang } else { /* do not use compressed row format */ 897b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 898b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 899b05257ddSBarry Smith #else 90017ab2063SBarry Smith for (i=0; i<m; i++) { 9019ea0dfa2SSatish Balay jrow = ii[i]; 9029ea0dfa2SSatish Balay n = ii[i+1] - jrow; 90317ab2063SBarry Smith sum = 0.0; 9049ea0dfa2SSatish Balay for (j=0; j<n; j++) { 90597952fefSHong Zhang sum += aa[jrow]*x[aj[jrow]]; jrow++; 9069ea0dfa2SSatish Balay } 90717ab2063SBarry Smith y[i] = sum; 90817ab2063SBarry Smith } 9098d195f9aSBarry Smith #endif 910b05257ddSBarry Smith } 911efee365bSSatish Balay ierr = PetscLogFlops(2*a->nz - m);CHKERRQ(ierr); 9121ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 9131ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 9143a40ed3dSBarry Smith PetscFunctionReturn(0); 91517ab2063SBarry Smith } 91617ab2063SBarry Smith 9174a2ae208SSatish Balay #undef __FUNCT__ 9184a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ" 919dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 92017ab2063SBarry Smith { 921416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 92297952fefSHong Zhang PetscScalar *x,*y,*z,*aa; 923dfbe8321SBarry Smith PetscErrorCode ierr; 92497952fefSHong Zhang PetscInt m = A->m,*aj,*ii; 925aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 92697952fefSHong Zhang PetscInt n,i,jrow,j,*ridx=PETSC_NULL; 927362ced78SSatish Balay PetscScalar sum; 92897952fefSHong Zhang PetscTruth usecprow=a->compressedrow.use; 929e36a17ebSSatish Balay #endif 9309ea0dfa2SSatish Balay 9313a40ed3dSBarry Smith PetscFunctionBegin; 9321ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 9331ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 9342e8a6d31SBarry Smith if (zz != yy) { 9351ebc52fbSHong Zhang ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 9362e8a6d31SBarry Smith } else { 9372e8a6d31SBarry Smith z = y; 9382e8a6d31SBarry Smith } 939bfeeae90SHong Zhang 94097952fefSHong Zhang aj = a->j; 94197952fefSHong Zhang aa = a->a; 942cddf8d76SBarry Smith ii = a->i; 943aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 94497952fefSHong Zhang fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 94502ab625aSSatish Balay #else 9464eb6d288SHong Zhang if (usecprow){ /* use compressed row format */ 9474eb6d288SHong Zhang if (zz != yy){ 9484eb6d288SHong Zhang ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 9494eb6d288SHong Zhang } 95097952fefSHong Zhang m = a->compressedrow.nrows; 95197952fefSHong Zhang ii = a->compressedrow.i; 95297952fefSHong Zhang ridx = a->compressedrow.rindex; 95397952fefSHong Zhang for (i=0; i<m; i++){ 95497952fefSHong Zhang n = ii[i+1] - ii[i]; 95597952fefSHong Zhang aj = a->j + ii[i]; 95697952fefSHong Zhang aa = a->a + ii[i]; 95797952fefSHong Zhang sum = y[*ridx]; 95897952fefSHong Zhang for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; 95997952fefSHong Zhang z[*ridx++] = sum; 96097952fefSHong Zhang } 96197952fefSHong Zhang } else { /* do not use compressed row format */ 96217ab2063SBarry Smith for (i=0; i<m; i++) { 9639ea0dfa2SSatish Balay jrow = ii[i]; 9649ea0dfa2SSatish Balay n = ii[i+1] - jrow; 96517ab2063SBarry Smith sum = y[i]; 9669ea0dfa2SSatish Balay for (j=0; j<n; j++) { 96797952fefSHong Zhang sum += aa[jrow]*x[aj[jrow]]; jrow++; 9689ea0dfa2SSatish Balay } 96917ab2063SBarry Smith z[i] = sum; 97017ab2063SBarry Smith } 97197952fefSHong Zhang } 97202ab625aSSatish Balay #endif 973efee365bSSatish Balay ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr); 9741ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 9751ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 9762e8a6d31SBarry Smith if (zz != yy) { 9771ebc52fbSHong Zhang ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 9782e8a6d31SBarry Smith } 9793a40ed3dSBarry Smith PetscFunctionReturn(0); 98017ab2063SBarry Smith } 98117ab2063SBarry Smith 98217ab2063SBarry Smith /* 98317ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 98417ab2063SBarry Smith */ 9854a2ae208SSatish Balay #undef __FUNCT__ 9864a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ" 987dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 98817ab2063SBarry Smith { 989416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 9906849ba73SBarry Smith PetscErrorCode ierr; 99197f1f81fSBarry Smith PetscInt i,j,*diag,m = A->m; 99217ab2063SBarry Smith 9933a40ed3dSBarry Smith PetscFunctionBegin; 994f1e2ffcdSBarry Smith if (a->diag) PetscFunctionReturn(0); 995f1e2ffcdSBarry Smith 99697f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&diag);CHKERRQ(ierr); 99752e6d16bSBarry Smith ierr = PetscLogObjectMemory(A,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 998273d9f13SBarry Smith for (i=0; i<A->m; i++) { 99935b0346bSBarry Smith diag[i] = a->i[i+1]; 1000bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1001bfeeae90SHong Zhang if (a->j[j] == i) { 1002bfeeae90SHong Zhang diag[i] = j; 100317ab2063SBarry Smith break; 100417ab2063SBarry Smith } 100517ab2063SBarry Smith } 100617ab2063SBarry Smith } 1007416022c9SBarry Smith a->diag = diag; 10083a40ed3dSBarry Smith PetscFunctionReturn(0); 100917ab2063SBarry Smith } 101017ab2063SBarry Smith 1011be5855fcSBarry Smith /* 1012be5855fcSBarry Smith Checks for missing diagonals 1013be5855fcSBarry Smith */ 10144a2ae208SSatish Balay #undef __FUNCT__ 10154a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ" 1016dfbe8321SBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A) 1017be5855fcSBarry Smith { 1018be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 10196849ba73SBarry Smith PetscErrorCode ierr; 102097f1f81fSBarry Smith PetscInt *diag,*jj = a->j,i; 1021be5855fcSBarry Smith 1022be5855fcSBarry Smith PetscFunctionBegin; 1023f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1024f1e2ffcdSBarry Smith diag = a->diag; 1025273d9f13SBarry Smith for (i=0; i<A->m; i++) { 1026bfeeae90SHong Zhang if (jj[diag[i]] != i) { 102777431f27SBarry Smith SETERRQ1(PETSC_ERR_PLIB,"Matrix is missing diagonal number %D",i); 1028be5855fcSBarry Smith } 1029be5855fcSBarry Smith } 1030be5855fcSBarry Smith PetscFunctionReturn(0); 1031be5855fcSBarry Smith } 1032be5855fcSBarry Smith 10334a2ae208SSatish Balay #undef __FUNCT__ 10344a2ae208SSatish Balay #define __FUNCT__ "MatRelax_SeqAIJ" 103597f1f81fSBarry Smith PetscErrorCode MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 103617ab2063SBarry Smith { 1037416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1038beeb8507SBarry Smith PetscScalar *x,d,*xs,sum,*t,scale,*idiag=0,*mdiag; 1039beeb8507SBarry Smith const PetscScalar *v = a->a, *b, *bs,*xb, *ts; 1040dfbe8321SBarry Smith PetscErrorCode ierr; 104197f1f81fSBarry Smith PetscInt n = A->n,m = A->m,i; 104297f1f81fSBarry Smith const PetscInt *idx,*diag; 104317ab2063SBarry Smith 10443a40ed3dSBarry Smith PetscFunctionBegin; 1045b965ef7fSBarry Smith its = its*lits; 104677431f27SBarry Smith if (its <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D and local its %D both positive",its,lits); 104791723122SBarry Smith 1048ed480e8bSBarry Smith if (!a->diag) {ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);} 1049ed480e8bSBarry Smith diag = a->diag; 1050ed480e8bSBarry Smith if (!a->idiag) { 1051ed480e8bSBarry Smith ierr = PetscMalloc(3*m*sizeof(PetscScalar),&a->idiag);CHKERRQ(ierr); 1052ed480e8bSBarry Smith a->ssor = a->idiag + m; 1053ed480e8bSBarry Smith mdiag = a->ssor + m; 1054ed480e8bSBarry Smith 1055ed480e8bSBarry Smith v = a->a; 1056ed480e8bSBarry Smith 1057ed480e8bSBarry Smith /* this is wrong when fshift omega changes each iteration */ 1058958c9bccSBarry Smith if (omega == 1.0 && !fshift) { 1059ed480e8bSBarry Smith for (i=0; i<m; i++) { 1060ed480e8bSBarry Smith mdiag[i] = v[diag[i]]; 1061ed480e8bSBarry Smith a->idiag[i] = 1.0/v[diag[i]]; 1062ed480e8bSBarry Smith } 1063efee365bSSatish Balay ierr = PetscLogFlops(m);CHKERRQ(ierr); 1064ed480e8bSBarry Smith } else { 1065ed480e8bSBarry Smith for (i=0; i<m; i++) { 1066ed480e8bSBarry Smith mdiag[i] = v[diag[i]]; 1067beeb8507SBarry Smith a->idiag[i] = omega/(fshift + v[diag[i]]); 1068ed480e8bSBarry Smith } 1069efee365bSSatish Balay ierr = PetscLogFlops(2*m);CHKERRQ(ierr); 1070beeb8507SBarry Smith } 1071ed480e8bSBarry Smith } 1072ed480e8bSBarry Smith t = a->ssor; 1073ed480e8bSBarry Smith idiag = a->idiag; 1074ed480e8bSBarry Smith mdiag = a->idiag + 2*m; 1075ed480e8bSBarry Smith 10761ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 1077fb2e594dSBarry Smith if (xx != bb) { 10781ebc52fbSHong Zhang ierr = VecGetArray(bb,(PetscScalar**)&b);CHKERRQ(ierr); 1079fb2e594dSBarry Smith } else { 1080fb2e594dSBarry Smith b = x; 1081fb2e594dSBarry Smith } 1082fb2e594dSBarry Smith 1083ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 1084ed480e8bSBarry Smith xs = x; 108517ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 108617ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1087ed480e8bSBarry Smith bs = b; 108817ab2063SBarry Smith for (i=0; i<m; i++) { 1089ed480e8bSBarry Smith d = fshift + a->a[diag[i]]; 1090416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1091ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1092ed480e8bSBarry Smith v = a->a + diag[i] + 1; 109317ab2063SBarry Smith sum = b[i]*d/omega; 109417ab2063SBarry Smith SPARSEDENSEDOT(sum,bs,v,idx,n); 109517ab2063SBarry Smith x[i] = sum; 109617ab2063SBarry Smith } 10971ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 10981ebc52fbSHong Zhang if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);} 1099efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 11003a40ed3dSBarry Smith PetscFunctionReturn(0); 110117ab2063SBarry Smith } 1102c783ea89SBarry Smith 1103ed480e8bSBarry Smith 1104fc3d8934SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1105fc3d8934SBarry Smith U is upper triangular, E is diagonal; This routine applies 1106fc3d8934SBarry Smith 1107fc3d8934SBarry Smith (L + E)^{-1} A (U + E)^{-1} 1108fc3d8934SBarry Smith 1109fc3d8934SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 1110fc3d8934SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 111148af12d7SBarry Smith is the relaxation factor. 1112fc3d8934SBarry Smith */ 1113fc3d8934SBarry Smith 111448af12d7SBarry Smith if (flag == SOR_APPLY_LOWER) { 111529bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 11163a40ed3dSBarry Smith } else if (flag & SOR_EISENSTAT) { 111717ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 111817ab2063SBarry Smith U is upper triangular, E is diagonal; This routine applies 111917ab2063SBarry Smith 112017ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 112117ab2063SBarry Smith 112217ab2063SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 112317ab2063SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 112417ab2063SBarry Smith is the relaxation factor. 112517ab2063SBarry Smith */ 112617ab2063SBarry Smith scale = (2.0/omega) - 1.0; 112717ab2063SBarry Smith 112817ab2063SBarry Smith /* x = (E + U)^{-1} b */ 112917ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1130416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1131ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1132ed480e8bSBarry Smith v = a->a + diag[i] + 1; 113317ab2063SBarry Smith sum = b[i]; 113417ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1135ed480e8bSBarry Smith x[i] = sum*idiag[i]; 113617ab2063SBarry Smith } 113717ab2063SBarry Smith 113817ab2063SBarry Smith /* t = b - (2*E - D)x */ 1139416022c9SBarry Smith v = a->a; 1140ed480e8bSBarry Smith for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; } 114117ab2063SBarry Smith 114217ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1143ed480e8bSBarry Smith ts = t; 1144416022c9SBarry Smith diag = a->diag; 114517ab2063SBarry Smith for (i=0; i<m; i++) { 1146416022c9SBarry Smith n = diag[i] - a->i[i]; 1147ed480e8bSBarry Smith idx = a->j + a->i[i]; 1148ed480e8bSBarry Smith v = a->a + a->i[i]; 114917ab2063SBarry Smith sum = t[i]; 115017ab2063SBarry Smith SPARSEDENSEMDOT(sum,ts,v,idx,n); 1151ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1152733d66baSBarry Smith /* x = x + t */ 1153733d66baSBarry Smith x[i] += t[i]; 115417ab2063SBarry Smith } 115517ab2063SBarry Smith 1156efee365bSSatish Balay ierr = PetscLogFlops(6*m-1 + 2*a->nz);CHKERRQ(ierr); 11571ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 11581ebc52fbSHong Zhang if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);} 11593a40ed3dSBarry Smith PetscFunctionReturn(0); 116017ab2063SBarry Smith } 116117ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 116217ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 116377d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 116497f1f81fSBarry Smith fortranrelaxaijforwardzero_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,idiag,a->a,(void*)b); 116577d8c4bbSBarry Smith #else 116617ab2063SBarry Smith for (i=0; i<m; i++) { 1167416022c9SBarry Smith n = diag[i] - a->i[i]; 1168ed480e8bSBarry Smith idx = a->j + a->i[i]; 1169ed480e8bSBarry Smith v = a->a + a->i[i]; 117017ab2063SBarry Smith sum = b[i]; 117117ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1172ed480e8bSBarry Smith x[i] = sum*idiag[i]; 117317ab2063SBarry Smith } 117477d8c4bbSBarry Smith #endif 117517ab2063SBarry Smith xb = x; 1176efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 11773a40ed3dSBarry Smith } else xb = b; 117817ab2063SBarry Smith if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) && 117917ab2063SBarry Smith (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) { 118017ab2063SBarry Smith for (i=0; i<m; i++) { 1181ed480e8bSBarry Smith x[i] *= mdiag[i]; 118217ab2063SBarry Smith } 1183efee365bSSatish Balay ierr = PetscLogFlops(m);CHKERRQ(ierr); 118417ab2063SBarry Smith } 118517ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 118677d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 118797f1f81fSBarry Smith fortranrelaxaijbackwardzero_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,idiag,a->a,(void*)xb); 118877d8c4bbSBarry Smith #else 118917ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1190416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1191ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1192ed480e8bSBarry Smith v = a->a + diag[i] + 1; 119317ab2063SBarry Smith sum = xb[i]; 119417ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1195ed480e8bSBarry Smith x[i] = sum*idiag[i]; 119617ab2063SBarry Smith } 119777d8c4bbSBarry Smith #endif 1198efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 119917ab2063SBarry Smith } 120017ab2063SBarry Smith its--; 120117ab2063SBarry Smith } 120217ab2063SBarry Smith while (its--) { 120317ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 120477d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 120597f1f81fSBarry Smith fortranrelaxaijforward_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,a->a,(void*)b); 120677d8c4bbSBarry Smith #else 120717ab2063SBarry Smith for (i=0; i<m; i++) { 1208ed480e8bSBarry Smith d = fshift + a->a[diag[i]]; 1209416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1210ed480e8bSBarry Smith idx = a->j + a->i[i]; 1211ed480e8bSBarry Smith v = a->a + a->i[i]; 121217ab2063SBarry Smith sum = b[i]; 121317ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1214ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 121517ab2063SBarry Smith } 121677d8c4bbSBarry Smith #endif 1217efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 121817ab2063SBarry Smith } 121917ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 122077d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 122197f1f81fSBarry Smith fortranrelaxaijbackward_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,a->a,(void*)b); 122277d8c4bbSBarry Smith #else 122317ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1224ed480e8bSBarry Smith d = fshift + a->a[diag[i]]; 1225416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1226ed480e8bSBarry Smith idx = a->j + a->i[i]; 1227ed480e8bSBarry Smith v = a->a + a->i[i]; 122817ab2063SBarry Smith sum = b[i]; 122917ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1230ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 123117ab2063SBarry Smith } 123277d8c4bbSBarry Smith #endif 1233efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 123417ab2063SBarry Smith } 123517ab2063SBarry Smith } 12361ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 12371ebc52fbSHong Zhang if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);} 12383a40ed3dSBarry Smith PetscFunctionReturn(0); 123917ab2063SBarry Smith } 124017ab2063SBarry Smith 12414a2ae208SSatish Balay #undef __FUNCT__ 12424a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ" 1243dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 124417ab2063SBarry Smith { 1245416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 12464e220ebcSLois Curfman McInnes 12473a40ed3dSBarry Smith PetscFunctionBegin; 1248273d9f13SBarry Smith info->rows_global = (double)A->m; 1249273d9f13SBarry Smith info->columns_global = (double)A->n; 1250273d9f13SBarry Smith info->rows_local = (double)A->m; 1251273d9f13SBarry Smith info->columns_local = (double)A->n; 12524e220ebcSLois Curfman McInnes info->block_size = 1.0; 12534e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 12544e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 12554e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 12564e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 12574e220ebcSLois Curfman McInnes info->mallocs = (double)a->reallocs; 12584e220ebcSLois Curfman McInnes info->memory = A->mem; 12594e220ebcSLois Curfman McInnes if (A->factor) { 12604e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 12614e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 12624e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 12634e220ebcSLois Curfman McInnes } else { 12644e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 12654e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 12664e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 12674e220ebcSLois Curfman McInnes } 12683a40ed3dSBarry Smith PetscFunctionReturn(0); 126917ab2063SBarry Smith } 127017ab2063SBarry Smith 12714a2ae208SSatish Balay #undef __FUNCT__ 12724a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ" 1273f4df32b1SMatthew Knepley PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag) 127417ab2063SBarry Smith { 1275416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1276f4df32b1SMatthew Knepley PetscInt i,m = A->m - 1; 12776849ba73SBarry Smith PetscErrorCode ierr; 127817ab2063SBarry Smith 12793a40ed3dSBarry Smith PetscFunctionBegin; 1280f1e2ffcdSBarry Smith if (a->keepzeroedrows) { 1281f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 128277431f27SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1283bfeeae90SHong Zhang ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 1284f1e2ffcdSBarry Smith } 1285f4df32b1SMatthew Knepley if (diag != 0.0) { 1286f1e2ffcdSBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1287f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1288f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1289f4df32b1SMatthew Knepley a->a[a->diag[rows[i]]] = diag; 1290f1e2ffcdSBarry Smith } 1291f1e2ffcdSBarry Smith } 129288e51ccdSHong Zhang A->same_nonzero = PETSC_TRUE; 1293f1e2ffcdSBarry Smith } else { 1294f4df32b1SMatthew Knepley if (diag != 0.0) { 129517ab2063SBarry Smith for (i=0; i<N; i++) { 129677431f27SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 12977ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1298416022c9SBarry Smith a->ilen[rows[i]] = 1; 1299f4df32b1SMatthew Knepley a->a[a->i[rows[i]]] = diag; 1300bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 13017ae801bdSBarry Smith } else { /* in case row was completely empty */ 1302f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 130317ab2063SBarry Smith } 130417ab2063SBarry Smith } 13053a40ed3dSBarry Smith } else { 130617ab2063SBarry Smith for (i=0; i<N; i++) { 130777431f27SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1308416022c9SBarry Smith a->ilen[rows[i]] = 0; 130917ab2063SBarry Smith } 131017ab2063SBarry Smith } 131188e51ccdSHong Zhang A->same_nonzero = PETSC_FALSE; 1312f1e2ffcdSBarry Smith } 131343a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13143a40ed3dSBarry Smith PetscFunctionReturn(0); 131517ab2063SBarry Smith } 131617ab2063SBarry Smith 13174a2ae208SSatish Balay #undef __FUNCT__ 13184a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ" 131997f1f81fSBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 132017ab2063SBarry Smith { 1321416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 132297f1f81fSBarry Smith PetscInt *itmp; 132317ab2063SBarry Smith 13243a40ed3dSBarry Smith PetscFunctionBegin; 132577431f27SBarry Smith if (row < 0 || row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 132617ab2063SBarry Smith 1327416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1328bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 132917ab2063SBarry Smith if (idx) { 1330bfeeae90SHong Zhang itmp = a->j + a->i[row]; 1331bfeeae90SHong Zhang if (*nz) { 13324e093b46SBarry Smith *idx = itmp; 133317ab2063SBarry Smith } 133417ab2063SBarry Smith else *idx = 0; 133517ab2063SBarry Smith } 13363a40ed3dSBarry Smith PetscFunctionReturn(0); 133717ab2063SBarry Smith } 133817ab2063SBarry Smith 1339bfeeae90SHong Zhang /* remove this function? */ 13404a2ae208SSatish Balay #undef __FUNCT__ 13414a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ" 134297f1f81fSBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 134317ab2063SBarry Smith { 13443a40ed3dSBarry Smith PetscFunctionBegin; 13453a40ed3dSBarry Smith PetscFunctionReturn(0); 134617ab2063SBarry Smith } 134717ab2063SBarry Smith 13484a2ae208SSatish Balay #undef __FUNCT__ 13494a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ" 1350dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 135117ab2063SBarry Smith { 1352416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 135387828ca2SBarry Smith PetscScalar *v = a->a; 135436db0b34SBarry Smith PetscReal sum = 0.0; 13556849ba73SBarry Smith PetscErrorCode ierr; 135697f1f81fSBarry Smith PetscInt i,j; 135717ab2063SBarry Smith 13583a40ed3dSBarry Smith PetscFunctionBegin; 135917ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1360416022c9SBarry Smith for (i=0; i<a->nz; i++) { 1361aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 136236db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 136317ab2063SBarry Smith #else 136417ab2063SBarry Smith sum += (*v)*(*v); v++; 136517ab2063SBarry Smith #endif 136617ab2063SBarry Smith } 1367064f8208SBarry Smith *nrm = sqrt(sum); 13683a40ed3dSBarry Smith } else if (type == NORM_1) { 136936db0b34SBarry Smith PetscReal *tmp; 137097f1f81fSBarry Smith PetscInt *jj = a->j; 1371b0a32e0cSBarry Smith ierr = PetscMalloc((A->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr); 1372273d9f13SBarry Smith ierr = PetscMemzero(tmp,A->n*sizeof(PetscReal));CHKERRQ(ierr); 1373064f8208SBarry Smith *nrm = 0.0; 1374416022c9SBarry Smith for (j=0; j<a->nz; j++) { 1375bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 137617ab2063SBarry Smith } 1377273d9f13SBarry Smith for (j=0; j<A->n; j++) { 1378064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 137917ab2063SBarry Smith } 1380606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 13813a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1382064f8208SBarry Smith *nrm = 0.0; 1383273d9f13SBarry Smith for (j=0; j<A->m; j++) { 1384bfeeae90SHong Zhang v = a->a + a->i[j]; 138517ab2063SBarry Smith sum = 0.0; 1386416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 1387cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 138817ab2063SBarry Smith } 1389064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 139017ab2063SBarry Smith } 13913a40ed3dSBarry Smith } else { 139229bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"No support for two norm"); 139317ab2063SBarry Smith } 13943a40ed3dSBarry Smith PetscFunctionReturn(0); 139517ab2063SBarry Smith } 139617ab2063SBarry Smith 13974a2ae208SSatish Balay #undef __FUNCT__ 13984a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ" 1399dfbe8321SBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,Mat *B) 140017ab2063SBarry Smith { 1401416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1402416022c9SBarry Smith Mat C; 14036849ba73SBarry Smith PetscErrorCode ierr; 140497f1f81fSBarry Smith PetscInt i,*aj = a->j,*ai = a->i,m = A->m,len,*col; 140587828ca2SBarry Smith PetscScalar *array = a->a; 140617ab2063SBarry Smith 14073a40ed3dSBarry Smith PetscFunctionBegin; 1408273d9f13SBarry Smith if (!B && m != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Square matrix only for in-place"); 140997f1f81fSBarry Smith ierr = PetscMalloc((1+A->n)*sizeof(PetscInt),&col);CHKERRQ(ierr); 141097f1f81fSBarry Smith ierr = PetscMemzero(col,(1+A->n)*sizeof(PetscInt));CHKERRQ(ierr); 1411bfeeae90SHong Zhang 1412bfeeae90SHong Zhang for (i=0; i<ai[m]; i++) col[aj[i]] += 1; 1413f69a0ea3SMatthew Knepley ierr = MatCreate(A->comm,&C);CHKERRQ(ierr); 1414f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,A->n,m,A->n,m);CHKERRQ(ierr); 1415f204ca49SKris Buschelman ierr = MatSetType(C,A->type_name);CHKERRQ(ierr); 1416ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr); 1417606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 141817ab2063SBarry Smith for (i=0; i<m; i++) { 141917ab2063SBarry Smith len = ai[i+1]-ai[i]; 1420416022c9SBarry Smith ierr = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 1421b9b97703SBarry Smith array += len; 1422b9b97703SBarry Smith aj += len; 142317ab2063SBarry Smith } 142417ab2063SBarry Smith 14256d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14266d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 142717ab2063SBarry Smith 1428f1e2ffcdSBarry Smith if (B) { 1429416022c9SBarry Smith *B = C; 143017ab2063SBarry Smith } else { 1431273d9f13SBarry Smith ierr = MatHeaderCopy(A,C);CHKERRQ(ierr); 143217ab2063SBarry Smith } 14333a40ed3dSBarry Smith PetscFunctionReturn(0); 143417ab2063SBarry Smith } 143517ab2063SBarry Smith 1436cd0d46ebSvictorle EXTERN_C_BEGIN 1437cd0d46ebSvictorle #undef __FUNCT__ 14385fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ" 1439be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscTruth *f) 1440cd0d46ebSvictorle { 1441cd0d46ebSvictorle Mat_SeqAIJ *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data; 144297f1f81fSBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; PetscScalar *va,*vb; 14436849ba73SBarry Smith PetscErrorCode ierr; 144497f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 1445cd0d46ebSvictorle 1446cd0d46ebSvictorle PetscFunctionBegin; 1447cd0d46ebSvictorle bij = (Mat_SeqAIJ *) B->data; 1448cd0d46ebSvictorle 1449cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 1450cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 14515485867bSBarry Smith if (ma!=nb || na!=mb){ 14525485867bSBarry Smith *f = PETSC_FALSE; 14535485867bSBarry Smith PetscFunctionReturn(0); 14545485867bSBarry Smith } 1455cd0d46ebSvictorle aii = aij->i; bii = bij->i; 1456cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 1457cd0d46ebSvictorle va = aij->a; vb = bij->a; 145897f1f81fSBarry Smith ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr); 145997f1f81fSBarry Smith ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr); 1460cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 1461cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 1462cd0d46ebSvictorle 1463cd0d46ebSvictorle *f = PETSC_TRUE; 1464cd0d46ebSvictorle for (i=0; i<ma; i++) { 1465cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 146697f1f81fSBarry Smith PetscInt idc,idr; 14675485867bSBarry Smith PetscScalar vc,vr; 1468cd0d46ebSvictorle /* column/row index/value */ 14695485867bSBarry Smith idc = adx[aptr[i]]; 14705485867bSBarry Smith idr = bdx[bptr[idc]]; 14715485867bSBarry Smith vc = va[aptr[i]]; 14725485867bSBarry Smith vr = vb[bptr[idc]]; 14735485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 14745485867bSBarry Smith *f = PETSC_FALSE; 14755485867bSBarry Smith goto done; 1476cd0d46ebSvictorle } else { 14775485867bSBarry Smith aptr[i]++; 14785485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 1479cd0d46ebSvictorle } 1480cd0d46ebSvictorle } 1481cd0d46ebSvictorle } 1482cd0d46ebSvictorle done: 1483cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 14843aeef889SHong Zhang if (B) { 14853aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 14863aeef889SHong Zhang } 1487cd0d46ebSvictorle PetscFunctionReturn(0); 1488cd0d46ebSvictorle } 1489cd0d46ebSvictorle EXTERN_C_END 1490cd0d46ebSvictorle 14919e29f15eSvictorle #undef __FUNCT__ 14929e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ" 1493dfbe8321SBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscTruth *f) 14949e29f15eSvictorle { 1495dfbe8321SBarry Smith PetscErrorCode ierr; 14969e29f15eSvictorle PetscFunctionBegin; 14975485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 14989e29f15eSvictorle PetscFunctionReturn(0); 14999e29f15eSvictorle } 15009e29f15eSvictorle 15014a2ae208SSatish Balay #undef __FUNCT__ 15024a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ" 1503dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 150417ab2063SBarry Smith { 1505416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 150687828ca2SBarry Smith PetscScalar *l,*r,x,*v; 1507dfbe8321SBarry Smith PetscErrorCode ierr; 150897f1f81fSBarry Smith PetscInt i,j,m = A->m,n = A->n,M,nz = a->nz,*jj; 150917ab2063SBarry Smith 15103a40ed3dSBarry Smith PetscFunctionBegin; 151117ab2063SBarry Smith if (ll) { 15123ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 15133ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 1514e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 1515273d9f13SBarry Smith if (m != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 15161ebc52fbSHong Zhang ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 1517416022c9SBarry Smith v = a->a; 151817ab2063SBarry Smith for (i=0; i<m; i++) { 151917ab2063SBarry Smith x = l[i]; 1520416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 152117ab2063SBarry Smith for (j=0; j<M; j++) { (*v++) *= x;} 152217ab2063SBarry Smith } 15231ebc52fbSHong Zhang ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 1524efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 152517ab2063SBarry Smith } 152617ab2063SBarry Smith if (rr) { 1527e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 1528273d9f13SBarry Smith if (n != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 15291ebc52fbSHong Zhang ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 1530416022c9SBarry Smith v = a->a; jj = a->j; 153117ab2063SBarry Smith for (i=0; i<nz; i++) { 1532bfeeae90SHong Zhang (*v++) *= r[*jj++]; 153317ab2063SBarry Smith } 15341ebc52fbSHong Zhang ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 1535efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 153617ab2063SBarry Smith } 15373a40ed3dSBarry Smith PetscFunctionReturn(0); 153817ab2063SBarry Smith } 153917ab2063SBarry Smith 15404a2ae208SSatish Balay #undef __FUNCT__ 15414a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ" 154297f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 154317ab2063SBarry Smith { 1544db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 15456849ba73SBarry Smith PetscErrorCode ierr; 154697f1f81fSBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->n,*lens; 154797f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 154897f1f81fSBarry Smith PetscInt *irow,*icol,nrows,ncols; 154997f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 155087828ca2SBarry Smith PetscScalar *a_new,*mat_a; 1551416022c9SBarry Smith Mat C; 1552fee21e36SBarry Smith PetscTruth stride; 155317ab2063SBarry Smith 15543a40ed3dSBarry Smith PetscFunctionBegin; 1555d64ed03dSBarry Smith ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr); 155629bbc08cSBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted"); 1557d64ed03dSBarry Smith ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr); 155829bbc08cSBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted"); 155999141d43SSatish Balay 156017ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 1561b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 1562b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 156317ab2063SBarry Smith 1564fee21e36SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 1565fee21e36SBarry Smith ierr = ISStride(iscol,&stride);CHKERRQ(ierr); 1566fee21e36SBarry Smith if (stride && step == 1) { 156702834360SBarry Smith /* special case of contiguous rows */ 156897f1f81fSBarry Smith ierr = PetscMalloc((2*nrows+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 156931ebf83bSSatish Balay starts = lens + nrows; 157002834360SBarry Smith /* loop over new rows determining lens and starting points */ 157102834360SBarry Smith for (i=0; i<nrows; i++) { 1572bfeeae90SHong Zhang kstart = ai[irow[i]]; 1573a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 157402834360SBarry Smith for (k=kstart; k<kend; k++) { 1575bfeeae90SHong Zhang if (aj[k] >= first) { 157602834360SBarry Smith starts[i] = k; 157702834360SBarry Smith break; 157802834360SBarry Smith } 157902834360SBarry Smith } 1580a2744918SBarry Smith sum = 0; 158102834360SBarry Smith while (k < kend) { 1582bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 1583a2744918SBarry Smith sum++; 158402834360SBarry Smith } 1585a2744918SBarry Smith lens[i] = sum; 158602834360SBarry Smith } 158702834360SBarry Smith /* create submatrix */ 1588cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 158997f1f81fSBarry Smith PetscInt n_cols,n_rows; 159008480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 159129bbc08cSBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 1592d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 159308480c60SBarry Smith C = *B; 15943a40ed3dSBarry Smith } else { 1595f69a0ea3SMatthew Knepley ierr = MatCreate(A->comm,&C);CHKERRQ(ierr); 1596f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 1597e2d9671bSKris Buschelman ierr = MatSetType(C,A->type_name);CHKERRQ(ierr); 1598ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 159908480c60SBarry Smith } 1600db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 1601db02288aSLois Curfman McInnes 160202834360SBarry Smith /* loop over rows inserting into submatrix */ 1603db02288aSLois Curfman McInnes a_new = c->a; 1604db02288aSLois Curfman McInnes j_new = c->j; 1605db02288aSLois Curfman McInnes i_new = c->i; 1606bfeeae90SHong Zhang 160702834360SBarry Smith for (i=0; i<nrows; i++) { 1608a2744918SBarry Smith ii = starts[i]; 1609a2744918SBarry Smith lensi = lens[i]; 1610a2744918SBarry Smith for (k=0; k<lensi; k++) { 1611a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 161202834360SBarry Smith } 161387828ca2SBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr); 1614a2744918SBarry Smith a_new += lensi; 1615a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 1616a2744918SBarry Smith c->ilen[i] = lensi; 161702834360SBarry Smith } 1618606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 16193a40ed3dSBarry Smith } else { 162002834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 162197f1f81fSBarry Smith ierr = PetscMalloc((1+oldcols)*sizeof(PetscInt),&smap);CHKERRQ(ierr); 1622bfeeae90SHong Zhang 162397f1f81fSBarry Smith ierr = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 162497f1f81fSBarry Smith ierr = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr); 162517ab2063SBarry Smith for (i=0; i<ncols; i++) smap[icol[i]] = i+1; 162602834360SBarry Smith /* determine lens of each row */ 162702834360SBarry Smith for (i=0; i<nrows; i++) { 1628bfeeae90SHong Zhang kstart = ai[irow[i]]; 162902834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 163002834360SBarry Smith lens[i] = 0; 163102834360SBarry Smith for (k=kstart; k<kend; k++) { 1632bfeeae90SHong Zhang if (smap[aj[k]]) { 163302834360SBarry Smith lens[i]++; 163402834360SBarry Smith } 163502834360SBarry Smith } 163602834360SBarry Smith } 163717ab2063SBarry Smith /* Create and fill new matrix */ 1638a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 16390f5bd95cSBarry Smith PetscTruth equal; 16400f5bd95cSBarry Smith 164199141d43SSatish Balay c = (Mat_SeqAIJ *)((*B)->data); 1642273d9f13SBarry Smith if ((*B)->m != nrows || (*B)->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 164397f1f81fSBarry Smith ierr = PetscMemcmp(c->ilen,lens,(*B)->m*sizeof(PetscInt),&equal);CHKERRQ(ierr); 16440f5bd95cSBarry Smith if (!equal) { 164529bbc08cSBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 164699141d43SSatish Balay } 164797f1f81fSBarry Smith ierr = PetscMemzero(c->ilen,(*B)->m*sizeof(PetscInt));CHKERRQ(ierr); 164808480c60SBarry Smith C = *B; 16493a40ed3dSBarry Smith } else { 1650f69a0ea3SMatthew Knepley ierr = MatCreate(A->comm,&C);CHKERRQ(ierr); 1651f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 1652e2d9671bSKris Buschelman ierr = MatSetType(C,A->type_name);CHKERRQ(ierr); 1653ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 165408480c60SBarry Smith } 165599141d43SSatish Balay c = (Mat_SeqAIJ *)(C->data); 165617ab2063SBarry Smith for (i=0; i<nrows; i++) { 165799141d43SSatish Balay row = irow[i]; 1658bfeeae90SHong Zhang kstart = ai[row]; 165999141d43SSatish Balay kend = kstart + a->ilen[row]; 1660bfeeae90SHong Zhang mat_i = c->i[i]; 166199141d43SSatish Balay mat_j = c->j + mat_i; 166299141d43SSatish Balay mat_a = c->a + mat_i; 166399141d43SSatish Balay mat_ilen = c->ilen + i; 166417ab2063SBarry Smith for (k=kstart; k<kend; k++) { 1665bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 1666ed480e8bSBarry Smith *mat_j++ = tcol - 1; 166799141d43SSatish Balay *mat_a++ = a->a[k]; 166899141d43SSatish Balay (*mat_ilen)++; 166999141d43SSatish Balay 167017ab2063SBarry Smith } 167117ab2063SBarry Smith } 167217ab2063SBarry Smith } 167302834360SBarry Smith /* Free work space */ 167402834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 1675606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 1676606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 167702834360SBarry Smith } 16786d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16796d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 168017ab2063SBarry Smith 168117ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 1682416022c9SBarry Smith *B = C; 16833a40ed3dSBarry Smith PetscFunctionReturn(0); 168417ab2063SBarry Smith } 168517ab2063SBarry Smith 1686a871dcd8SBarry Smith /* 1687a871dcd8SBarry Smith */ 16884a2ae208SSatish Balay #undef __FUNCT__ 16894a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ" 1690dfbe8321SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatFactorInfo *info) 1691a871dcd8SBarry Smith { 169263b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 1693dfbe8321SBarry Smith PetscErrorCode ierr; 169463b91edcSBarry Smith Mat outA; 1695b8a78c4aSBarry Smith PetscTruth row_identity,col_identity; 169663b91edcSBarry Smith 16973a40ed3dSBarry Smith PetscFunctionBegin; 1698d3d32019SBarry Smith if (info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 1699b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 1700b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 1701b8a78c4aSBarry Smith if (!row_identity || !col_identity) { 1702634064b4SBarry Smith SETERRQ(PETSC_ERR_ARG_WRONG,"Row and column permutations must be identity for in-place ILU"); 1703b8a78c4aSBarry Smith } 1704a871dcd8SBarry Smith 170563b91edcSBarry Smith outA = inA; 170663b91edcSBarry Smith inA->factor = FACTOR_LU; 170763b91edcSBarry Smith a->row = row; 170863b91edcSBarry Smith a->col = col; 1709c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1710c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 171163b91edcSBarry Smith 171236db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 1713b9b97703SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */ 17144c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 171552e6d16bSBarry Smith ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr); 1716f0ec6fceSSatish Balay 171794a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 171887828ca2SBarry Smith ierr = PetscMalloc((inA->m+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr); 171994a9d846SBarry Smith } 172063b91edcSBarry Smith 172108480c60SBarry Smith if (!a->diag) { 1722f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 172363b91edcSBarry Smith } 1724af281ebdSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ(inA,info,&outA);CHKERRQ(ierr); 17253a40ed3dSBarry Smith PetscFunctionReturn(0); 1726a871dcd8SBarry Smith } 1727a871dcd8SBarry Smith 1728d9eff348SSatish Balay #include "petscblaslapack.h" 17294a2ae208SSatish Balay #undef __FUNCT__ 17304a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ" 1731f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 1732f0b747eeSBarry Smith { 1733f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 17344ce68768SBarry Smith PetscBLASInt bnz = (PetscBLASInt)a->nz,one = 1; 1735f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 1736efee365bSSatish Balay PetscErrorCode ierr; 1737efee365bSSatish Balay 17383a40ed3dSBarry Smith 17393a40ed3dSBarry Smith PetscFunctionBegin; 1740f4df32b1SMatthew Knepley BLASscal_(&bnz,&oalpha,a->a,&one); 1741efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 17423a40ed3dSBarry Smith PetscFunctionReturn(0); 1743f0b747eeSBarry Smith } 1744f0b747eeSBarry Smith 17454a2ae208SSatish Balay #undef __FUNCT__ 17464a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ" 174797f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 1748cddf8d76SBarry Smith { 1749dfbe8321SBarry Smith PetscErrorCode ierr; 175097f1f81fSBarry Smith PetscInt i; 1751cddf8d76SBarry Smith 17523a40ed3dSBarry Smith PetscFunctionBegin; 1753cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 1754b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr); 1755cddf8d76SBarry Smith } 1756cddf8d76SBarry Smith 1757cddf8d76SBarry Smith for (i=0; i<n; i++) { 17586a6a5d1dSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 1759cddf8d76SBarry Smith } 17603a40ed3dSBarry Smith PetscFunctionReturn(0); 1761cddf8d76SBarry Smith } 1762cddf8d76SBarry Smith 17634a2ae208SSatish Balay #undef __FUNCT__ 17644a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ" 176597f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 17664dcbc457SBarry Smith { 1767e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17686849ba73SBarry Smith PetscErrorCode ierr; 176997f1f81fSBarry Smith PetscInt row,i,j,k,l,m,n,*idx,*nidx,isz,val; 177097f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 1771f1af5d2fSBarry Smith PetscBT table; 1772bbd702dbSSatish Balay 17733a40ed3dSBarry Smith PetscFunctionBegin; 1774273d9f13SBarry Smith m = A->m; 1775e4d965acSSatish Balay ai = a->i; 1776bfeeae90SHong Zhang aj = a->j; 17778a047759SSatish Balay 1778a45adfd6SMatthew Knepley if (ov < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 177906763907SSatish Balay 178097f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr); 17816831982aSBarry Smith ierr = PetscBTCreate(m,table);CHKERRQ(ierr); 178206763907SSatish Balay 1783e4d965acSSatish Balay for (i=0; i<is_max; i++) { 1784b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 1785e4d965acSSatish Balay isz = 0; 17866831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 1787e4d965acSSatish Balay 1788e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 17894dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 1790b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 1791e4d965acSSatish Balay 1792dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 1793e4d965acSSatish Balay for (j=0; j<n ; ++j){ 1794f1af5d2fSBarry Smith if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];} 17954dcbc457SBarry Smith } 179606763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 179706763907SSatish Balay ierr = ISDestroy(is[i]);CHKERRQ(ierr); 1798e4d965acSSatish Balay 179904a348a9SBarry Smith k = 0; 180004a348a9SBarry Smith for (j=0; j<ov; j++){ /* for each overlap */ 180104a348a9SBarry Smith n = isz; 180206763907SSatish Balay for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */ 1803e4d965acSSatish Balay row = nidx[k]; 1804e4d965acSSatish Balay start = ai[row]; 1805e4d965acSSatish Balay end = ai[row+1]; 180604a348a9SBarry Smith for (l = start; l<end ; l++){ 1807efb16452SHong Zhang val = aj[l] ; 1808f1af5d2fSBarry Smith if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;} 1809e4d965acSSatish Balay } 1810e4d965acSSatish Balay } 1811e4d965acSSatish Balay } 1812029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr); 1813e4d965acSSatish Balay } 18146831982aSBarry Smith ierr = PetscBTDestroy(table);CHKERRQ(ierr); 1815606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 18163a40ed3dSBarry Smith PetscFunctionReturn(0); 18174dcbc457SBarry Smith } 181817ab2063SBarry Smith 18190513a670SBarry Smith /* -------------------------------------------------------------- */ 18204a2ae208SSatish Balay #undef __FUNCT__ 18214a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ" 1822dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 18230513a670SBarry Smith { 18240513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18256849ba73SBarry Smith PetscErrorCode ierr; 182697f1f81fSBarry Smith PetscInt i,nz,m = A->m,n = A->n,*col; 182797f1f81fSBarry Smith PetscInt *row,*cnew,j,*lens; 182856cd22aeSBarry Smith IS icolp,irowp; 182997f1f81fSBarry Smith PetscInt *cwork; 183032ec9ce4SBarry Smith PetscScalar *vwork; 18310513a670SBarry Smith 18323a40ed3dSBarry Smith PetscFunctionBegin; 18334c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 183456cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 18354c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 183656cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 18370513a670SBarry Smith 18380513a670SBarry Smith /* determine lengths of permuted rows */ 183997f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 18400513a670SBarry Smith for (i=0; i<m; i++) { 18410513a670SBarry Smith lens[row[i]] = a->i[i+1] - a->i[i]; 18420513a670SBarry Smith } 1843f69a0ea3SMatthew Knepley ierr = MatCreate(A->comm,B);CHKERRQ(ierr); 1844f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 1845f204ca49SKris Buschelman ierr = MatSetType(*B,A->type_name);CHKERRQ(ierr); 1846ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 1847606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 18480513a670SBarry Smith 184997f1f81fSBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr); 18500513a670SBarry Smith for (i=0; i<m; i++) { 185132ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 18520513a670SBarry Smith for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];} 1853cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 185432ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 18550513a670SBarry Smith } 1856606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 18573c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 18580513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18590513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 186056cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 186156cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 186256cd22aeSBarry Smith ierr = ISDestroy(irowp);CHKERRQ(ierr); 186356cd22aeSBarry Smith ierr = ISDestroy(icolp);CHKERRQ(ierr); 18643a40ed3dSBarry Smith PetscFunctionReturn(0); 18650513a670SBarry Smith } 18660513a670SBarry Smith 18674a2ae208SSatish Balay #undef __FUNCT__ 18684a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqAIJ" 1869dfbe8321SBarry Smith PetscErrorCode MatPrintHelp_SeqAIJ(Mat A) 1870682d7d0cSBarry Smith { 1871c38d4ed2SBarry Smith static PetscTruth called = PETSC_FALSE; 1872682d7d0cSBarry Smith MPI_Comm comm = A->comm; 1873dfbe8321SBarry Smith PetscErrorCode ierr; 1874682d7d0cSBarry Smith 18753a40ed3dSBarry Smith PetscFunctionBegin; 18764846f1f5SKris Buschelman ierr = MatPrintHelp_Inode(A);CHKERRQ(ierr); 1877c38d4ed2SBarry Smith if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE; 1878d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr); 1879d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr); 1880d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr); 188173e7a558SHong Zhang ierr = (*PetscHelpPrintf)(comm," -mat_no_compressedrow: Do not use compressedrow\n");CHKERRQ(ierr); 18823a40ed3dSBarry Smith PetscFunctionReturn(0); 1883682d7d0cSBarry Smith } 188497304618SKris Buschelman 18854a2ae208SSatish Balay #undef __FUNCT__ 18864a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ" 1887dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 1888cb5b572fSBarry Smith { 1889dfbe8321SBarry Smith PetscErrorCode ierr; 1890cb5b572fSBarry Smith 1891cb5b572fSBarry Smith PetscFunctionBegin; 189233f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 189333f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 1894be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1895be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 1896be6bf707SBarry Smith 1897bfeeae90SHong Zhang if (a->i[A->m] != b->i[B->m]) { 1898634064b4SBarry Smith SETERRQ(PETSC_ERR_ARG_INCOMP,"Number of nonzeros in two matrices are different"); 1899cb5b572fSBarry Smith } 1900bfeeae90SHong Zhang ierr = PetscMemcpy(b->a,a->a,(a->i[A->m])*sizeof(PetscScalar));CHKERRQ(ierr); 1901cb5b572fSBarry Smith } else { 1902cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1903cb5b572fSBarry Smith } 1904cb5b572fSBarry Smith PetscFunctionReturn(0); 1905cb5b572fSBarry Smith } 1906cb5b572fSBarry Smith 19074a2ae208SSatish Balay #undef __FUNCT__ 19084a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ" 1909dfbe8321SBarry Smith PetscErrorCode MatSetUpPreallocation_SeqAIJ(Mat A) 1910273d9f13SBarry Smith { 1911dfbe8321SBarry Smith PetscErrorCode ierr; 1912273d9f13SBarry Smith 1913273d9f13SBarry Smith PetscFunctionBegin; 1914ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 1915273d9f13SBarry Smith PetscFunctionReturn(0); 1916273d9f13SBarry Smith } 1917273d9f13SBarry Smith 19184a2ae208SSatish Balay #undef __FUNCT__ 19194a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ" 1920dfbe8321SBarry Smith PetscErrorCode MatGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 19216c0721eeSBarry Smith { 19226c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 19236c0721eeSBarry Smith PetscFunctionBegin; 19246c0721eeSBarry Smith *array = a->a; 19256c0721eeSBarry Smith PetscFunctionReturn(0); 19266c0721eeSBarry Smith } 19276c0721eeSBarry Smith 19284a2ae208SSatish Balay #undef __FUNCT__ 19294a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ" 1930dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 19316c0721eeSBarry Smith { 19326c0721eeSBarry Smith PetscFunctionBegin; 19336c0721eeSBarry Smith PetscFunctionReturn(0); 19346c0721eeSBarry Smith } 1935273d9f13SBarry Smith 1936ee4f033dSBarry Smith #undef __FUNCT__ 1937ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ" 1938dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 1939ee4f033dSBarry Smith { 19406849ba73SBarry Smith PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f; 19416849ba73SBarry Smith PetscErrorCode ierr; 194297f1f81fSBarry Smith PetscInt k,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2; 1943efb30889SBarry Smith PetscScalar dx,*y,*xx,*w3_array; 194487828ca2SBarry Smith PetscScalar *vscale_array; 1945ee4f033dSBarry Smith PetscReal epsilon = coloring->error_rel,umin = coloring->umin; 1946ee4f033dSBarry Smith Vec w1,w2,w3; 1947ee4f033dSBarry Smith void *fctx = coloring->fctx; 1948ee4f033dSBarry Smith PetscTruth flg; 1949ee4f033dSBarry Smith 1950ee4f033dSBarry Smith PetscFunctionBegin; 1951ee4f033dSBarry Smith if (!coloring->w1) { 1952ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr); 195352e6d16bSBarry Smith ierr = PetscLogObjectParent(coloring,coloring->w1);CHKERRQ(ierr); 1954ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr); 195552e6d16bSBarry Smith ierr = PetscLogObjectParent(coloring,coloring->w2);CHKERRQ(ierr); 1956ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr); 195752e6d16bSBarry Smith ierr = PetscLogObjectParent(coloring,coloring->w3);CHKERRQ(ierr); 1958ee4f033dSBarry Smith } 1959ee4f033dSBarry Smith w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3; 1960ee4f033dSBarry Smith 1961ee4f033dSBarry Smith ierr = MatSetUnfactored(J);CHKERRQ(ierr); 1962e82a3eeeSBarry Smith ierr = PetscOptionsHasName(coloring->prefix,"-mat_fd_coloring_dont_rezero",&flg);CHKERRQ(ierr); 1963ee4f033dSBarry Smith if (flg) { 196463ba0a88SBarry Smith ierr = PetscLogInfo((coloring,"MatFDColoringApply_SeqAIJ: Not calling MatZeroEntries()\n"));CHKERRQ(ierr); 1965ee4f033dSBarry Smith } else { 19660b9b6f31SBarry Smith PetscTruth assembled; 19670b9b6f31SBarry Smith ierr = MatAssembled(J,&assembled);CHKERRQ(ierr); 19680b9b6f31SBarry Smith if (assembled) { 1969ee4f033dSBarry Smith ierr = MatZeroEntries(J);CHKERRQ(ierr); 1970ee4f033dSBarry Smith } 19710b9b6f31SBarry Smith } 1972ee4f033dSBarry Smith 1973ee4f033dSBarry Smith ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr); 1974ee4f033dSBarry Smith ierr = VecGetSize(x1,&N);CHKERRQ(ierr); 1975ee4f033dSBarry Smith 1976ee4f033dSBarry Smith /* 1977ee4f033dSBarry Smith This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets 1978ee4f033dSBarry Smith coloring->F for the coarser grids from the finest 1979ee4f033dSBarry Smith */ 1980ee4f033dSBarry Smith if (coloring->F) { 1981ee4f033dSBarry Smith ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr); 1982ee4f033dSBarry Smith ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr); 1983ee4f033dSBarry Smith if (m1 != m2) { 1984ee4f033dSBarry Smith coloring->F = 0; 1985ee4f033dSBarry Smith } 1986ee4f033dSBarry Smith } 1987ee4f033dSBarry Smith 1988ee4f033dSBarry Smith if (coloring->F) { 1989ee4f033dSBarry Smith w1 = coloring->F; 1990ee4f033dSBarry Smith coloring->F = 0; 1991ee4f033dSBarry Smith } else { 199266f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 1993ee4f033dSBarry Smith ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr); 199466f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 1995ee4f033dSBarry Smith } 1996ee4f033dSBarry Smith 1997ee4f033dSBarry Smith /* 1998ee4f033dSBarry Smith Compute all the scale factors and share with other processors 1999ee4f033dSBarry Smith */ 20001ebc52fbSHong Zhang ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start; 20011ebc52fbSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start; 2002ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 2003ee4f033dSBarry Smith /* 2004ee4f033dSBarry Smith Loop over each column associated with color adding the 2005ee4f033dSBarry Smith perturbation to the vector w3. 2006ee4f033dSBarry Smith */ 2007ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 2008ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 2009ee4f033dSBarry Smith dx = xx[col]; 2010ee4f033dSBarry Smith if (dx == 0.0) dx = 1.0; 2011ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 2012ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 2013ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 2014ee4f033dSBarry Smith #else 2015ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2016ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2017ee4f033dSBarry Smith #endif 2018ee4f033dSBarry Smith dx *= epsilon; 2019ee4f033dSBarry Smith vscale_array[col] = 1.0/dx; 2020ee4f033dSBarry Smith } 2021ee4f033dSBarry Smith } 20221ebc52fbSHong Zhang vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2023ee4f033dSBarry Smith ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2024ee4f033dSBarry Smith ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2025ee4f033dSBarry Smith 2026ee4f033dSBarry Smith /* ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD); 2027ee4f033dSBarry Smith ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/ 2028ee4f033dSBarry Smith 2029ee4f033dSBarry Smith if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow; 2030ee4f033dSBarry Smith else vscaleforrow = coloring->columnsforrow; 2031ee4f033dSBarry Smith 20321ebc52fbSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2033ee4f033dSBarry Smith /* 2034ee4f033dSBarry Smith Loop over each color 2035ee4f033dSBarry Smith */ 2036ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 203749b058dcSBarry Smith coloring->currentcolor = k; 2038ee4f033dSBarry Smith ierr = VecCopy(x1,w3);CHKERRQ(ierr); 20391ebc52fbSHong Zhang ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start; 2040ee4f033dSBarry Smith /* 2041ee4f033dSBarry Smith Loop over each column associated with color adding the 2042ee4f033dSBarry Smith perturbation to the vector w3. 2043ee4f033dSBarry Smith */ 2044ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 2045ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 2046ee4f033dSBarry Smith dx = xx[col]; 20475b8514ebSBarry Smith if (dx == 0.0) dx = 1.0; 2048ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 2049ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 2050ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 2051ee4f033dSBarry Smith #else 2052ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2053ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2054ee4f033dSBarry Smith #endif 2055ee4f033dSBarry Smith dx *= epsilon; 2056634064b4SBarry Smith if (!PetscAbsScalar(dx)) SETERRQ(PETSC_ERR_PLIB,"Computed 0 differencing parameter"); 2057ee4f033dSBarry Smith w3_array[col] += dx; 2058ee4f033dSBarry Smith } 20591ebc52fbSHong Zhang w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr); 2060ee4f033dSBarry Smith 2061ee4f033dSBarry Smith /* 2062ee4f033dSBarry Smith Evaluate function at x1 + dx (here dx is a vector of perturbations) 2063ee4f033dSBarry Smith */ 2064ee4f033dSBarry Smith 206566f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2066ee4f033dSBarry Smith ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr); 206766f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2068efb30889SBarry Smith ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr); 2069ee4f033dSBarry Smith 2070ee4f033dSBarry Smith /* 2071ee4f033dSBarry Smith Loop over rows of vector, putting results into Jacobian matrix 2072ee4f033dSBarry Smith */ 20731ebc52fbSHong Zhang ierr = VecGetArray(w2,&y);CHKERRQ(ierr); 2074ee4f033dSBarry Smith for (l=0; l<coloring->nrows[k]; l++) { 2075ee4f033dSBarry Smith row = coloring->rows[k][l]; 2076ee4f033dSBarry Smith col = coloring->columnsforrow[k][l]; 2077ee4f033dSBarry Smith y[row] *= vscale_array[vscaleforrow[k][l]]; 2078ee4f033dSBarry Smith srow = row + start; 2079ee4f033dSBarry Smith ierr = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr); 2080ee4f033dSBarry Smith } 20811ebc52fbSHong Zhang ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr); 2082ee4f033dSBarry Smith } 208349b058dcSBarry Smith coloring->currentcolor = k; 20841ebc52fbSHong Zhang ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 20851ebc52fbSHong Zhang xx = xx + start; ierr = VecRestoreArray(x1,&xx);CHKERRQ(ierr); 2086ee4f033dSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2087ee4f033dSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2088ee4f033dSBarry Smith PetscFunctionReturn(0); 2089ee4f033dSBarry Smith } 2090ee4f033dSBarry Smith 2091ac90fabeSBarry Smith #include "petscblaslapack.h" 2092ac90fabeSBarry Smith #undef __FUNCT__ 2093ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ" 2094f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 2095ac90fabeSBarry Smith { 2096dfbe8321SBarry Smith PetscErrorCode ierr; 209797f1f81fSBarry Smith PetscInt i; 2098ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data; 20994ce68768SBarry Smith PetscBLASInt one=1,bnz = (PetscBLASInt)x->nz; 2100ac90fabeSBarry Smith 2101ac90fabeSBarry Smith PetscFunctionBegin; 2102ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 2103f4df32b1SMatthew Knepley PetscScalar alpha = a; 2104f4df32b1SMatthew Knepley BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one); 2105c537a176SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 2106a30b2313SHong Zhang if (y->xtoy && y->XtoY != X) { 2107a30b2313SHong Zhang ierr = PetscFree(y->xtoy);CHKERRQ(ierr); 2108a30b2313SHong Zhang ierr = MatDestroy(y->XtoY);CHKERRQ(ierr); 2109a30b2313SHong Zhang } 2110a30b2313SHong Zhang if (!y->xtoy) { /* get xtoy */ 211124f910e3SHong Zhang ierr = MatAXPYGetxtoy_Private(X->m,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr); 2112a30b2313SHong Zhang y->XtoY = X; 2113c537a176SHong Zhang } 2114f4df32b1SMatthew Knepley for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]); 211563ba0a88SBarry Smith ierr = PetscLogInfo((0,"MatAXPY_SeqAIJ: ratio of nnz(X)/nnz(Y): %d/%d = %g\n",x->nz,y->nz,(PetscReal)(x->nz)/y->nz));CHKERRQ(ierr); 2116ac90fabeSBarry Smith } else { 2117f4df32b1SMatthew Knepley ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 2118ac90fabeSBarry Smith } 2119ac90fabeSBarry Smith PetscFunctionReturn(0); 2120ac90fabeSBarry Smith } 2121ac90fabeSBarry Smith 2122521d7252SBarry Smith #undef __FUNCT__ 2123521d7252SBarry Smith #define __FUNCT__ "MatSetBlockSize_SeqAIJ" 2124521d7252SBarry Smith PetscErrorCode MatSetBlockSize_SeqAIJ(Mat A,PetscInt bs) 2125521d7252SBarry Smith { 2126521d7252SBarry Smith PetscFunctionBegin; 2127521d7252SBarry Smith PetscFunctionReturn(0); 2128521d7252SBarry Smith } 2129521d7252SBarry Smith 2130354c94deSBarry Smith #undef __FUNCT__ 2131354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ" 2132354c94deSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatConjugate_SeqAIJ(Mat mat) 2133354c94deSBarry Smith { 2134354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 2135354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2136354c94deSBarry Smith PetscInt i,nz; 2137354c94deSBarry Smith PetscScalar *a; 2138354c94deSBarry Smith 2139354c94deSBarry Smith PetscFunctionBegin; 2140354c94deSBarry Smith nz = aij->nz; 2141354c94deSBarry Smith a = aij->a; 2142354c94deSBarry Smith for (i=0; i<nz; i++) { 2143354c94deSBarry Smith a[i] = PetscConj(a[i]); 2144354c94deSBarry Smith } 2145354c94deSBarry Smith #else 2146354c94deSBarry Smith PetscFunctionBegin; 2147354c94deSBarry Smith #endif 2148354c94deSBarry Smith PetscFunctionReturn(0); 2149354c94deSBarry Smith } 2150354c94deSBarry Smith 2151e34fafa9SBarry Smith #undef __FUNCT__ 2152e34fafa9SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ" 2153e34fafa9SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v) 2154e34fafa9SBarry Smith { 2155e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2156e34fafa9SBarry Smith PetscErrorCode ierr; 2157e34fafa9SBarry Smith PetscInt i,j,m = A->m,*ai,*aj,ncols,n; 2158e34fafa9SBarry Smith PetscReal atmp; 2159e34fafa9SBarry Smith PetscScalar *x,zero = 0.0; 2160e34fafa9SBarry Smith MatScalar *aa; 2161e34fafa9SBarry Smith 2162e34fafa9SBarry Smith PetscFunctionBegin; 2163e34fafa9SBarry Smith if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2164e34fafa9SBarry Smith aa = a->a; 2165e34fafa9SBarry Smith ai = a->i; 2166e34fafa9SBarry Smith aj = a->j; 2167e34fafa9SBarry Smith 216843e18e04SHong Zhang ierr = VecSet(v,zero);CHKERRQ(ierr); 2169e34fafa9SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2170e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2171e34fafa9SBarry Smith if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2172e34fafa9SBarry Smith for (i=0; i<m; i++) { 2173e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 2174e34fafa9SBarry Smith for (j=0; j<ncols; j++){ 2175e34fafa9SBarry Smith atmp = PetscAbsScalar(*aa); aa++; 2176e34fafa9SBarry Smith if (PetscAbsScalar(x[i]) < atmp) x[i] = atmp; 2177e34fafa9SBarry Smith aj++; 2178e34fafa9SBarry Smith } 2179e34fafa9SBarry Smith } 2180e34fafa9SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2181e34fafa9SBarry Smith PetscFunctionReturn(0); 2182e34fafa9SBarry Smith } 2183e34fafa9SBarry Smith 2184682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 21850a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ, 2186cb5b572fSBarry Smith MatGetRow_SeqAIJ, 2187cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 2188cb5b572fSBarry Smith MatMult_SeqAIJ, 218997304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 21907c922b88SBarry Smith MatMultTranspose_SeqAIJ, 21917c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 2192cb5b572fSBarry Smith MatSolve_SeqAIJ, 2193cb5b572fSBarry Smith MatSolveAdd_SeqAIJ, 21947c922b88SBarry Smith MatSolveTranspose_SeqAIJ, 219597304618SKris Buschelman /*10*/ MatSolveTransposeAdd_SeqAIJ, 2196cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 2197cb5b572fSBarry Smith 0, 219817ab2063SBarry Smith MatRelax_SeqAIJ, 219917ab2063SBarry Smith MatTranspose_SeqAIJ, 220097304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ, 2201cb5b572fSBarry Smith MatEqual_SeqAIJ, 2202cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 2203cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 2204cb5b572fSBarry Smith MatNorm_SeqAIJ, 220597304618SKris Buschelman /*20*/ 0, 2206cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 220717ab2063SBarry Smith MatCompress_SeqAIJ, 2208cb5b572fSBarry Smith MatSetOption_SeqAIJ, 2209cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 221097304618SKris Buschelman /*25*/ MatZeroRows_SeqAIJ, 2211cb5b572fSBarry Smith MatLUFactorSymbolic_SeqAIJ, 2212cb5b572fSBarry Smith MatLUFactorNumeric_SeqAIJ, 2213f76d2b81SHong Zhang MatCholeskyFactorSymbolic_SeqAIJ, 2214a6175056SHong Zhang MatCholeskyFactorNumeric_SeqAIJ, 221597304618SKris Buschelman /*30*/ MatSetUpPreallocation_SeqAIJ, 2216cb5b572fSBarry Smith MatILUFactorSymbolic_SeqAIJ, 2217861ba921SHong Zhang MatICCFactorSymbolic_SeqAIJ, 22186c0721eeSBarry Smith MatGetArray_SeqAIJ, 22196c0721eeSBarry Smith MatRestoreArray_SeqAIJ, 222097304618SKris Buschelman /*35*/ MatDuplicate_SeqAIJ, 2221cb5b572fSBarry Smith 0, 2222cb5b572fSBarry Smith 0, 2223cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 2224cb5b572fSBarry Smith 0, 222597304618SKris Buschelman /*40*/ MatAXPY_SeqAIJ, 2226cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 2227cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 2228cb5b572fSBarry Smith MatGetValues_SeqAIJ, 2229cb5b572fSBarry Smith MatCopy_SeqAIJ, 223097304618SKris Buschelman /*45*/ MatPrintHelp_SeqAIJ, 2231cb5b572fSBarry Smith MatScale_SeqAIJ, 2232cb5b572fSBarry Smith 0, 223379299369SBarry Smith MatDiagonalSet_SeqAIJ, 22346945ee14SBarry Smith MatILUDTFactor_SeqAIJ, 2235521d7252SBarry Smith /*50*/ MatSetBlockSize_SeqAIJ, 22363b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 22373b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 22383b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 2239a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 224097304618SKris Buschelman /*55*/ MatFDColoringCreate_SeqAIJ, 2241b9617806SBarry Smith 0, 22420513a670SBarry Smith 0, 2243cda55fadSBarry Smith MatPermute_SeqAIJ, 2244cda55fadSBarry Smith 0, 224597304618SKris Buschelman /*60*/ 0, 2246b9b97703SBarry Smith MatDestroy_SeqAIJ, 2247b9b97703SBarry Smith MatView_SeqAIJ, 22488a124369SBarry Smith MatGetPetscMaps_Petsc, 2249ee4f033dSBarry Smith 0, 225097304618SKris Buschelman /*65*/ 0, 2251ee4f033dSBarry Smith 0, 2252ee4f033dSBarry Smith 0, 2253ee4f033dSBarry Smith 0, 2254ee4f033dSBarry Smith 0, 2255e34fafa9SBarry Smith /*70*/ MatGetRowMax_SeqAIJ, 2256ee4f033dSBarry Smith 0, 2257ee4f033dSBarry Smith MatSetColoring_SeqAIJ, 2258dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC) 2259ee4f033dSBarry Smith MatSetValuesAdic_SeqAIJ, 2260dcf5cc72SBarry Smith #else 2261dcf5cc72SBarry Smith 0, 2262dcf5cc72SBarry Smith #endif 2263ee4f033dSBarry Smith MatSetValuesAdifor_SeqAIJ, 226497304618SKris Buschelman /*75*/ MatFDColoringApply_SeqAIJ, 226597304618SKris Buschelman 0, 226697304618SKris Buschelman 0, 226797304618SKris Buschelman 0, 226897304618SKris Buschelman 0, 226997304618SKris Buschelman /*80*/ 0, 227097304618SKris Buschelman 0, 227197304618SKris Buschelman 0, 227297304618SKris Buschelman 0, 2273bc011b1eSHong Zhang MatLoad_SeqAIJ, 2274bc011b1eSHong Zhang /*85*/ MatIsSymmetric_SeqAIJ, 22756284ec50SHong Zhang 0, 22766284ec50SHong Zhang 0, 22776284ec50SHong Zhang 0, 2278bc011b1eSHong Zhang 0, 2279bc011b1eSHong Zhang /*90*/ MatMatMult_SeqAIJ_SeqAIJ, 228026be0446SHong Zhang MatMatMultSymbolic_SeqAIJ_SeqAIJ, 228126be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 2282d439da42SKris Buschelman MatPtAP_Basic, 22837ba1a0bfSKris Buschelman MatPtAPSymbolic_SeqAIJ, 22847ba1a0bfSKris Buschelman /*95*/ MatPtAPNumeric_SeqAIJ, 2285bc011b1eSHong Zhang MatMatMultTranspose_SeqAIJ_SeqAIJ, 2286bc011b1eSHong Zhang MatMatMultTransposeSymbolic_SeqAIJ_SeqAIJ, 2287bc011b1eSHong Zhang MatMatMultTransposeNumeric_SeqAIJ_SeqAIJ, 22887ba1a0bfSKris Buschelman MatPtAPSymbolic_SeqAIJ_SeqAIJ, 22897ba1a0bfSKris Buschelman /*100*/MatPtAPNumeric_SeqAIJ_SeqAIJ, 2290609c6c4dSKris Buschelman 0, 2291609c6c4dSKris Buschelman 0, 2292354c94deSBarry Smith MatConjugate_SeqAIJ 22939e29f15eSvictorle }; 229417ab2063SBarry Smith 2295fb2e594dSBarry Smith EXTERN_C_BEGIN 22964a2ae208SSatish Balay #undef __FUNCT__ 22974a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ" 2298be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 2299bef8e0ddSBarry Smith { 2300bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 230197f1f81fSBarry Smith PetscInt i,nz,n; 2302bef8e0ddSBarry Smith 2303bef8e0ddSBarry Smith PetscFunctionBegin; 2304bef8e0ddSBarry Smith 2305bef8e0ddSBarry Smith nz = aij->maxnz; 2306273d9f13SBarry Smith n = mat->n; 2307bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 2308bef8e0ddSBarry Smith aij->j[i] = indices[i]; 2309bef8e0ddSBarry Smith } 2310bef8e0ddSBarry Smith aij->nz = nz; 2311bef8e0ddSBarry Smith for (i=0; i<n; i++) { 2312bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 2313bef8e0ddSBarry Smith } 2314bef8e0ddSBarry Smith 2315bef8e0ddSBarry Smith PetscFunctionReturn(0); 2316bef8e0ddSBarry Smith } 2317fb2e594dSBarry Smith EXTERN_C_END 2318bef8e0ddSBarry Smith 23194a2ae208SSatish Balay #undef __FUNCT__ 23204a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices" 2321bef8e0ddSBarry Smith /*@ 2322bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 2323bef8e0ddSBarry Smith in the matrix. 2324bef8e0ddSBarry Smith 2325bef8e0ddSBarry Smith Input Parameters: 2326bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 2327bef8e0ddSBarry Smith - indices - the column indices 2328bef8e0ddSBarry Smith 232915091d37SBarry Smith Level: advanced 233015091d37SBarry Smith 2331bef8e0ddSBarry Smith Notes: 2332bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 2333bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 2334bef8e0ddSBarry Smith of the MatSetValues() operation. 2335bef8e0ddSBarry Smith 2336bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 2337d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 2338bef8e0ddSBarry Smith 2339bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 2340bef8e0ddSBarry Smith 2341b9617806SBarry Smith The indices should start with zero, not one. 2342b9617806SBarry Smith 2343bef8e0ddSBarry Smith @*/ 2344be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 2345bef8e0ddSBarry Smith { 234697f1f81fSBarry Smith PetscErrorCode ierr,(*f)(Mat,PetscInt *); 2347bef8e0ddSBarry Smith 2348bef8e0ddSBarry Smith PetscFunctionBegin; 23494482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 23504482741eSBarry Smith PetscValidPointer(indices,2); 2351c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr); 2352bef8e0ddSBarry Smith if (f) { 2353bef8e0ddSBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 2354bef8e0ddSBarry Smith } else { 2355634064b4SBarry Smith SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to set column indices"); 2356bef8e0ddSBarry Smith } 2357bef8e0ddSBarry Smith PetscFunctionReturn(0); 2358bef8e0ddSBarry Smith } 2359bef8e0ddSBarry Smith 2360be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 2361be6bf707SBarry Smith 2362fb2e594dSBarry Smith EXTERN_C_BEGIN 23634a2ae208SSatish Balay #undef __FUNCT__ 23644a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ" 2365be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatStoreValues_SeqAIJ(Mat mat) 2366be6bf707SBarry Smith { 2367be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 23686849ba73SBarry Smith PetscErrorCode ierr; 23696849ba73SBarry Smith size_t nz = aij->i[mat->m]; 2370be6bf707SBarry Smith 2371be6bf707SBarry Smith PetscFunctionBegin; 2372be6bf707SBarry Smith if (aij->nonew != 1) { 2373634064b4SBarry Smith SETERRQ(PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2374be6bf707SBarry Smith } 2375be6bf707SBarry Smith 2376be6bf707SBarry Smith /* allocate space for values if not already there */ 2377be6bf707SBarry Smith if (!aij->saved_values) { 237887828ca2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr); 2379be6bf707SBarry Smith } 2380be6bf707SBarry Smith 2381be6bf707SBarry Smith /* copy values over */ 238287828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 2383be6bf707SBarry Smith PetscFunctionReturn(0); 2384be6bf707SBarry Smith } 2385fb2e594dSBarry Smith EXTERN_C_END 2386be6bf707SBarry Smith 23874a2ae208SSatish Balay #undef __FUNCT__ 2388b9617806SBarry Smith #define __FUNCT__ "MatStoreValues" 2389be6bf707SBarry Smith /*@ 2390be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 2391be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2392be6bf707SBarry Smith nonlinear portion. 2393be6bf707SBarry Smith 2394be6bf707SBarry Smith Collect on Mat 2395be6bf707SBarry Smith 2396be6bf707SBarry Smith Input Parameters: 23970e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 2398be6bf707SBarry Smith 239915091d37SBarry Smith Level: advanced 240015091d37SBarry Smith 2401be6bf707SBarry Smith Common Usage, with SNESSolve(): 2402be6bf707SBarry Smith $ Create Jacobian matrix 2403be6bf707SBarry Smith $ Set linear terms into matrix 2404be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 2405be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 2406be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 2407be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2408be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2409be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 2410be6bf707SBarry Smith $ In your Jacobian routine 2411be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2412be6bf707SBarry Smith $ Set nonlinear terms in matrix 2413be6bf707SBarry Smith 2414be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 2415be6bf707SBarry Smith $ // build linear portion of Jacobian 2416be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2417be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2418be6bf707SBarry Smith $ loop over nonlinear iterations 2419be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2420be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 2421be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 2422be6bf707SBarry Smith $ Solve linear system with Jacobian 2423be6bf707SBarry Smith $ endloop 2424be6bf707SBarry Smith 2425be6bf707SBarry Smith Notes: 2426be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 2427be6bf707SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before 2428be6bf707SBarry Smith calling this routine. 2429be6bf707SBarry Smith 24300c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 24310c468ba9SBarry Smith and does not allocated additional space. 24320c468ba9SBarry Smith 2433be6bf707SBarry Smith .seealso: MatRetrieveValues() 2434be6bf707SBarry Smith 2435be6bf707SBarry Smith @*/ 2436be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatStoreValues(Mat mat) 2437be6bf707SBarry Smith { 2438dfbe8321SBarry Smith PetscErrorCode ierr,(*f)(Mat); 2439be6bf707SBarry Smith 2440be6bf707SBarry Smith PetscFunctionBegin; 24414482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 244229bbc08cSBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 244329bbc08cSBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2444be6bf707SBarry Smith 2445c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void (**)(void))&f);CHKERRQ(ierr); 2446be6bf707SBarry Smith if (f) { 2447be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2448be6bf707SBarry Smith } else { 2449634064b4SBarry Smith SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to store values"); 2450be6bf707SBarry Smith } 2451be6bf707SBarry Smith PetscFunctionReturn(0); 2452be6bf707SBarry Smith } 2453be6bf707SBarry Smith 2454fb2e594dSBarry Smith EXTERN_C_BEGIN 24554a2ae208SSatish Balay #undef __FUNCT__ 24564a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ" 2457be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatRetrieveValues_SeqAIJ(Mat mat) 2458be6bf707SBarry Smith { 2459be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 24606849ba73SBarry Smith PetscErrorCode ierr; 246197f1f81fSBarry Smith PetscInt nz = aij->i[mat->m]; 2462be6bf707SBarry Smith 2463be6bf707SBarry Smith PetscFunctionBegin; 2464be6bf707SBarry Smith if (aij->nonew != 1) { 2465634064b4SBarry Smith SETERRQ(PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2466be6bf707SBarry Smith } 2467be6bf707SBarry Smith if (!aij->saved_values) { 2468634064b4SBarry Smith SETERRQ(PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 2469be6bf707SBarry Smith } 2470be6bf707SBarry Smith /* copy values over */ 247187828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 2472be6bf707SBarry Smith PetscFunctionReturn(0); 2473be6bf707SBarry Smith } 2474fb2e594dSBarry Smith EXTERN_C_END 2475be6bf707SBarry Smith 24764a2ae208SSatish Balay #undef __FUNCT__ 24774a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues" 2478be6bf707SBarry Smith /*@ 2479be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 2480be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2481be6bf707SBarry Smith nonlinear portion. 2482be6bf707SBarry Smith 2483be6bf707SBarry Smith Collect on Mat 2484be6bf707SBarry Smith 2485be6bf707SBarry Smith Input Parameters: 2486be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2487be6bf707SBarry Smith 248815091d37SBarry Smith Level: advanced 248915091d37SBarry Smith 2490be6bf707SBarry Smith .seealso: MatStoreValues() 2491be6bf707SBarry Smith 2492be6bf707SBarry Smith @*/ 2493be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatRetrieveValues(Mat mat) 2494be6bf707SBarry Smith { 2495dfbe8321SBarry Smith PetscErrorCode ierr,(*f)(Mat); 2496be6bf707SBarry Smith 2497be6bf707SBarry Smith PetscFunctionBegin; 24984482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 249929bbc08cSBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 250029bbc08cSBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2501be6bf707SBarry Smith 2502c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void (**)(void))&f);CHKERRQ(ierr); 2503be6bf707SBarry Smith if (f) { 2504be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2505be6bf707SBarry Smith } else { 2506634064b4SBarry Smith SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to retrieve values"); 2507be6bf707SBarry Smith } 2508be6bf707SBarry Smith PetscFunctionReturn(0); 2509be6bf707SBarry Smith } 2510be6bf707SBarry Smith 2511f83d6046SBarry Smith 2512be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 25134a2ae208SSatish Balay #undef __FUNCT__ 25144a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ" 251517ab2063SBarry Smith /*@C 2516682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 25170d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 25186e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 251951c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 25202bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 252117ab2063SBarry Smith 2522db81eaa0SLois Curfman McInnes Collective on MPI_Comm 2523db81eaa0SLois Curfman McInnes 252417ab2063SBarry Smith Input Parameters: 2525db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 252617ab2063SBarry Smith . m - number of rows 252717ab2063SBarry Smith . n - number of columns 252817ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 252951c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 25302bd5e0b2SLois Curfman McInnes (possibly different for each row) or PETSC_NULL 253117ab2063SBarry Smith 253217ab2063SBarry Smith Output Parameter: 2533416022c9SBarry Smith . A - the matrix 253417ab2063SBarry Smith 2535b259b22eSLois Curfman McInnes Notes: 253649a6f317SBarry Smith If nnz is given then nz is ignored 253749a6f317SBarry Smith 253817ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 253917ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 25400002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 254144cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 254217ab2063SBarry Smith 254317ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2544a40aa06bSLois Curfman McInnes Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 25453d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 25466da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 254717ab2063SBarry Smith 2548682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 25494fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 2550682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 25516c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 25526c7ebb05SLois Curfman McInnes 25536c7ebb05SLois Curfman McInnes Options Database Keys: 2554698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 2555698d4c6aSKris Buschelman . -mat_inode_limit <limit> - Sets inode limit (max limit=5) 2556db81eaa0SLois Curfman McInnes - -mat_aij_oneindex - Internally use indexing starting at 1 2557db81eaa0SLois Curfman McInnes rather than 0. Note that when calling MatSetValues(), 2558db81eaa0SLois Curfman McInnes the user still MUST index entries starting at 0! 255917ab2063SBarry Smith 2560027ccd11SLois Curfman McInnes Level: intermediate 2561027ccd11SLois Curfman McInnes 256236db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 256336db0b34SBarry Smith 256417ab2063SBarry Smith @*/ 2565be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 256617ab2063SBarry Smith { 2567dfbe8321SBarry Smith PetscErrorCode ierr; 25686945ee14SBarry Smith 25693a40ed3dSBarry Smith PetscFunctionBegin; 2570f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 2571f69a0ea3SMatthew Knepley ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 2572273d9f13SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 2573ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,(PetscInt*)nnz);CHKERRQ(ierr); 2574273d9f13SBarry Smith PetscFunctionReturn(0); 2575273d9f13SBarry Smith } 2576273d9f13SBarry Smith 25774a2ae208SSatish Balay #undef __FUNCT__ 25784a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation" 2579273d9f13SBarry Smith /*@C 2580273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 2581273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 2582273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 2583273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 2584273d9f13SBarry Smith 2585273d9f13SBarry Smith Collective on MPI_Comm 2586273d9f13SBarry Smith 2587273d9f13SBarry Smith Input Parameters: 258845bfc511SMatthew Knepley + B - The matrix 2589273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 2590273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 2591273d9f13SBarry Smith (possibly different for each row) or PETSC_NULL 2592273d9f13SBarry Smith 2593273d9f13SBarry Smith Notes: 259449a6f317SBarry Smith If nnz is given then nz is ignored 259549a6f317SBarry Smith 2596273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 2597273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 2598273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 2599273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 2600273d9f13SBarry Smith 2601273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2602273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 2603273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 2604273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 2605273d9f13SBarry Smith 2606a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 2607a96a251dSBarry Smith entries or columns indices 2608a96a251dSBarry Smith 2609273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 2610273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 2611273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 2612273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 2613273d9f13SBarry Smith 2614273d9f13SBarry Smith Options Database Keys: 2615698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 2616698d4c6aSKris Buschelman . -mat_inode_limit <limit> - Sets inode limit (max limit=5) 2617273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 2618273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 2619273d9f13SBarry Smith the user still MUST index entries starting at 0! 2620273d9f13SBarry Smith 2621273d9f13SBarry Smith Level: intermediate 2622273d9f13SBarry Smith 2623273d9f13SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 2624273d9f13SBarry Smith 2625273d9f13SBarry Smith @*/ 2626be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 2627273d9f13SBarry Smith { 262897f1f81fSBarry Smith PetscErrorCode ierr,(*f)(Mat,PetscInt,const PetscInt[]); 2629a23d5eceSKris Buschelman 2630a23d5eceSKris Buschelman PetscFunctionBegin; 2631a23d5eceSKris Buschelman ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",(void (**)(void))&f);CHKERRQ(ierr); 2632a23d5eceSKris Buschelman if (f) { 2633a23d5eceSKris Buschelman ierr = (*f)(B,nz,nnz);CHKERRQ(ierr); 2634a23d5eceSKris Buschelman } 2635a23d5eceSKris Buschelman PetscFunctionReturn(0); 2636a23d5eceSKris Buschelman } 2637a23d5eceSKris Buschelman 2638a23d5eceSKris Buschelman EXTERN_C_BEGIN 2639a23d5eceSKris Buschelman #undef __FUNCT__ 2640a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ" 2641be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,PetscInt *nnz) 2642a23d5eceSKris Buschelman { 2643273d9f13SBarry Smith Mat_SeqAIJ *b; 2644a43ee2ecSKris Buschelman PetscTruth skipallocation = PETSC_FALSE; 26456849ba73SBarry Smith PetscErrorCode ierr; 264697f1f81fSBarry Smith PetscInt i; 2647273d9f13SBarry Smith 2648273d9f13SBarry Smith PetscFunctionBegin; 2649d5d45c9bSBarry Smith 2650a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 2651c461c341SBarry Smith skipallocation = PETSC_TRUE; 2652c461c341SBarry Smith nz = 0; 2653c461c341SBarry Smith } 2654c461c341SBarry Smith 2655435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 2656435da068SBarry Smith if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 2657b73539f3SBarry Smith if (nnz) { 2658273d9f13SBarry Smith for (i=0; i<B->m; i++) { 265929bbc08cSBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 26603a7fca6bSBarry 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); 2661b73539f3SBarry Smith } 2662b73539f3SBarry Smith } 2663b73539f3SBarry Smith 2664273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 2665273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 2666273d9f13SBarry Smith 2667ab93d7beSBarry Smith if (!skipallocation) { 2668ab93d7beSBarry Smith ierr = PetscMalloc2(B->m,PetscInt,&b->imax,B->m,PetscInt,&b->ilen);CHKERRQ(ierr); 2669273d9f13SBarry Smith if (!nnz) { 2670435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 2671273d9f13SBarry Smith else if (nz <= 0) nz = 1; 2672273d9f13SBarry Smith for (i=0; i<B->m; i++) b->imax[i] = nz; 2673273d9f13SBarry Smith nz = nz*B->m; 2674273d9f13SBarry Smith } else { 2675273d9f13SBarry Smith nz = 0; 2676273d9f13SBarry Smith for (i=0; i<B->m; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 2677273d9f13SBarry Smith } 2678273d9f13SBarry Smith 2679ab93d7beSBarry Smith /* b->ilen will count nonzeros in each row so far. */ 2680ab93d7beSBarry Smith for (i=0; i<B->m; i++) { b->ilen[i] = 0;} 2681ab93d7beSBarry Smith 2682273d9f13SBarry Smith /* allocate the matrix space */ 2683a96a251dSBarry Smith ierr = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->m+1,PetscInt,&b->i);CHKERRQ(ierr); 2684bfeeae90SHong Zhang b->i[0] = 0; 26855da197adSKris Buschelman for (i=1; i<B->m+1; i++) { 26865da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 26875da197adSKris Buschelman } 2688273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 2689273d9f13SBarry Smith b->freedata = PETSC_TRUE; 2690c461c341SBarry Smith } else { 2691c461c341SBarry Smith b->freedata = PETSC_FALSE; 2692c461c341SBarry Smith } 2693273d9f13SBarry Smith 2694273d9f13SBarry Smith b->nz = 0; 2695273d9f13SBarry Smith b->maxnz = nz; 2696273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 2697273d9f13SBarry Smith PetscFunctionReturn(0); 2698273d9f13SBarry Smith } 2699a23d5eceSKris Buschelman EXTERN_C_END 2700273d9f13SBarry Smith 2701a1661176SMatthew Knepley #undef __FUNCT__ 2702a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR" 2703a1661176SMatthew Knepley /*@C 2704a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 2705a1661176SMatthew Knepley 2706a1661176SMatthew Knepley Input Parameters: 2707a1661176SMatthew Knepley + B - the matrix 2708a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 2709a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 2710a1661176SMatthew Knepley - v - optional values in the matrix 2711a1661176SMatthew Knepley 2712d58b2322SMatthew Knepley Contributed by: Lisandro Dalchin 2713d58b2322SMatthew Knepley 2714a1661176SMatthew Knepley Level: developer 2715a1661176SMatthew Knepley 2716a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential 2717a1661176SMatthew Knepley 2718a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ 2719a1661176SMatthew Knepley @*/ 2720a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 2721a1661176SMatthew Knepley { 2722a1661176SMatthew Knepley PetscErrorCode (*f)(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]); 2723a1661176SMatthew Knepley PetscErrorCode ierr; 2724a1661176SMatthew Knepley 2725a1661176SMatthew Knepley PetscFunctionBegin; 2726a1661176SMatthew Knepley PetscValidHeaderSpecific(B,MAT_COOKIE,1); 2727a1661176SMatthew Knepley ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",(void (**)(void))&f);CHKERRQ(ierr); 2728a1661176SMatthew Knepley if (f) { 2729a1661176SMatthew Knepley ierr = (*f)(B,i,j,v);CHKERRQ(ierr); 2730a1661176SMatthew Knepley } 2731a1661176SMatthew Knepley PetscFunctionReturn(0); 2732a1661176SMatthew Knepley } 2733a1661176SMatthew Knepley 2734a1661176SMatthew Knepley EXTERN_C_BEGIN 2735a1661176SMatthew Knepley #undef __FUNCT__ 2736a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR_SeqAIJ" 2737a1661176SMatthew Knepley PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt I[],const PetscInt J[],const PetscScalar v[]) 2738a1661176SMatthew Knepley { 2739a1661176SMatthew Knepley PetscInt i; 2740a1661176SMatthew Knepley PetscInt m,n; 2741a1661176SMatthew Knepley PetscInt nz; 2742a1661176SMatthew Knepley PetscInt *nnz, nz_max = 0; 2743a1661176SMatthew Knepley PetscScalar *values; 2744a1661176SMatthew Knepley PetscErrorCode ierr; 2745a1661176SMatthew Knepley 2746a1661176SMatthew Knepley PetscFunctionBegin; 2747a1661176SMatthew Knepley ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 2748a1661176SMatthew Knepley 2749a1661176SMatthew Knepley if (I[0]) { 2750a1661176SMatthew Knepley SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "I[0] must be 0 it is %D", I[0]); 2751a1661176SMatthew Knepley } 2752a1661176SMatthew Knepley ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr); 2753a1661176SMatthew Knepley for(i = 0; i < m; i++) { 2754a1661176SMatthew Knepley nz = I[i+1]- I[i]; 2755a1661176SMatthew Knepley nz_max = PetscMax(nz_max, nz); 2756a1661176SMatthew Knepley if (nz < 0) { 2757a1661176SMatthew Knepley SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 2758a1661176SMatthew Knepley } 2759a1661176SMatthew Knepley nnz[i] = nz; 2760a1661176SMatthew Knepley } 2761a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 2762a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 2763a1661176SMatthew Knepley 2764a1661176SMatthew Knepley if (v) { 2765a1661176SMatthew Knepley values = (PetscScalar*) v; 2766a1661176SMatthew Knepley } else { 2767a1661176SMatthew Knepley ierr = PetscMalloc((nz_max+1)*sizeof(PetscScalar), &values);CHKERRQ(ierr); 2768a1661176SMatthew Knepley ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr); 2769a1661176SMatthew Knepley } 2770a1661176SMatthew Knepley 2771a1661176SMatthew Knepley ierr = MatSetOption(B,MAT_COLUMNS_SORTED);CHKERRQ(ierr); 2772a1661176SMatthew Knepley 2773a1661176SMatthew Knepley for(i = 0; i < m; i++) { 2774a1661176SMatthew Knepley nz = I[i+1] - I[i]; 2775a1661176SMatthew Knepley ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+I[i], values + (v ? I[i] : 0), INSERT_VALUES);CHKERRQ(ierr); 2776a1661176SMatthew Knepley } 2777a1661176SMatthew Knepley 2778a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2779a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2780a1661176SMatthew Knepley ierr = MatSetOption(B,MAT_COLUMNS_UNSORTED);CHKERRQ(ierr); 2781a1661176SMatthew Knepley 2782a1661176SMatthew Knepley if (!v) { 2783a1661176SMatthew Knepley ierr = PetscFree(values);CHKERRQ(ierr); 2784a1661176SMatthew Knepley } 2785a1661176SMatthew Knepley PetscFunctionReturn(0); 2786a1661176SMatthew Knepley } 2787a1661176SMatthew Knepley EXTERN_C_END 2788a1661176SMatthew Knepley 27890bad9183SKris Buschelman /*MC 2790fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 27910bad9183SKris Buschelman based on compressed sparse row format. 27920bad9183SKris Buschelman 27930bad9183SKris Buschelman Options Database Keys: 27940bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 27950bad9183SKris Buschelman 27960bad9183SKris Buschelman Level: beginner 27970bad9183SKris Buschelman 2798f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 27990bad9183SKris Buschelman M*/ 28000bad9183SKris Buschelman 2801a6175056SHong Zhang EXTERN_C_BEGIN 28024a2ae208SSatish Balay #undef __FUNCT__ 28034a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ" 2804be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_SeqAIJ(Mat B) 2805273d9f13SBarry Smith { 2806273d9f13SBarry Smith Mat_SeqAIJ *b; 2807dfbe8321SBarry Smith PetscErrorCode ierr; 280838baddfdSBarry Smith PetscMPIInt size; 2809273d9f13SBarry Smith 2810273d9f13SBarry Smith PetscFunctionBegin; 2811273d9f13SBarry Smith ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr); 2812273d9f13SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 2813273d9f13SBarry Smith 2814273d9f13SBarry Smith B->m = B->M = PetscMax(B->m,B->M); 2815273d9f13SBarry Smith B->n = B->N = PetscMax(B->n,B->N); 2816273d9f13SBarry Smith 2817b0a32e0cSBarry Smith ierr = PetscNew(Mat_SeqAIJ,&b);CHKERRQ(ierr); 2818b0a32e0cSBarry Smith B->data = (void*)b; 2819549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 2820416022c9SBarry Smith B->factor = 0; 282190f02eecSBarry Smith B->mapping = 0; 2822416022c9SBarry Smith b->row = 0; 2823416022c9SBarry Smith b->col = 0; 282482bf6240SBarry Smith b->icol = 0; 2825b810aeb4SBarry Smith b->reallocs = 0; 282617ab2063SBarry Smith 28278a124369SBarry Smith ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr); 28288a124369SBarry Smith ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr); 2829a5ae1ecdSBarry Smith 2830f1e2ffcdSBarry Smith b->sorted = PETSC_FALSE; 283136db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 2832f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 2833416022c9SBarry Smith b->nonew = 0; 2834416022c9SBarry Smith b->diag = 0; 2835416022c9SBarry Smith b->solve_work = 0; 28362a1b7f2aSHong Zhang B->spptr = 0; 2837be6bf707SBarry Smith b->saved_values = 0; 2838d7f994e1SBarry Smith b->idiag = 0; 2839d7f994e1SBarry Smith b->ssor = 0; 2840f1e2ffcdSBarry Smith b->keepzeroedrows = PETSC_FALSE; 2841a30b2313SHong Zhang b->xtoy = 0; 2842a30b2313SHong Zhang b->XtoY = 0; 284373e7a558SHong Zhang b->compressedrow.use = PETSC_FALSE; 2844d487561eSHong Zhang b->compressedrow.nrows = B->m; 2845d487561eSHong Zhang b->compressedrow.i = PETSC_NULL; 2846d487561eSHong Zhang b->compressedrow.rindex = PETSC_NULL; 2847d487561eSHong Zhang b->compressedrow.checked = PETSC_FALSE; 284888e51ccdSHong Zhang B->same_nonzero = PETSC_FALSE; 284917ab2063SBarry Smith 285035d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 285135d8aa7fSBarry Smith 2852f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C", 2853bef8e0ddSBarry Smith "MatSeqAIJSetColumnIndices_SeqAIJ", 2854bc4b532fSSatish Balay MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 2855f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 2856be6bf707SBarry Smith "MatStoreValues_SeqAIJ", 2857bc4b532fSSatish Balay MatStoreValues_SeqAIJ);CHKERRQ(ierr); 2858f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 2859be6bf707SBarry Smith "MatRetrieveValues_SeqAIJ", 2860bc4b532fSSatish Balay MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 2861a6175056SHong Zhang ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C", 2862a6175056SHong Zhang "MatConvert_SeqAIJ_SeqSBAIJ", 2863a6175056SHong Zhang MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 286485fc7724SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C", 286585fc7724SBarry Smith "MatConvert_SeqAIJ_SeqBAIJ", 286685fc7724SBarry Smith MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 28675fbd3699SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C", 28685fbd3699SBarry Smith "MatIsTranspose_SeqAIJ", 28695fbd3699SBarry Smith MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 2870a23d5eceSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C", 2871a23d5eceSKris Buschelman "MatSeqAIJSetPreallocation_SeqAIJ", 2872a23d5eceSKris Buschelman MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 2873a1661176SMatthew Knepley ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C", 2874a1661176SMatthew Knepley "MatSeqAIJSetPreallocationCSR_SeqAIJ", 2875a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 287605b94e36SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C", 287705b94e36SKris Buschelman "MatReorderForNonzeroDiagonal_SeqAIJ", 287805b94e36SKris Buschelman MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 28794846f1f5SKris Buschelman ierr = MatCreate_Inode(B);CHKERRQ(ierr); 28803a40ed3dSBarry Smith PetscFunctionReturn(0); 288117ab2063SBarry Smith } 2882273d9f13SBarry Smith EXTERN_C_END 288317ab2063SBarry Smith 28844a2ae208SSatish Balay #undef __FUNCT__ 28854a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqAIJ" 2886dfbe8321SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 288717ab2063SBarry Smith { 2888416022c9SBarry Smith Mat C; 2889416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 28906849ba73SBarry Smith PetscErrorCode ierr; 289197f1f81fSBarry Smith PetscInt i,m = A->m; 289217ab2063SBarry Smith 28933a40ed3dSBarry Smith PetscFunctionBegin; 28944043dd9cSLois Curfman McInnes *B = 0; 2895f69a0ea3SMatthew Knepley ierr = MatCreate(A->comm,&C);CHKERRQ(ierr); 2896f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,A->m,A->n,A->m,A->n);CHKERRQ(ierr); 2897be5d1d56SKris Buschelman ierr = MatSetType(C,A->type_name);CHKERRQ(ierr); 28981d5dac46SHong Zhang ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 28991d5dac46SHong Zhang 2900273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 2901273d9f13SBarry Smith 2902416022c9SBarry Smith C->factor = A->factor; 29036ad4291fSHong Zhang 2904416022c9SBarry Smith c->row = 0; 2905416022c9SBarry Smith c->col = 0; 290682bf6240SBarry Smith c->icol = 0; 29076ad4291fSHong Zhang c->reallocs = 0; 290817ab2063SBarry Smith 29096ad4291fSHong Zhang C->assembled = PETSC_TRUE; 291017ab2063SBarry Smith 291133b91e9fSSatish Balay ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr); 291217ab2063SBarry Smith for (i=0; i<m; i++) { 2913416022c9SBarry Smith c->imax[i] = a->imax[i]; 2914416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 291517ab2063SBarry Smith } 291617ab2063SBarry Smith 291717ab2063SBarry Smith /* allocate the matrix space */ 2918a96a251dSBarry Smith ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr); 2919f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 292097f1f81fSBarry Smith ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 292117ab2063SBarry Smith if (m > 0) { 292297f1f81fSBarry Smith ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr); 2923be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 2924bfeeae90SHong Zhang ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 2925be6bf707SBarry Smith } else { 2926bfeeae90SHong Zhang ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 292717ab2063SBarry Smith } 292808480c60SBarry Smith } 292917ab2063SBarry Smith 2930416022c9SBarry Smith c->sorted = a->sorted; 29316ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 2932416022c9SBarry Smith c->roworiented = a->roworiented; 2933416022c9SBarry Smith c->nonew = a->nonew; 2934416022c9SBarry Smith if (a->diag) { 293597f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr); 293652e6d16bSBarry Smith ierr = PetscLogObjectMemory(C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 293717ab2063SBarry Smith for (i=0; i<m; i++) { 2938416022c9SBarry Smith c->diag[i] = a->diag[i]; 293917ab2063SBarry Smith } 29403a40ed3dSBarry Smith } else c->diag = 0; 29416ad4291fSHong Zhang c->solve_work = 0; 29426ad4291fSHong Zhang c->saved_values = 0; 29436ad4291fSHong Zhang c->idiag = 0; 29446ad4291fSHong Zhang c->ssor = 0; 29456ad4291fSHong Zhang c->keepzeroedrows = a->keepzeroedrows; 29466ad4291fSHong Zhang c->freedata = PETSC_TRUE; 29476ad4291fSHong Zhang c->xtoy = 0; 29486ad4291fSHong Zhang c->XtoY = 0; 29496ad4291fSHong Zhang 2950416022c9SBarry Smith c->nz = a->nz; 2951416022c9SBarry Smith c->maxnz = a->maxnz; 2952273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 2953754ec7b1SSatish Balay 29546ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 29556ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 29566ad4291fSHong Zhang c->compressedrow.checked = a->compressedrow.checked; 29576ad4291fSHong Zhang if ( a->compressedrow.checked && a->compressedrow.use){ 29586ad4291fSHong Zhang i = a->compressedrow.nrows; 29596ad4291fSHong Zhang ierr = PetscMalloc((2*i+1)*sizeof(PetscInt),&c->compressedrow.i);CHKERRQ(ierr); 29606ad4291fSHong Zhang c->compressedrow.rindex = c->compressedrow.i + i + 1; 29616ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr); 29626ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr); 296327ea64f8SHong Zhang } else { 296427ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 296527ea64f8SHong Zhang c->compressedrow.i = PETSC_NULL; 296627ea64f8SHong Zhang c->compressedrow.rindex = PETSC_NULL; 29676ad4291fSHong Zhang } 296888e51ccdSHong Zhang C->same_nonzero = A->same_nonzero; 29696ad4291fSHong Zhang 29704846f1f5SKris Buschelman ierr = MatDuplicate_Inode(A,cpvalues,&C);CHKERRQ(ierr); 29714846f1f5SKris Buschelman 2972416022c9SBarry Smith *B = C; 2973b0a32e0cSBarry Smith ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 29743a40ed3dSBarry Smith PetscFunctionReturn(0); 297517ab2063SBarry Smith } 297617ab2063SBarry Smith 29774a2ae208SSatish Balay #undef __FUNCT__ 29784a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ" 2979f69a0ea3SMatthew Knepley PetscErrorCode MatLoad_SeqAIJ(PetscViewer viewer, MatType type,Mat *A) 298017ab2063SBarry Smith { 2981416022c9SBarry Smith Mat_SeqAIJ *a; 2982416022c9SBarry Smith Mat B; 29836849ba73SBarry Smith PetscErrorCode ierr; 29843c601197SSatish Balay PetscInt i,sum,nz,header[4],*rowlengths = 0,M,N; 298538baddfdSBarry Smith int fd; 298638baddfdSBarry Smith PetscMPIInt size; 2987bcd2baecSBarry Smith MPI_Comm comm; 298817ab2063SBarry Smith 29893a40ed3dSBarry Smith PetscFunctionBegin; 2990e864ced6SBarry Smith ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 2991d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 299229bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,"view must have one processor"); 2993b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 29940752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 2995552e946dSBarry Smith if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 299617ab2063SBarry Smith M = header[1]; N = header[2]; nz = header[3]; 299717ab2063SBarry Smith 2998d64ed03dSBarry Smith if (nz < 0) { 299929bbc08cSBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 3000d64ed03dSBarry Smith } 3001d64ed03dSBarry Smith 300217ab2063SBarry Smith /* read in row lengths */ 300397f1f81fSBarry Smith ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr); 30040752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 300517ab2063SBarry Smith 30063c601197SSatish Balay /* check if sum of rowlengths is same as nz */ 30073c601197SSatish Balay for (i=0,sum=0; i< M; i++) sum +=rowlengths[i]; 30083c601197SSatish Balay if (sum != nz) SETERRQ2(PETSC_ERR_FILE_READ,"Inconsistant matrix data in file. no-nonzeros = %d, sum-row-lengths = %d\n",nz,sum); 30093c601197SSatish Balay 301017ab2063SBarry Smith /* create our matrix */ 3011f69a0ea3SMatthew Knepley ierr = MatCreate(comm,&B);CHKERRQ(ierr); 3012f69a0ea3SMatthew Knepley ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 3013b3a1e11cSKris Buschelman ierr = MatSetType(B,type);CHKERRQ(ierr); 3014ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(B,0,rowlengths);CHKERRQ(ierr); 3015416022c9SBarry Smith a = (Mat_SeqAIJ*)B->data; 301617ab2063SBarry Smith 301717ab2063SBarry Smith /* read in column indices and adjust for Fortran indexing*/ 30180752156aSBarry Smith ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 301917ab2063SBarry Smith 302017ab2063SBarry Smith /* read in nonzero values */ 30210752156aSBarry Smith ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 302217ab2063SBarry Smith 302317ab2063SBarry Smith /* set matrix "i" values */ 3024efb16452SHong Zhang a->i[0] = 0; 302517ab2063SBarry Smith for (i=1; i<= M; i++) { 3026416022c9SBarry Smith a->i[i] = a->i[i-1] + rowlengths[i-1]; 3027416022c9SBarry Smith a->ilen[i-1] = rowlengths[i-1]; 302817ab2063SBarry Smith } 3029606d414cSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 303017ab2063SBarry Smith 30316d4a8577SBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 30326d4a8577SBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3033b3a1e11cSKris Buschelman *A = B; 30343a40ed3dSBarry Smith PetscFunctionReturn(0); 303517ab2063SBarry Smith } 303617ab2063SBarry Smith 30374a2ae208SSatish Balay #undef __FUNCT__ 3038b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ" 3039dfbe8321SBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg) 30407264ac53SSatish Balay { 30417264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data; 3042dfbe8321SBarry Smith PetscErrorCode ierr; 30437264ac53SSatish Balay 30443a40ed3dSBarry Smith PetscFunctionBegin; 3045bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 3046bfeeae90SHong Zhang if ((A->m != B->m) || (A->n != B->n) ||(a->nz != b->nz)) { 3047ca44d042SBarry Smith *flg = PETSC_FALSE; 3048ca44d042SBarry Smith PetscFunctionReturn(0); 3049bcd2baecSBarry Smith } 30507264ac53SSatish Balay 30517264ac53SSatish Balay /* if the a->i are the same */ 305297f1f81fSBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->m+1)*sizeof(PetscInt),flg);CHKERRQ(ierr); 3053abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 30547264ac53SSatish Balay 30557264ac53SSatish Balay /* if a->j are the same */ 305697f1f81fSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr); 3057abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 3058bcd2baecSBarry Smith 3059bcd2baecSBarry Smith /* if a->a are the same */ 306087828ca2SBarry Smith ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 30610f5bd95cSBarry Smith 30623a40ed3dSBarry Smith PetscFunctionReturn(0); 30637264ac53SSatish Balay 30647264ac53SSatish Balay } 306536db0b34SBarry Smith 30664a2ae208SSatish Balay #undef __FUNCT__ 30674a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays" 306805869f15SSatish Balay /*@ 306936db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 307036db0b34SBarry Smith provided by the user. 307136db0b34SBarry Smith 307236db0b34SBarry Smith Coolective on MPI_Comm 307336db0b34SBarry Smith 307436db0b34SBarry Smith Input Parameters: 307536db0b34SBarry Smith + comm - must be an MPI communicator of size 1 307636db0b34SBarry Smith . m - number of rows 307736db0b34SBarry Smith . n - number of columns 307836db0b34SBarry Smith . i - row indices 307936db0b34SBarry Smith . j - column indices 308036db0b34SBarry Smith - a - matrix values 308136db0b34SBarry Smith 308236db0b34SBarry Smith Output Parameter: 308336db0b34SBarry Smith . mat - the matrix 308436db0b34SBarry Smith 308536db0b34SBarry Smith Level: intermediate 308636db0b34SBarry Smith 308736db0b34SBarry Smith Notes: 30880551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 308936db0b34SBarry Smith once the matrix is destroyed 309036db0b34SBarry Smith 309136db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 309236db0b34SBarry Smith 3093bfeeae90SHong Zhang The i and j indices are 0 based 309436db0b34SBarry Smith 309536db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ() 309636db0b34SBarry Smith 309736db0b34SBarry Smith @*/ 3098be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat) 309936db0b34SBarry Smith { 3100dfbe8321SBarry Smith PetscErrorCode ierr; 310197f1f81fSBarry Smith PetscInt ii; 310236db0b34SBarry Smith Mat_SeqAIJ *aij; 310336db0b34SBarry Smith 310436db0b34SBarry Smith PetscFunctionBegin; 3105a96a251dSBarry Smith if (i[0]) { 3106634064b4SBarry Smith SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 310736db0b34SBarry Smith } 3108f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 3109f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 3110ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 3111ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 3112ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 3113ab93d7beSBarry Smith ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr); 3114ab93d7beSBarry Smith 311536db0b34SBarry Smith aij->i = i; 311636db0b34SBarry Smith aij->j = j; 311736db0b34SBarry Smith aij->a = a; 311836db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 311936db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 312036db0b34SBarry Smith aij->freedata = PETSC_FALSE; 312136db0b34SBarry Smith 312236db0b34SBarry Smith for (ii=0; ii<m; ii++) { 312336db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 31242515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 312579a5c55eSBarry Smith if (i[ii+1] - i[ii] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Negative row length in i (row indices) row = %d length = %d",ii,i[ii+1] - i[ii]); 312636db0b34SBarry Smith #endif 312736db0b34SBarry Smith } 31282515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 312936db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 313079a5c55eSBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]); 313179a5c55eSBarry Smith if (j[ii] > n - 1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column index to large at location = %d index = %d",ii,j[ii]); 313236db0b34SBarry Smith } 313336db0b34SBarry Smith #endif 313436db0b34SBarry Smith 3135b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3136b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 313736db0b34SBarry Smith PetscFunctionReturn(0); 313836db0b34SBarry Smith } 313936db0b34SBarry Smith 3140cc8ba8e1SBarry Smith #undef __FUNCT__ 3141ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ" 3142dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring) 3143cc8ba8e1SBarry Smith { 3144dfbe8321SBarry Smith PetscErrorCode ierr; 3145cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 314636db0b34SBarry Smith 3147cc8ba8e1SBarry Smith PetscFunctionBegin; 314812c595b3SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 3149cc8ba8e1SBarry Smith ierr = ISColoringReference(coloring);CHKERRQ(ierr); 3150cc8ba8e1SBarry Smith a->coloring = coloring; 315112c595b3SBarry Smith } else if (coloring->ctype == IS_COLORING_GHOSTED) { 315297f1f81fSBarry Smith PetscInt i,*larray; 315312c595b3SBarry Smith ISColoring ocoloring; 315408b6dcc0SBarry Smith ISColoringValue *colors; 315512c595b3SBarry Smith 315612c595b3SBarry Smith /* set coloring for diagonal portion */ 315797f1f81fSBarry Smith ierr = PetscMalloc((A->n+1)*sizeof(PetscInt),&larray);CHKERRQ(ierr); 315812c595b3SBarry Smith for (i=0; i<A->n; i++) { 315912c595b3SBarry Smith larray[i] = i; 316012c595b3SBarry Smith } 316112c595b3SBarry Smith ierr = ISGlobalToLocalMappingApply(A->mapping,IS_GTOLM_MASK,A->n,larray,PETSC_NULL,larray);CHKERRQ(ierr); 316208b6dcc0SBarry Smith ierr = PetscMalloc((A->n+1)*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); 316312c595b3SBarry Smith for (i=0; i<A->n; i++) { 316412c595b3SBarry Smith colors[i] = coloring->colors[larray[i]]; 316512c595b3SBarry Smith } 316612c595b3SBarry Smith ierr = PetscFree(larray);CHKERRQ(ierr); 316712c595b3SBarry Smith ierr = ISColoringCreate(PETSC_COMM_SELF,A->n,colors,&ocoloring);CHKERRQ(ierr); 316812c595b3SBarry Smith a->coloring = ocoloring; 316912c595b3SBarry Smith } 3170cc8ba8e1SBarry Smith PetscFunctionReturn(0); 3171cc8ba8e1SBarry Smith } 3172cc8ba8e1SBarry Smith 3173dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC) 3174ee4f033dSBarry Smith EXTERN_C_BEGIN 317529c1e371SBarry Smith #include "adic/ad_utils.h" 3176ee4f033dSBarry Smith EXTERN_C_END 3177cc8ba8e1SBarry Smith 3178cc8ba8e1SBarry Smith #undef __FUNCT__ 3179ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ" 3180dfbe8321SBarry Smith PetscErrorCode MatSetValuesAdic_SeqAIJ(Mat A,void *advalues) 3181cc8ba8e1SBarry Smith { 3182cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 318397f1f81fSBarry Smith PetscInt m = A->m,*ii = a->i,*jj = a->j,nz,i,j,nlen; 31844440f671SBarry Smith PetscScalar *v = a->a,*values = ((PetscScalar*)advalues)+1; 318508b6dcc0SBarry Smith ISColoringValue *color; 3186cc8ba8e1SBarry Smith 3187cc8ba8e1SBarry Smith PetscFunctionBegin; 3188e005ede5SBarry Smith if (!a->coloring) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix"); 31894440f671SBarry Smith nlen = PetscADGetDerivTypeSize()/sizeof(PetscScalar); 3190cc8ba8e1SBarry Smith color = a->coloring->colors; 3191cc8ba8e1SBarry Smith /* loop over rows */ 3192cc8ba8e1SBarry Smith for (i=0; i<m; i++) { 3193cc8ba8e1SBarry Smith nz = ii[i+1] - ii[i]; 3194cc8ba8e1SBarry Smith /* loop over columns putting computed value into matrix */ 3195cc8ba8e1SBarry Smith for (j=0; j<nz; j++) { 3196cc8ba8e1SBarry Smith *v++ = values[color[*jj++]]; 3197cc8ba8e1SBarry Smith } 31984440f671SBarry Smith values += nlen; /* jump to next row of derivatives */ 3199ee4f033dSBarry Smith } 3200ee4f033dSBarry Smith PetscFunctionReturn(0); 3201ee4f033dSBarry Smith } 3202ee4f033dSBarry Smith #endif 3203ee4f033dSBarry Smith 3204ee4f033dSBarry Smith #undef __FUNCT__ 3205ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ" 320697f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues) 3207ee4f033dSBarry Smith { 3208ee4f033dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 320997f1f81fSBarry Smith PetscInt m = A->m,*ii = a->i,*jj = a->j,nz,i,j; 321087828ca2SBarry Smith PetscScalar *v = a->a,*values = (PetscScalar *)advalues; 321108b6dcc0SBarry Smith ISColoringValue *color; 3212ee4f033dSBarry Smith 3213ee4f033dSBarry Smith PetscFunctionBegin; 3214e005ede5SBarry Smith if (!a->coloring) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix"); 3215ee4f033dSBarry Smith color = a->coloring->colors; 3216ee4f033dSBarry Smith /* loop over rows */ 3217ee4f033dSBarry Smith for (i=0; i<m; i++) { 3218ee4f033dSBarry Smith nz = ii[i+1] - ii[i]; 3219ee4f033dSBarry Smith /* loop over columns putting computed value into matrix */ 3220ee4f033dSBarry Smith for (j=0; j<nz; j++) { 3221ee4f033dSBarry Smith *v++ = values[color[*jj++]]; 3222ee4f033dSBarry Smith } 3223ee4f033dSBarry Smith values += nl; /* jump to next row of derivatives */ 3224cc8ba8e1SBarry Smith } 3225cc8ba8e1SBarry Smith PetscFunctionReturn(0); 3226cc8ba8e1SBarry Smith } 322736db0b34SBarry Smith 3228