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__ 14*79299369SBarry Smith #define __FUNCT__ "MatDiagonalSet_SeqAIJ" 15*79299369SBarry Smith /* only works if matrix has a full set of diagonal entries */ 16*79299369SBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is) 17*79299369SBarry Smith { 18*79299369SBarry Smith PetscErrorCode ierr; 19*79299369SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) Y->data; 20*79299369SBarry Smith PetscInt i,*diag, m = Y->m; 21*79299369SBarry Smith PetscScalar *v,*aa = aij->a; 22*79299369SBarry Smith 23*79299369SBarry Smith PetscFunctionBegin; 24*79299369SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(Y);CHKERRQ(ierr); 25*79299369SBarry Smith diag = aij->diag; 26*79299369SBarry Smith ierr = VecGetArray(D,&v);CHKERRQ(ierr); 27*79299369SBarry Smith if (is == INSERT_VALUES) { 28*79299369SBarry Smith for (i=0; i<m; i++) { 29*79299369SBarry Smith aa[diag[i]] = v[i]; 30*79299369SBarry Smith } 31*79299369SBarry Smith } else { 32*79299369SBarry Smith for (i=0; i<m; i++) { 33*79299369SBarry Smith aa[diag[i]] += v[i]; 34*79299369SBarry Smith } 35*79299369SBarry Smith } 36*79299369SBarry Smith ierr = VecRestoreArray(D,&v);CHKERRQ(ierr); 37*79299369SBarry Smith PetscFunctionReturn(0); 38*79299369SBarry Smith } 39*79299369SBarry Smith 40*79299369SBarry 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; 867aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 86897952fefSHong Zhang PetscInt n,i,jrow,j,*ridx=PETSC_NULL; 869362ced78SSatish Balay PetscScalar sum; 87097952fefSHong Zhang PetscTruth usecprow=a->compressedrow.use; 871e36a17ebSSatish Balay #endif 87217ab2063SBarry Smith 873b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 87497952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 875fee21e36SBarry Smith #endif 876fee21e36SBarry Smith 8773a40ed3dSBarry Smith PetscFunctionBegin; 8781ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 8791ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 88097952fefSHong Zhang aj = a->j; 88197952fefSHong Zhang aa = a->a; 882416022c9SBarry Smith ii = a->i; 8834eb6d288SHong Zhang if (usecprow){ /* use compressed row format */ 88497952fefSHong Zhang m = a->compressedrow.nrows; 88597952fefSHong Zhang ii = a->compressedrow.i; 88697952fefSHong Zhang ridx = a->compressedrow.rindex; 88797952fefSHong Zhang for (i=0; i<m; i++){ 88897952fefSHong Zhang n = ii[i+1] - ii[i]; 88997952fefSHong Zhang aj = a->j + ii[i]; 89097952fefSHong Zhang aa = a->a + ii[i]; 89197952fefSHong Zhang sum = 0.0; 89297952fefSHong Zhang for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; 89397952fefSHong Zhang y[*ridx++] = sum; 89497952fefSHong Zhang } 89597952fefSHong Zhang } else { /* do not use compressed row format */ 896b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 897b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 898b05257ddSBarry Smith #else 89917ab2063SBarry Smith for (i=0; i<m; i++) { 9009ea0dfa2SSatish Balay jrow = ii[i]; 9019ea0dfa2SSatish Balay n = ii[i+1] - jrow; 90217ab2063SBarry Smith sum = 0.0; 9039ea0dfa2SSatish Balay for (j=0; j<n; j++) { 90497952fefSHong Zhang sum += aa[jrow]*x[aj[jrow]]; jrow++; 9059ea0dfa2SSatish Balay } 90617ab2063SBarry Smith y[i] = sum; 90717ab2063SBarry Smith } 9088d195f9aSBarry Smith #endif 909b05257ddSBarry Smith } 910efee365bSSatish Balay ierr = PetscLogFlops(2*a->nz - m);CHKERRQ(ierr); 9111ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 9121ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 9133a40ed3dSBarry Smith PetscFunctionReturn(0); 91417ab2063SBarry Smith } 91517ab2063SBarry Smith 9164a2ae208SSatish Balay #undef __FUNCT__ 9174a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ" 918dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 91917ab2063SBarry Smith { 920416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 92197952fefSHong Zhang PetscScalar *x,*y,*z,*aa; 922dfbe8321SBarry Smith PetscErrorCode ierr; 92397952fefSHong Zhang PetscInt m = A->m,*aj,*ii; 924aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 92597952fefSHong Zhang PetscInt n,i,jrow,j,*ridx=PETSC_NULL; 926362ced78SSatish Balay PetscScalar sum; 92797952fefSHong Zhang PetscTruth usecprow=a->compressedrow.use; 928e36a17ebSSatish Balay #endif 9299ea0dfa2SSatish Balay 9303a40ed3dSBarry Smith PetscFunctionBegin; 9311ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 9321ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 9332e8a6d31SBarry Smith if (zz != yy) { 9341ebc52fbSHong Zhang ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 9352e8a6d31SBarry Smith } else { 9362e8a6d31SBarry Smith z = y; 9372e8a6d31SBarry Smith } 938bfeeae90SHong Zhang 93997952fefSHong Zhang aj = a->j; 94097952fefSHong Zhang aa = a->a; 941cddf8d76SBarry Smith ii = a->i; 942aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 94397952fefSHong Zhang fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 94402ab625aSSatish Balay #else 9454eb6d288SHong Zhang if (usecprow){ /* use compressed row format */ 9464eb6d288SHong Zhang if (zz != yy){ 9474eb6d288SHong Zhang ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 9484eb6d288SHong Zhang } 94997952fefSHong Zhang m = a->compressedrow.nrows; 95097952fefSHong Zhang ii = a->compressedrow.i; 95197952fefSHong Zhang ridx = a->compressedrow.rindex; 95297952fefSHong Zhang for (i=0; i<m; i++){ 95397952fefSHong Zhang n = ii[i+1] - ii[i]; 95497952fefSHong Zhang aj = a->j + ii[i]; 95597952fefSHong Zhang aa = a->a + ii[i]; 95697952fefSHong Zhang sum = y[*ridx]; 95797952fefSHong Zhang for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; 95897952fefSHong Zhang z[*ridx++] = sum; 95997952fefSHong Zhang } 96097952fefSHong Zhang } else { /* do not use compressed row format */ 96117ab2063SBarry Smith for (i=0; i<m; i++) { 9629ea0dfa2SSatish Balay jrow = ii[i]; 9639ea0dfa2SSatish Balay n = ii[i+1] - jrow; 96417ab2063SBarry Smith sum = y[i]; 9659ea0dfa2SSatish Balay for (j=0; j<n; j++) { 96697952fefSHong Zhang sum += aa[jrow]*x[aj[jrow]]; jrow++; 9679ea0dfa2SSatish Balay } 96817ab2063SBarry Smith z[i] = sum; 96917ab2063SBarry Smith } 97097952fefSHong Zhang } 97102ab625aSSatish Balay #endif 972efee365bSSatish Balay ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr); 9731ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 9741ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 9752e8a6d31SBarry Smith if (zz != yy) { 9761ebc52fbSHong Zhang ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 9772e8a6d31SBarry Smith } 9783a40ed3dSBarry Smith PetscFunctionReturn(0); 97917ab2063SBarry Smith } 98017ab2063SBarry Smith 98117ab2063SBarry Smith /* 98217ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 98317ab2063SBarry Smith */ 9844a2ae208SSatish Balay #undef __FUNCT__ 9854a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ" 986dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 98717ab2063SBarry Smith { 988416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 9896849ba73SBarry Smith PetscErrorCode ierr; 99097f1f81fSBarry Smith PetscInt i,j,*diag,m = A->m; 99117ab2063SBarry Smith 9923a40ed3dSBarry Smith PetscFunctionBegin; 993f1e2ffcdSBarry Smith if (a->diag) PetscFunctionReturn(0); 994f1e2ffcdSBarry Smith 99597f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&diag);CHKERRQ(ierr); 99652e6d16bSBarry Smith ierr = PetscLogObjectMemory(A,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 997273d9f13SBarry Smith for (i=0; i<A->m; i++) { 99835b0346bSBarry Smith diag[i] = a->i[i+1]; 999bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1000bfeeae90SHong Zhang if (a->j[j] == i) { 1001bfeeae90SHong Zhang diag[i] = j; 100217ab2063SBarry Smith break; 100317ab2063SBarry Smith } 100417ab2063SBarry Smith } 100517ab2063SBarry Smith } 1006416022c9SBarry Smith a->diag = diag; 10073a40ed3dSBarry Smith PetscFunctionReturn(0); 100817ab2063SBarry Smith } 100917ab2063SBarry Smith 1010be5855fcSBarry Smith /* 1011be5855fcSBarry Smith Checks for missing diagonals 1012be5855fcSBarry Smith */ 10134a2ae208SSatish Balay #undef __FUNCT__ 10144a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ" 1015dfbe8321SBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A) 1016be5855fcSBarry Smith { 1017be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 10186849ba73SBarry Smith PetscErrorCode ierr; 101997f1f81fSBarry Smith PetscInt *diag,*jj = a->j,i; 1020be5855fcSBarry Smith 1021be5855fcSBarry Smith PetscFunctionBegin; 1022f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1023f1e2ffcdSBarry Smith diag = a->diag; 1024273d9f13SBarry Smith for (i=0; i<A->m; i++) { 1025bfeeae90SHong Zhang if (jj[diag[i]] != i) { 102677431f27SBarry Smith SETERRQ1(PETSC_ERR_PLIB,"Matrix is missing diagonal number %D",i); 1027be5855fcSBarry Smith } 1028be5855fcSBarry Smith } 1029be5855fcSBarry Smith PetscFunctionReturn(0); 1030be5855fcSBarry Smith } 1031be5855fcSBarry Smith 10324a2ae208SSatish Balay #undef __FUNCT__ 10334a2ae208SSatish Balay #define __FUNCT__ "MatRelax_SeqAIJ" 103497f1f81fSBarry Smith PetscErrorCode MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 103517ab2063SBarry Smith { 1036416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1037beeb8507SBarry Smith PetscScalar *x,d,*xs,sum,*t,scale,*idiag=0,*mdiag; 1038beeb8507SBarry Smith const PetscScalar *v = a->a, *b, *bs,*xb, *ts; 1039dfbe8321SBarry Smith PetscErrorCode ierr; 104097f1f81fSBarry Smith PetscInt n = A->n,m = A->m,i; 104197f1f81fSBarry Smith const PetscInt *idx,*diag; 104217ab2063SBarry Smith 10433a40ed3dSBarry Smith PetscFunctionBegin; 1044b965ef7fSBarry Smith its = its*lits; 104577431f27SBarry Smith if (its <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D and local its %D both positive",its,lits); 104691723122SBarry Smith 1047ed480e8bSBarry Smith if (!a->diag) {ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);} 1048ed480e8bSBarry Smith diag = a->diag; 1049ed480e8bSBarry Smith if (!a->idiag) { 1050ed480e8bSBarry Smith ierr = PetscMalloc(3*m*sizeof(PetscScalar),&a->idiag);CHKERRQ(ierr); 1051ed480e8bSBarry Smith a->ssor = a->idiag + m; 1052ed480e8bSBarry Smith mdiag = a->ssor + m; 1053ed480e8bSBarry Smith 1054ed480e8bSBarry Smith v = a->a; 1055ed480e8bSBarry Smith 1056ed480e8bSBarry Smith /* this is wrong when fshift omega changes each iteration */ 1057958c9bccSBarry Smith if (omega == 1.0 && !fshift) { 1058ed480e8bSBarry Smith for (i=0; i<m; i++) { 1059ed480e8bSBarry Smith mdiag[i] = v[diag[i]]; 1060ed480e8bSBarry Smith a->idiag[i] = 1.0/v[diag[i]]; 1061ed480e8bSBarry Smith } 1062efee365bSSatish Balay ierr = PetscLogFlops(m);CHKERRQ(ierr); 1063ed480e8bSBarry Smith } else { 1064ed480e8bSBarry Smith for (i=0; i<m; i++) { 1065ed480e8bSBarry Smith mdiag[i] = v[diag[i]]; 1066beeb8507SBarry Smith a->idiag[i] = omega/(fshift + v[diag[i]]); 1067ed480e8bSBarry Smith } 1068efee365bSSatish Balay ierr = PetscLogFlops(2*m);CHKERRQ(ierr); 1069beeb8507SBarry Smith } 1070ed480e8bSBarry Smith } 1071ed480e8bSBarry Smith t = a->ssor; 1072ed480e8bSBarry Smith idiag = a->idiag; 1073ed480e8bSBarry Smith mdiag = a->idiag + 2*m; 1074ed480e8bSBarry Smith 10751ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 1076fb2e594dSBarry Smith if (xx != bb) { 10771ebc52fbSHong Zhang ierr = VecGetArray(bb,(PetscScalar**)&b);CHKERRQ(ierr); 1078fb2e594dSBarry Smith } else { 1079fb2e594dSBarry Smith b = x; 1080fb2e594dSBarry Smith } 1081fb2e594dSBarry Smith 1082ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 1083ed480e8bSBarry Smith xs = x; 108417ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 108517ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1086ed480e8bSBarry Smith bs = b; 108717ab2063SBarry Smith for (i=0; i<m; i++) { 1088ed480e8bSBarry Smith d = fshift + a->a[diag[i]]; 1089416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1090ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1091ed480e8bSBarry Smith v = a->a + diag[i] + 1; 109217ab2063SBarry Smith sum = b[i]*d/omega; 109317ab2063SBarry Smith SPARSEDENSEDOT(sum,bs,v,idx,n); 109417ab2063SBarry Smith x[i] = sum; 109517ab2063SBarry Smith } 10961ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 10971ebc52fbSHong Zhang if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);} 1098efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 10993a40ed3dSBarry Smith PetscFunctionReturn(0); 110017ab2063SBarry Smith } 1101c783ea89SBarry Smith 1102ed480e8bSBarry Smith 1103fc3d8934SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1104fc3d8934SBarry Smith U is upper triangular, E is diagonal; This routine applies 1105fc3d8934SBarry Smith 1106fc3d8934SBarry Smith (L + E)^{-1} A (U + E)^{-1} 1107fc3d8934SBarry Smith 1108fc3d8934SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 1109fc3d8934SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 111048af12d7SBarry Smith is the relaxation factor. 1111fc3d8934SBarry Smith */ 1112fc3d8934SBarry Smith 111348af12d7SBarry Smith if (flag == SOR_APPLY_LOWER) { 111429bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 11153a40ed3dSBarry Smith } else if (flag & SOR_EISENSTAT) { 111617ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 111717ab2063SBarry Smith U is upper triangular, E is diagonal; This routine applies 111817ab2063SBarry Smith 111917ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 112017ab2063SBarry Smith 112117ab2063SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 112217ab2063SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 112317ab2063SBarry Smith is the relaxation factor. 112417ab2063SBarry Smith */ 112517ab2063SBarry Smith scale = (2.0/omega) - 1.0; 112617ab2063SBarry Smith 112717ab2063SBarry Smith /* x = (E + U)^{-1} b */ 112817ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1129416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1130ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1131ed480e8bSBarry Smith v = a->a + diag[i] + 1; 113217ab2063SBarry Smith sum = b[i]; 113317ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1134ed480e8bSBarry Smith x[i] = sum*idiag[i]; 113517ab2063SBarry Smith } 113617ab2063SBarry Smith 113717ab2063SBarry Smith /* t = b - (2*E - D)x */ 1138416022c9SBarry Smith v = a->a; 1139ed480e8bSBarry Smith for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; } 114017ab2063SBarry Smith 114117ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1142ed480e8bSBarry Smith ts = t; 1143416022c9SBarry Smith diag = a->diag; 114417ab2063SBarry Smith for (i=0; i<m; i++) { 1145416022c9SBarry Smith n = diag[i] - a->i[i]; 1146ed480e8bSBarry Smith idx = a->j + a->i[i]; 1147ed480e8bSBarry Smith v = a->a + a->i[i]; 114817ab2063SBarry Smith sum = t[i]; 114917ab2063SBarry Smith SPARSEDENSEMDOT(sum,ts,v,idx,n); 1150ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1151733d66baSBarry Smith /* x = x + t */ 1152733d66baSBarry Smith x[i] += t[i]; 115317ab2063SBarry Smith } 115417ab2063SBarry Smith 1155efee365bSSatish Balay ierr = PetscLogFlops(6*m-1 + 2*a->nz);CHKERRQ(ierr); 11561ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 11571ebc52fbSHong Zhang if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);} 11583a40ed3dSBarry Smith PetscFunctionReturn(0); 115917ab2063SBarry Smith } 116017ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 116117ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 116277d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 116397f1f81fSBarry Smith fortranrelaxaijforwardzero_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,idiag,a->a,(void*)b); 116477d8c4bbSBarry Smith #else 116517ab2063SBarry Smith for (i=0; i<m; i++) { 1166416022c9SBarry Smith n = diag[i] - a->i[i]; 1167ed480e8bSBarry Smith idx = a->j + a->i[i]; 1168ed480e8bSBarry Smith v = a->a + a->i[i]; 116917ab2063SBarry Smith sum = b[i]; 117017ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1171ed480e8bSBarry Smith x[i] = sum*idiag[i]; 117217ab2063SBarry Smith } 117377d8c4bbSBarry Smith #endif 117417ab2063SBarry Smith xb = x; 1175efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 11763a40ed3dSBarry Smith } else xb = b; 117717ab2063SBarry Smith if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) && 117817ab2063SBarry Smith (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) { 117917ab2063SBarry Smith for (i=0; i<m; i++) { 1180ed480e8bSBarry Smith x[i] *= mdiag[i]; 118117ab2063SBarry Smith } 1182efee365bSSatish Balay ierr = PetscLogFlops(m);CHKERRQ(ierr); 118317ab2063SBarry Smith } 118417ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 118577d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 118697f1f81fSBarry Smith fortranrelaxaijbackwardzero_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,idiag,a->a,(void*)xb); 118777d8c4bbSBarry Smith #else 118817ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1189416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1190ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1191ed480e8bSBarry Smith v = a->a + diag[i] + 1; 119217ab2063SBarry Smith sum = xb[i]; 119317ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1194ed480e8bSBarry Smith x[i] = sum*idiag[i]; 119517ab2063SBarry Smith } 119677d8c4bbSBarry Smith #endif 1197efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 119817ab2063SBarry Smith } 119917ab2063SBarry Smith its--; 120017ab2063SBarry Smith } 120117ab2063SBarry Smith while (its--) { 120217ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 120377d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 120497f1f81fSBarry Smith fortranrelaxaijforward_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,a->a,(void*)b); 120577d8c4bbSBarry Smith #else 120617ab2063SBarry Smith for (i=0; i<m; i++) { 1207ed480e8bSBarry Smith d = fshift + a->a[diag[i]]; 1208416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1209ed480e8bSBarry Smith idx = a->j + a->i[i]; 1210ed480e8bSBarry Smith v = a->a + a->i[i]; 121117ab2063SBarry Smith sum = b[i]; 121217ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1213ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 121417ab2063SBarry Smith } 121577d8c4bbSBarry Smith #endif 1216efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 121717ab2063SBarry Smith } 121817ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 121977d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 122097f1f81fSBarry Smith fortranrelaxaijbackward_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,a->a,(void*)b); 122177d8c4bbSBarry Smith #else 122217ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1223ed480e8bSBarry Smith d = fshift + a->a[diag[i]]; 1224416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1225ed480e8bSBarry Smith idx = a->j + a->i[i]; 1226ed480e8bSBarry Smith v = a->a + a->i[i]; 122717ab2063SBarry Smith sum = b[i]; 122817ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1229ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 123017ab2063SBarry Smith } 123177d8c4bbSBarry Smith #endif 1232efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 123317ab2063SBarry Smith } 123417ab2063SBarry Smith } 12351ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 12361ebc52fbSHong Zhang if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);} 12373a40ed3dSBarry Smith PetscFunctionReturn(0); 123817ab2063SBarry Smith } 123917ab2063SBarry Smith 12404a2ae208SSatish Balay #undef __FUNCT__ 12414a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ" 1242dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 124317ab2063SBarry Smith { 1244416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 12454e220ebcSLois Curfman McInnes 12463a40ed3dSBarry Smith PetscFunctionBegin; 1247273d9f13SBarry Smith info->rows_global = (double)A->m; 1248273d9f13SBarry Smith info->columns_global = (double)A->n; 1249273d9f13SBarry Smith info->rows_local = (double)A->m; 1250273d9f13SBarry Smith info->columns_local = (double)A->n; 12514e220ebcSLois Curfman McInnes info->block_size = 1.0; 12524e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 12534e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 12544e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 12554e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 12564e220ebcSLois Curfman McInnes info->mallocs = (double)a->reallocs; 12574e220ebcSLois Curfman McInnes info->memory = A->mem; 12584e220ebcSLois Curfman McInnes if (A->factor) { 12594e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 12604e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 12614e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 12624e220ebcSLois Curfman McInnes } else { 12634e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 12644e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 12654e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 12664e220ebcSLois Curfman McInnes } 12673a40ed3dSBarry Smith PetscFunctionReturn(0); 126817ab2063SBarry Smith } 126917ab2063SBarry Smith 12704a2ae208SSatish Balay #undef __FUNCT__ 12714a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ" 1272f4df32b1SMatthew Knepley PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag) 127317ab2063SBarry Smith { 1274416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1275f4df32b1SMatthew Knepley PetscInt i,m = A->m - 1; 12766849ba73SBarry Smith PetscErrorCode ierr; 127717ab2063SBarry Smith 12783a40ed3dSBarry Smith PetscFunctionBegin; 1279f1e2ffcdSBarry Smith if (a->keepzeroedrows) { 1280f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 128177431f27SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1282bfeeae90SHong Zhang ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 1283f1e2ffcdSBarry Smith } 1284f4df32b1SMatthew Knepley if (diag != 0.0) { 1285f1e2ffcdSBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1286f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1287f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1288f4df32b1SMatthew Knepley a->a[a->diag[rows[i]]] = diag; 1289f1e2ffcdSBarry Smith } 1290f1e2ffcdSBarry Smith } 129188e51ccdSHong Zhang A->same_nonzero = PETSC_TRUE; 1292f1e2ffcdSBarry Smith } else { 1293f4df32b1SMatthew Knepley if (diag != 0.0) { 129417ab2063SBarry Smith for (i=0; i<N; i++) { 129577431f27SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 12967ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1297416022c9SBarry Smith a->ilen[rows[i]] = 1; 1298f4df32b1SMatthew Knepley a->a[a->i[rows[i]]] = diag; 1299bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 13007ae801bdSBarry Smith } else { /* in case row was completely empty */ 1301f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 130217ab2063SBarry Smith } 130317ab2063SBarry Smith } 13043a40ed3dSBarry Smith } else { 130517ab2063SBarry Smith for (i=0; i<N; i++) { 130677431f27SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1307416022c9SBarry Smith a->ilen[rows[i]] = 0; 130817ab2063SBarry Smith } 130917ab2063SBarry Smith } 131088e51ccdSHong Zhang A->same_nonzero = PETSC_FALSE; 1311f1e2ffcdSBarry Smith } 131243a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13133a40ed3dSBarry Smith PetscFunctionReturn(0); 131417ab2063SBarry Smith } 131517ab2063SBarry Smith 13164a2ae208SSatish Balay #undef __FUNCT__ 13174a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ" 131897f1f81fSBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 131917ab2063SBarry Smith { 1320416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 132197f1f81fSBarry Smith PetscInt *itmp; 132217ab2063SBarry Smith 13233a40ed3dSBarry Smith PetscFunctionBegin; 132477431f27SBarry Smith if (row < 0 || row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 132517ab2063SBarry Smith 1326416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1327bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 132817ab2063SBarry Smith if (idx) { 1329bfeeae90SHong Zhang itmp = a->j + a->i[row]; 1330bfeeae90SHong Zhang if (*nz) { 13314e093b46SBarry Smith *idx = itmp; 133217ab2063SBarry Smith } 133317ab2063SBarry Smith else *idx = 0; 133417ab2063SBarry Smith } 13353a40ed3dSBarry Smith PetscFunctionReturn(0); 133617ab2063SBarry Smith } 133717ab2063SBarry Smith 1338bfeeae90SHong Zhang /* remove this function? */ 13394a2ae208SSatish Balay #undef __FUNCT__ 13404a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ" 134197f1f81fSBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 134217ab2063SBarry Smith { 13433a40ed3dSBarry Smith PetscFunctionBegin; 13443a40ed3dSBarry Smith PetscFunctionReturn(0); 134517ab2063SBarry Smith } 134617ab2063SBarry Smith 13474a2ae208SSatish Balay #undef __FUNCT__ 13484a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ" 1349dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 135017ab2063SBarry Smith { 1351416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 135287828ca2SBarry Smith PetscScalar *v = a->a; 135336db0b34SBarry Smith PetscReal sum = 0.0; 13546849ba73SBarry Smith PetscErrorCode ierr; 135597f1f81fSBarry Smith PetscInt i,j; 135617ab2063SBarry Smith 13573a40ed3dSBarry Smith PetscFunctionBegin; 135817ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1359416022c9SBarry Smith for (i=0; i<a->nz; i++) { 1360aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 136136db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 136217ab2063SBarry Smith #else 136317ab2063SBarry Smith sum += (*v)*(*v); v++; 136417ab2063SBarry Smith #endif 136517ab2063SBarry Smith } 1366064f8208SBarry Smith *nrm = sqrt(sum); 13673a40ed3dSBarry Smith } else if (type == NORM_1) { 136836db0b34SBarry Smith PetscReal *tmp; 136997f1f81fSBarry Smith PetscInt *jj = a->j; 1370b0a32e0cSBarry Smith ierr = PetscMalloc((A->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr); 1371273d9f13SBarry Smith ierr = PetscMemzero(tmp,A->n*sizeof(PetscReal));CHKERRQ(ierr); 1372064f8208SBarry Smith *nrm = 0.0; 1373416022c9SBarry Smith for (j=0; j<a->nz; j++) { 1374bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 137517ab2063SBarry Smith } 1376273d9f13SBarry Smith for (j=0; j<A->n; j++) { 1377064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 137817ab2063SBarry Smith } 1379606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 13803a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1381064f8208SBarry Smith *nrm = 0.0; 1382273d9f13SBarry Smith for (j=0; j<A->m; j++) { 1383bfeeae90SHong Zhang v = a->a + a->i[j]; 138417ab2063SBarry Smith sum = 0.0; 1385416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 1386cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 138717ab2063SBarry Smith } 1388064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 138917ab2063SBarry Smith } 13903a40ed3dSBarry Smith } else { 139129bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"No support for two norm"); 139217ab2063SBarry Smith } 13933a40ed3dSBarry Smith PetscFunctionReturn(0); 139417ab2063SBarry Smith } 139517ab2063SBarry Smith 13964a2ae208SSatish Balay #undef __FUNCT__ 13974a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ" 1398dfbe8321SBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,Mat *B) 139917ab2063SBarry Smith { 1400416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1401416022c9SBarry Smith Mat C; 14026849ba73SBarry Smith PetscErrorCode ierr; 140397f1f81fSBarry Smith PetscInt i,*aj = a->j,*ai = a->i,m = A->m,len,*col; 140487828ca2SBarry Smith PetscScalar *array = a->a; 140517ab2063SBarry Smith 14063a40ed3dSBarry Smith PetscFunctionBegin; 1407273d9f13SBarry Smith if (!B && m != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Square matrix only for in-place"); 140897f1f81fSBarry Smith ierr = PetscMalloc((1+A->n)*sizeof(PetscInt),&col);CHKERRQ(ierr); 140997f1f81fSBarry Smith ierr = PetscMemzero(col,(1+A->n)*sizeof(PetscInt));CHKERRQ(ierr); 1410bfeeae90SHong Zhang 1411bfeeae90SHong Zhang for (i=0; i<ai[m]; i++) col[aj[i]] += 1; 1412f69a0ea3SMatthew Knepley ierr = MatCreate(A->comm,&C);CHKERRQ(ierr); 1413f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,A->n,m,A->n,m);CHKERRQ(ierr); 1414f204ca49SKris Buschelman ierr = MatSetType(C,A->type_name);CHKERRQ(ierr); 1415ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr); 1416606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 141717ab2063SBarry Smith for (i=0; i<m; i++) { 141817ab2063SBarry Smith len = ai[i+1]-ai[i]; 1419416022c9SBarry Smith ierr = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 1420b9b97703SBarry Smith array += len; 1421b9b97703SBarry Smith aj += len; 142217ab2063SBarry Smith } 142317ab2063SBarry Smith 14246d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14256d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 142617ab2063SBarry Smith 1427f1e2ffcdSBarry Smith if (B) { 1428416022c9SBarry Smith *B = C; 142917ab2063SBarry Smith } else { 1430273d9f13SBarry Smith ierr = MatHeaderCopy(A,C);CHKERRQ(ierr); 143117ab2063SBarry Smith } 14323a40ed3dSBarry Smith PetscFunctionReturn(0); 143317ab2063SBarry Smith } 143417ab2063SBarry Smith 1435cd0d46ebSvictorle EXTERN_C_BEGIN 1436cd0d46ebSvictorle #undef __FUNCT__ 14375fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ" 1438be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscTruth *f) 1439cd0d46ebSvictorle { 1440cd0d46ebSvictorle Mat_SeqAIJ *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data; 144197f1f81fSBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; PetscScalar *va,*vb; 14426849ba73SBarry Smith PetscErrorCode ierr; 144397f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 1444cd0d46ebSvictorle 1445cd0d46ebSvictorle PetscFunctionBegin; 1446cd0d46ebSvictorle bij = (Mat_SeqAIJ *) B->data; 1447cd0d46ebSvictorle 1448cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 1449cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 14505485867bSBarry Smith if (ma!=nb || na!=mb){ 14515485867bSBarry Smith *f = PETSC_FALSE; 14525485867bSBarry Smith PetscFunctionReturn(0); 14535485867bSBarry Smith } 1454cd0d46ebSvictorle aii = aij->i; bii = bij->i; 1455cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 1456cd0d46ebSvictorle va = aij->a; vb = bij->a; 145797f1f81fSBarry Smith ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr); 145897f1f81fSBarry Smith ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr); 1459cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 1460cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 1461cd0d46ebSvictorle 1462cd0d46ebSvictorle *f = PETSC_TRUE; 1463cd0d46ebSvictorle for (i=0; i<ma; i++) { 1464cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 146597f1f81fSBarry Smith PetscInt idc,idr; 14665485867bSBarry Smith PetscScalar vc,vr; 1467cd0d46ebSvictorle /* column/row index/value */ 14685485867bSBarry Smith idc = adx[aptr[i]]; 14695485867bSBarry Smith idr = bdx[bptr[idc]]; 14705485867bSBarry Smith vc = va[aptr[i]]; 14715485867bSBarry Smith vr = vb[bptr[idc]]; 14725485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 14735485867bSBarry Smith *f = PETSC_FALSE; 14745485867bSBarry Smith goto done; 1475cd0d46ebSvictorle } else { 14765485867bSBarry Smith aptr[i]++; 14775485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 1478cd0d46ebSvictorle } 1479cd0d46ebSvictorle } 1480cd0d46ebSvictorle } 1481cd0d46ebSvictorle done: 1482cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 14833aeef889SHong Zhang if (B) { 14843aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 14853aeef889SHong Zhang } 1486cd0d46ebSvictorle PetscFunctionReturn(0); 1487cd0d46ebSvictorle } 1488cd0d46ebSvictorle EXTERN_C_END 1489cd0d46ebSvictorle 14909e29f15eSvictorle #undef __FUNCT__ 14919e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ" 1492dfbe8321SBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscTruth *f) 14939e29f15eSvictorle { 1494dfbe8321SBarry Smith PetscErrorCode ierr; 14959e29f15eSvictorle PetscFunctionBegin; 14965485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 14979e29f15eSvictorle PetscFunctionReturn(0); 14989e29f15eSvictorle } 14999e29f15eSvictorle 15004a2ae208SSatish Balay #undef __FUNCT__ 15014a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ" 1502dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 150317ab2063SBarry Smith { 1504416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 150587828ca2SBarry Smith PetscScalar *l,*r,x,*v; 1506dfbe8321SBarry Smith PetscErrorCode ierr; 150797f1f81fSBarry Smith PetscInt i,j,m = A->m,n = A->n,M,nz = a->nz,*jj; 150817ab2063SBarry Smith 15093a40ed3dSBarry Smith PetscFunctionBegin; 151017ab2063SBarry Smith if (ll) { 15113ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 15123ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 1513e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 1514273d9f13SBarry Smith if (m != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 15151ebc52fbSHong Zhang ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 1516416022c9SBarry Smith v = a->a; 151717ab2063SBarry Smith for (i=0; i<m; i++) { 151817ab2063SBarry Smith x = l[i]; 1519416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 152017ab2063SBarry Smith for (j=0; j<M; j++) { (*v++) *= x;} 152117ab2063SBarry Smith } 15221ebc52fbSHong Zhang ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 1523efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 152417ab2063SBarry Smith } 152517ab2063SBarry Smith if (rr) { 1526e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 1527273d9f13SBarry Smith if (n != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 15281ebc52fbSHong Zhang ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 1529416022c9SBarry Smith v = a->a; jj = a->j; 153017ab2063SBarry Smith for (i=0; i<nz; i++) { 1531bfeeae90SHong Zhang (*v++) *= r[*jj++]; 153217ab2063SBarry Smith } 15331ebc52fbSHong Zhang ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 1534efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 153517ab2063SBarry Smith } 15363a40ed3dSBarry Smith PetscFunctionReturn(0); 153717ab2063SBarry Smith } 153817ab2063SBarry Smith 15394a2ae208SSatish Balay #undef __FUNCT__ 15404a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ" 154197f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 154217ab2063SBarry Smith { 1543db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 15446849ba73SBarry Smith PetscErrorCode ierr; 154597f1f81fSBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->n,*lens; 154697f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 154797f1f81fSBarry Smith PetscInt *irow,*icol,nrows,ncols; 154897f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 154987828ca2SBarry Smith PetscScalar *a_new,*mat_a; 1550416022c9SBarry Smith Mat C; 1551fee21e36SBarry Smith PetscTruth stride; 155217ab2063SBarry Smith 15533a40ed3dSBarry Smith PetscFunctionBegin; 1554d64ed03dSBarry Smith ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr); 155529bbc08cSBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted"); 1556d64ed03dSBarry Smith ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr); 155729bbc08cSBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted"); 155899141d43SSatish Balay 155917ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 1560b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 1561b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 156217ab2063SBarry Smith 1563fee21e36SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 1564fee21e36SBarry Smith ierr = ISStride(iscol,&stride);CHKERRQ(ierr); 1565fee21e36SBarry Smith if (stride && step == 1) { 156602834360SBarry Smith /* special case of contiguous rows */ 156797f1f81fSBarry Smith ierr = PetscMalloc((2*nrows+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 156831ebf83bSSatish Balay starts = lens + nrows; 156902834360SBarry Smith /* loop over new rows determining lens and starting points */ 157002834360SBarry Smith for (i=0; i<nrows; i++) { 1571bfeeae90SHong Zhang kstart = ai[irow[i]]; 1572a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 157302834360SBarry Smith for (k=kstart; k<kend; k++) { 1574bfeeae90SHong Zhang if (aj[k] >= first) { 157502834360SBarry Smith starts[i] = k; 157602834360SBarry Smith break; 157702834360SBarry Smith } 157802834360SBarry Smith } 1579a2744918SBarry Smith sum = 0; 158002834360SBarry Smith while (k < kend) { 1581bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 1582a2744918SBarry Smith sum++; 158302834360SBarry Smith } 1584a2744918SBarry Smith lens[i] = sum; 158502834360SBarry Smith } 158602834360SBarry Smith /* create submatrix */ 1587cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 158897f1f81fSBarry Smith PetscInt n_cols,n_rows; 158908480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 159029bbc08cSBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 1591d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 159208480c60SBarry Smith C = *B; 15933a40ed3dSBarry Smith } else { 1594f69a0ea3SMatthew Knepley ierr = MatCreate(A->comm,&C);CHKERRQ(ierr); 1595f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 1596e2d9671bSKris Buschelman ierr = MatSetType(C,A->type_name);CHKERRQ(ierr); 1597ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 159808480c60SBarry Smith } 1599db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 1600db02288aSLois Curfman McInnes 160102834360SBarry Smith /* loop over rows inserting into submatrix */ 1602db02288aSLois Curfman McInnes a_new = c->a; 1603db02288aSLois Curfman McInnes j_new = c->j; 1604db02288aSLois Curfman McInnes i_new = c->i; 1605bfeeae90SHong Zhang 160602834360SBarry Smith for (i=0; i<nrows; i++) { 1607a2744918SBarry Smith ii = starts[i]; 1608a2744918SBarry Smith lensi = lens[i]; 1609a2744918SBarry Smith for (k=0; k<lensi; k++) { 1610a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 161102834360SBarry Smith } 161287828ca2SBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr); 1613a2744918SBarry Smith a_new += lensi; 1614a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 1615a2744918SBarry Smith c->ilen[i] = lensi; 161602834360SBarry Smith } 1617606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 16183a40ed3dSBarry Smith } else { 161902834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 162097f1f81fSBarry Smith ierr = PetscMalloc((1+oldcols)*sizeof(PetscInt),&smap);CHKERRQ(ierr); 1621bfeeae90SHong Zhang 162297f1f81fSBarry Smith ierr = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 162397f1f81fSBarry Smith ierr = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr); 162417ab2063SBarry Smith for (i=0; i<ncols; i++) smap[icol[i]] = i+1; 162502834360SBarry Smith /* determine lens of each row */ 162602834360SBarry Smith for (i=0; i<nrows; i++) { 1627bfeeae90SHong Zhang kstart = ai[irow[i]]; 162802834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 162902834360SBarry Smith lens[i] = 0; 163002834360SBarry Smith for (k=kstart; k<kend; k++) { 1631bfeeae90SHong Zhang if (smap[aj[k]]) { 163202834360SBarry Smith lens[i]++; 163302834360SBarry Smith } 163402834360SBarry Smith } 163502834360SBarry Smith } 163617ab2063SBarry Smith /* Create and fill new matrix */ 1637a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 16380f5bd95cSBarry Smith PetscTruth equal; 16390f5bd95cSBarry Smith 164099141d43SSatish Balay c = (Mat_SeqAIJ *)((*B)->data); 1641273d9f13SBarry Smith if ((*B)->m != nrows || (*B)->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 164297f1f81fSBarry Smith ierr = PetscMemcmp(c->ilen,lens,(*B)->m*sizeof(PetscInt),&equal);CHKERRQ(ierr); 16430f5bd95cSBarry Smith if (!equal) { 164429bbc08cSBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 164599141d43SSatish Balay } 164697f1f81fSBarry Smith ierr = PetscMemzero(c->ilen,(*B)->m*sizeof(PetscInt));CHKERRQ(ierr); 164708480c60SBarry Smith C = *B; 16483a40ed3dSBarry Smith } else { 1649f69a0ea3SMatthew Knepley ierr = MatCreate(A->comm,&C);CHKERRQ(ierr); 1650f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 1651e2d9671bSKris Buschelman ierr = MatSetType(C,A->type_name);CHKERRQ(ierr); 1652ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 165308480c60SBarry Smith } 165499141d43SSatish Balay c = (Mat_SeqAIJ *)(C->data); 165517ab2063SBarry Smith for (i=0; i<nrows; i++) { 165699141d43SSatish Balay row = irow[i]; 1657bfeeae90SHong Zhang kstart = ai[row]; 165899141d43SSatish Balay kend = kstart + a->ilen[row]; 1659bfeeae90SHong Zhang mat_i = c->i[i]; 166099141d43SSatish Balay mat_j = c->j + mat_i; 166199141d43SSatish Balay mat_a = c->a + mat_i; 166299141d43SSatish Balay mat_ilen = c->ilen + i; 166317ab2063SBarry Smith for (k=kstart; k<kend; k++) { 1664bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 1665ed480e8bSBarry Smith *mat_j++ = tcol - 1; 166699141d43SSatish Balay *mat_a++ = a->a[k]; 166799141d43SSatish Balay (*mat_ilen)++; 166899141d43SSatish Balay 166917ab2063SBarry Smith } 167017ab2063SBarry Smith } 167117ab2063SBarry Smith } 167202834360SBarry Smith /* Free work space */ 167302834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 1674606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 1675606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 167602834360SBarry Smith } 16776d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16786d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 167917ab2063SBarry Smith 168017ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 1681416022c9SBarry Smith *B = C; 16823a40ed3dSBarry Smith PetscFunctionReturn(0); 168317ab2063SBarry Smith } 168417ab2063SBarry Smith 1685a871dcd8SBarry Smith /* 1686a871dcd8SBarry Smith */ 16874a2ae208SSatish Balay #undef __FUNCT__ 16884a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ" 1689dfbe8321SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatFactorInfo *info) 1690a871dcd8SBarry Smith { 169163b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 1692dfbe8321SBarry Smith PetscErrorCode ierr; 169363b91edcSBarry Smith Mat outA; 1694b8a78c4aSBarry Smith PetscTruth row_identity,col_identity; 169563b91edcSBarry Smith 16963a40ed3dSBarry Smith PetscFunctionBegin; 1697d3d32019SBarry Smith if (info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 1698b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 1699b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 1700b8a78c4aSBarry Smith if (!row_identity || !col_identity) { 1701634064b4SBarry Smith SETERRQ(PETSC_ERR_ARG_WRONG,"Row and column permutations must be identity for in-place ILU"); 1702b8a78c4aSBarry Smith } 1703a871dcd8SBarry Smith 170463b91edcSBarry Smith outA = inA; 170563b91edcSBarry Smith inA->factor = FACTOR_LU; 170663b91edcSBarry Smith a->row = row; 170763b91edcSBarry Smith a->col = col; 1708c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1709c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 171063b91edcSBarry Smith 171136db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 1712b9b97703SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */ 17134c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 171452e6d16bSBarry Smith ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr); 1715f0ec6fceSSatish Balay 171694a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 171787828ca2SBarry Smith ierr = PetscMalloc((inA->m+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr); 171894a9d846SBarry Smith } 171963b91edcSBarry Smith 172008480c60SBarry Smith if (!a->diag) { 1721f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 172263b91edcSBarry Smith } 1723af281ebdSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ(inA,info,&outA);CHKERRQ(ierr); 17243a40ed3dSBarry Smith PetscFunctionReturn(0); 1725a871dcd8SBarry Smith } 1726a871dcd8SBarry Smith 1727d9eff348SSatish Balay #include "petscblaslapack.h" 17284a2ae208SSatish Balay #undef __FUNCT__ 17294a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ" 1730f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 1731f0b747eeSBarry Smith { 1732f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 17334ce68768SBarry Smith PetscBLASInt bnz = (PetscBLASInt)a->nz,one = 1; 1734f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 1735efee365bSSatish Balay PetscErrorCode ierr; 1736efee365bSSatish Balay 17373a40ed3dSBarry Smith 17383a40ed3dSBarry Smith PetscFunctionBegin; 1739f4df32b1SMatthew Knepley BLASscal_(&bnz,&oalpha,a->a,&one); 1740efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 17413a40ed3dSBarry Smith PetscFunctionReturn(0); 1742f0b747eeSBarry Smith } 1743f0b747eeSBarry Smith 17444a2ae208SSatish Balay #undef __FUNCT__ 17454a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ" 174697f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 1747cddf8d76SBarry Smith { 1748dfbe8321SBarry Smith PetscErrorCode ierr; 174997f1f81fSBarry Smith PetscInt i; 1750cddf8d76SBarry Smith 17513a40ed3dSBarry Smith PetscFunctionBegin; 1752cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 1753b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr); 1754cddf8d76SBarry Smith } 1755cddf8d76SBarry Smith 1756cddf8d76SBarry Smith for (i=0; i<n; i++) { 17576a6a5d1dSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 1758cddf8d76SBarry Smith } 17593a40ed3dSBarry Smith PetscFunctionReturn(0); 1760cddf8d76SBarry Smith } 1761cddf8d76SBarry Smith 17624a2ae208SSatish Balay #undef __FUNCT__ 17634a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ" 176497f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 17654dcbc457SBarry Smith { 1766e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17676849ba73SBarry Smith PetscErrorCode ierr; 176897f1f81fSBarry Smith PetscInt row,i,j,k,l,m,n,*idx,*nidx,isz,val; 176997f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 1770f1af5d2fSBarry Smith PetscBT table; 1771bbd702dbSSatish Balay 17723a40ed3dSBarry Smith PetscFunctionBegin; 1773273d9f13SBarry Smith m = A->m; 1774e4d965acSSatish Balay ai = a->i; 1775bfeeae90SHong Zhang aj = a->j; 17768a047759SSatish Balay 1777a45adfd6SMatthew Knepley if (ov < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 177806763907SSatish Balay 177997f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr); 17806831982aSBarry Smith ierr = PetscBTCreate(m,table);CHKERRQ(ierr); 178106763907SSatish Balay 1782e4d965acSSatish Balay for (i=0; i<is_max; i++) { 1783b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 1784e4d965acSSatish Balay isz = 0; 17856831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 1786e4d965acSSatish Balay 1787e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 17884dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 1789b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 1790e4d965acSSatish Balay 1791dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 1792e4d965acSSatish Balay for (j=0; j<n ; ++j){ 1793f1af5d2fSBarry Smith if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];} 17944dcbc457SBarry Smith } 179506763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 179606763907SSatish Balay ierr = ISDestroy(is[i]);CHKERRQ(ierr); 1797e4d965acSSatish Balay 179804a348a9SBarry Smith k = 0; 179904a348a9SBarry Smith for (j=0; j<ov; j++){ /* for each overlap */ 180004a348a9SBarry Smith n = isz; 180106763907SSatish Balay for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */ 1802e4d965acSSatish Balay row = nidx[k]; 1803e4d965acSSatish Balay start = ai[row]; 1804e4d965acSSatish Balay end = ai[row+1]; 180504a348a9SBarry Smith for (l = start; l<end ; l++){ 1806efb16452SHong Zhang val = aj[l] ; 1807f1af5d2fSBarry Smith if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;} 1808e4d965acSSatish Balay } 1809e4d965acSSatish Balay } 1810e4d965acSSatish Balay } 1811029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr); 1812e4d965acSSatish Balay } 18136831982aSBarry Smith ierr = PetscBTDestroy(table);CHKERRQ(ierr); 1814606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 18153a40ed3dSBarry Smith PetscFunctionReturn(0); 18164dcbc457SBarry Smith } 181717ab2063SBarry Smith 18180513a670SBarry Smith /* -------------------------------------------------------------- */ 18194a2ae208SSatish Balay #undef __FUNCT__ 18204a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ" 1821dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 18220513a670SBarry Smith { 18230513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18246849ba73SBarry Smith PetscErrorCode ierr; 182597f1f81fSBarry Smith PetscInt i,nz,m = A->m,n = A->n,*col; 182697f1f81fSBarry Smith PetscInt *row,*cnew,j,*lens; 182756cd22aeSBarry Smith IS icolp,irowp; 182897f1f81fSBarry Smith PetscInt *cwork; 182932ec9ce4SBarry Smith PetscScalar *vwork; 18300513a670SBarry Smith 18313a40ed3dSBarry Smith PetscFunctionBegin; 18324c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 183356cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 18344c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 183556cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 18360513a670SBarry Smith 18370513a670SBarry Smith /* determine lengths of permuted rows */ 183897f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 18390513a670SBarry Smith for (i=0; i<m; i++) { 18400513a670SBarry Smith lens[row[i]] = a->i[i+1] - a->i[i]; 18410513a670SBarry Smith } 1842f69a0ea3SMatthew Knepley ierr = MatCreate(A->comm,B);CHKERRQ(ierr); 1843f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 1844f204ca49SKris Buschelman ierr = MatSetType(*B,A->type_name);CHKERRQ(ierr); 1845ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 1846606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 18470513a670SBarry Smith 184897f1f81fSBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr); 18490513a670SBarry Smith for (i=0; i<m; i++) { 185032ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 18510513a670SBarry Smith for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];} 1852cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 185332ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 18540513a670SBarry Smith } 1855606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 18563c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 18570513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18580513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 185956cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 186056cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 186156cd22aeSBarry Smith ierr = ISDestroy(irowp);CHKERRQ(ierr); 186256cd22aeSBarry Smith ierr = ISDestroy(icolp);CHKERRQ(ierr); 18633a40ed3dSBarry Smith PetscFunctionReturn(0); 18640513a670SBarry Smith } 18650513a670SBarry Smith 18664a2ae208SSatish Balay #undef __FUNCT__ 18674a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqAIJ" 1868dfbe8321SBarry Smith PetscErrorCode MatPrintHelp_SeqAIJ(Mat A) 1869682d7d0cSBarry Smith { 1870c38d4ed2SBarry Smith static PetscTruth called = PETSC_FALSE; 1871682d7d0cSBarry Smith MPI_Comm comm = A->comm; 1872dfbe8321SBarry Smith PetscErrorCode ierr; 1873682d7d0cSBarry Smith 18743a40ed3dSBarry Smith PetscFunctionBegin; 18754846f1f5SKris Buschelman ierr = MatPrintHelp_Inode(A);CHKERRQ(ierr); 1876c38d4ed2SBarry Smith if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE; 1877d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr); 1878d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr); 1879d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr); 188073e7a558SHong Zhang ierr = (*PetscHelpPrintf)(comm," -mat_no_compressedrow: Do not use compressedrow\n");CHKERRQ(ierr); 18813a40ed3dSBarry Smith PetscFunctionReturn(0); 1882682d7d0cSBarry Smith } 188397304618SKris Buschelman 18844a2ae208SSatish Balay #undef __FUNCT__ 18854a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ" 1886dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 1887cb5b572fSBarry Smith { 1888dfbe8321SBarry Smith PetscErrorCode ierr; 1889cb5b572fSBarry Smith 1890cb5b572fSBarry Smith PetscFunctionBegin; 189133f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 189233f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 1893be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1894be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 1895be6bf707SBarry Smith 1896bfeeae90SHong Zhang if (a->i[A->m] != b->i[B->m]) { 1897634064b4SBarry Smith SETERRQ(PETSC_ERR_ARG_INCOMP,"Number of nonzeros in two matrices are different"); 1898cb5b572fSBarry Smith } 1899bfeeae90SHong Zhang ierr = PetscMemcpy(b->a,a->a,(a->i[A->m])*sizeof(PetscScalar));CHKERRQ(ierr); 1900cb5b572fSBarry Smith } else { 1901cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1902cb5b572fSBarry Smith } 1903cb5b572fSBarry Smith PetscFunctionReturn(0); 1904cb5b572fSBarry Smith } 1905cb5b572fSBarry Smith 19064a2ae208SSatish Balay #undef __FUNCT__ 19074a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ" 1908dfbe8321SBarry Smith PetscErrorCode MatSetUpPreallocation_SeqAIJ(Mat A) 1909273d9f13SBarry Smith { 1910dfbe8321SBarry Smith PetscErrorCode ierr; 1911273d9f13SBarry Smith 1912273d9f13SBarry Smith PetscFunctionBegin; 1913ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 1914273d9f13SBarry Smith PetscFunctionReturn(0); 1915273d9f13SBarry Smith } 1916273d9f13SBarry Smith 19174a2ae208SSatish Balay #undef __FUNCT__ 19184a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ" 1919dfbe8321SBarry Smith PetscErrorCode MatGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 19206c0721eeSBarry Smith { 19216c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 19226c0721eeSBarry Smith PetscFunctionBegin; 19236c0721eeSBarry Smith *array = a->a; 19246c0721eeSBarry Smith PetscFunctionReturn(0); 19256c0721eeSBarry Smith } 19266c0721eeSBarry Smith 19274a2ae208SSatish Balay #undef __FUNCT__ 19284a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ" 1929dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 19306c0721eeSBarry Smith { 19316c0721eeSBarry Smith PetscFunctionBegin; 19326c0721eeSBarry Smith PetscFunctionReturn(0); 19336c0721eeSBarry Smith } 1934273d9f13SBarry Smith 1935ee4f033dSBarry Smith #undef __FUNCT__ 1936ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ" 1937dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 1938ee4f033dSBarry Smith { 19396849ba73SBarry Smith PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f; 19406849ba73SBarry Smith PetscErrorCode ierr; 194197f1f81fSBarry Smith PetscInt k,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2; 1942efb30889SBarry Smith PetscScalar dx,*y,*xx,*w3_array; 194387828ca2SBarry Smith PetscScalar *vscale_array; 1944ee4f033dSBarry Smith PetscReal epsilon = coloring->error_rel,umin = coloring->umin; 1945ee4f033dSBarry Smith Vec w1,w2,w3; 1946ee4f033dSBarry Smith void *fctx = coloring->fctx; 1947ee4f033dSBarry Smith PetscTruth flg; 1948ee4f033dSBarry Smith 1949ee4f033dSBarry Smith PetscFunctionBegin; 1950ee4f033dSBarry Smith if (!coloring->w1) { 1951ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr); 195252e6d16bSBarry Smith ierr = PetscLogObjectParent(coloring,coloring->w1);CHKERRQ(ierr); 1953ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr); 195452e6d16bSBarry Smith ierr = PetscLogObjectParent(coloring,coloring->w2);CHKERRQ(ierr); 1955ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr); 195652e6d16bSBarry Smith ierr = PetscLogObjectParent(coloring,coloring->w3);CHKERRQ(ierr); 1957ee4f033dSBarry Smith } 1958ee4f033dSBarry Smith w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3; 1959ee4f033dSBarry Smith 1960ee4f033dSBarry Smith ierr = MatSetUnfactored(J);CHKERRQ(ierr); 1961e82a3eeeSBarry Smith ierr = PetscOptionsHasName(coloring->prefix,"-mat_fd_coloring_dont_rezero",&flg);CHKERRQ(ierr); 1962ee4f033dSBarry Smith if (flg) { 196363ba0a88SBarry Smith ierr = PetscLogInfo((coloring,"MatFDColoringApply_SeqAIJ: Not calling MatZeroEntries()\n"));CHKERRQ(ierr); 1964ee4f033dSBarry Smith } else { 19650b9b6f31SBarry Smith PetscTruth assembled; 19660b9b6f31SBarry Smith ierr = MatAssembled(J,&assembled);CHKERRQ(ierr); 19670b9b6f31SBarry Smith if (assembled) { 1968ee4f033dSBarry Smith ierr = MatZeroEntries(J);CHKERRQ(ierr); 1969ee4f033dSBarry Smith } 19700b9b6f31SBarry Smith } 1971ee4f033dSBarry Smith 1972ee4f033dSBarry Smith ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr); 1973ee4f033dSBarry Smith ierr = VecGetSize(x1,&N);CHKERRQ(ierr); 1974ee4f033dSBarry Smith 1975ee4f033dSBarry Smith /* 1976ee4f033dSBarry Smith This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets 1977ee4f033dSBarry Smith coloring->F for the coarser grids from the finest 1978ee4f033dSBarry Smith */ 1979ee4f033dSBarry Smith if (coloring->F) { 1980ee4f033dSBarry Smith ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr); 1981ee4f033dSBarry Smith ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr); 1982ee4f033dSBarry Smith if (m1 != m2) { 1983ee4f033dSBarry Smith coloring->F = 0; 1984ee4f033dSBarry Smith } 1985ee4f033dSBarry Smith } 1986ee4f033dSBarry Smith 1987ee4f033dSBarry Smith if (coloring->F) { 1988ee4f033dSBarry Smith w1 = coloring->F; 1989ee4f033dSBarry Smith coloring->F = 0; 1990ee4f033dSBarry Smith } else { 199166f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 1992ee4f033dSBarry Smith ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr); 199366f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 1994ee4f033dSBarry Smith } 1995ee4f033dSBarry Smith 1996ee4f033dSBarry Smith /* 1997ee4f033dSBarry Smith Compute all the scale factors and share with other processors 1998ee4f033dSBarry Smith */ 19991ebc52fbSHong Zhang ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start; 20001ebc52fbSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start; 2001ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 2002ee4f033dSBarry Smith /* 2003ee4f033dSBarry Smith Loop over each column associated with color adding the 2004ee4f033dSBarry Smith perturbation to the vector w3. 2005ee4f033dSBarry Smith */ 2006ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 2007ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 2008ee4f033dSBarry Smith dx = xx[col]; 2009ee4f033dSBarry Smith if (dx == 0.0) dx = 1.0; 2010ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 2011ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 2012ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 2013ee4f033dSBarry Smith #else 2014ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2015ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2016ee4f033dSBarry Smith #endif 2017ee4f033dSBarry Smith dx *= epsilon; 2018ee4f033dSBarry Smith vscale_array[col] = 1.0/dx; 2019ee4f033dSBarry Smith } 2020ee4f033dSBarry Smith } 20211ebc52fbSHong Zhang vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2022ee4f033dSBarry Smith ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2023ee4f033dSBarry Smith ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2024ee4f033dSBarry Smith 2025ee4f033dSBarry Smith /* ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD); 2026ee4f033dSBarry Smith ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/ 2027ee4f033dSBarry Smith 2028ee4f033dSBarry Smith if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow; 2029ee4f033dSBarry Smith else vscaleforrow = coloring->columnsforrow; 2030ee4f033dSBarry Smith 20311ebc52fbSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2032ee4f033dSBarry Smith /* 2033ee4f033dSBarry Smith Loop over each color 2034ee4f033dSBarry Smith */ 2035ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 203649b058dcSBarry Smith coloring->currentcolor = k; 2037ee4f033dSBarry Smith ierr = VecCopy(x1,w3);CHKERRQ(ierr); 20381ebc52fbSHong Zhang ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start; 2039ee4f033dSBarry Smith /* 2040ee4f033dSBarry Smith Loop over each column associated with color adding the 2041ee4f033dSBarry Smith perturbation to the vector w3. 2042ee4f033dSBarry Smith */ 2043ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 2044ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 2045ee4f033dSBarry Smith dx = xx[col]; 20465b8514ebSBarry Smith if (dx == 0.0) dx = 1.0; 2047ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 2048ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 2049ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 2050ee4f033dSBarry Smith #else 2051ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2052ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2053ee4f033dSBarry Smith #endif 2054ee4f033dSBarry Smith dx *= epsilon; 2055634064b4SBarry Smith if (!PetscAbsScalar(dx)) SETERRQ(PETSC_ERR_PLIB,"Computed 0 differencing parameter"); 2056ee4f033dSBarry Smith w3_array[col] += dx; 2057ee4f033dSBarry Smith } 20581ebc52fbSHong Zhang w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr); 2059ee4f033dSBarry Smith 2060ee4f033dSBarry Smith /* 2061ee4f033dSBarry Smith Evaluate function at x1 + dx (here dx is a vector of perturbations) 2062ee4f033dSBarry Smith */ 2063ee4f033dSBarry Smith 206466f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2065ee4f033dSBarry Smith ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr); 206666f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2067efb30889SBarry Smith ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr); 2068ee4f033dSBarry Smith 2069ee4f033dSBarry Smith /* 2070ee4f033dSBarry Smith Loop over rows of vector, putting results into Jacobian matrix 2071ee4f033dSBarry Smith */ 20721ebc52fbSHong Zhang ierr = VecGetArray(w2,&y);CHKERRQ(ierr); 2073ee4f033dSBarry Smith for (l=0; l<coloring->nrows[k]; l++) { 2074ee4f033dSBarry Smith row = coloring->rows[k][l]; 2075ee4f033dSBarry Smith col = coloring->columnsforrow[k][l]; 2076ee4f033dSBarry Smith y[row] *= vscale_array[vscaleforrow[k][l]]; 2077ee4f033dSBarry Smith srow = row + start; 2078ee4f033dSBarry Smith ierr = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr); 2079ee4f033dSBarry Smith } 20801ebc52fbSHong Zhang ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr); 2081ee4f033dSBarry Smith } 208249b058dcSBarry Smith coloring->currentcolor = k; 20831ebc52fbSHong Zhang ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 20841ebc52fbSHong Zhang xx = xx + start; ierr = VecRestoreArray(x1,&xx);CHKERRQ(ierr); 2085ee4f033dSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2086ee4f033dSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2087ee4f033dSBarry Smith PetscFunctionReturn(0); 2088ee4f033dSBarry Smith } 2089ee4f033dSBarry Smith 2090ac90fabeSBarry Smith #include "petscblaslapack.h" 2091ac90fabeSBarry Smith #undef __FUNCT__ 2092ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ" 2093f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 2094ac90fabeSBarry Smith { 2095dfbe8321SBarry Smith PetscErrorCode ierr; 209697f1f81fSBarry Smith PetscInt i; 2097ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data; 20984ce68768SBarry Smith PetscBLASInt one=1,bnz = (PetscBLASInt)x->nz; 2099ac90fabeSBarry Smith 2100ac90fabeSBarry Smith PetscFunctionBegin; 2101ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 2102f4df32b1SMatthew Knepley PetscScalar alpha = a; 2103f4df32b1SMatthew Knepley BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one); 2104c537a176SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 2105a30b2313SHong Zhang if (y->xtoy && y->XtoY != X) { 2106a30b2313SHong Zhang ierr = PetscFree(y->xtoy);CHKERRQ(ierr); 2107a30b2313SHong Zhang ierr = MatDestroy(y->XtoY);CHKERRQ(ierr); 2108a30b2313SHong Zhang } 2109a30b2313SHong Zhang if (!y->xtoy) { /* get xtoy */ 211024f910e3SHong Zhang ierr = MatAXPYGetxtoy_Private(X->m,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr); 2111a30b2313SHong Zhang y->XtoY = X; 2112c537a176SHong Zhang } 2113f4df32b1SMatthew Knepley for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]); 211463ba0a88SBarry 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); 2115ac90fabeSBarry Smith } else { 2116f4df32b1SMatthew Knepley ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 2117ac90fabeSBarry Smith } 2118ac90fabeSBarry Smith PetscFunctionReturn(0); 2119ac90fabeSBarry Smith } 2120ac90fabeSBarry Smith 2121521d7252SBarry Smith #undef __FUNCT__ 2122521d7252SBarry Smith #define __FUNCT__ "MatSetBlockSize_SeqAIJ" 2123521d7252SBarry Smith PetscErrorCode MatSetBlockSize_SeqAIJ(Mat A,PetscInt bs) 2124521d7252SBarry Smith { 2125521d7252SBarry Smith PetscFunctionBegin; 2126521d7252SBarry Smith PetscFunctionReturn(0); 2127521d7252SBarry Smith } 2128521d7252SBarry Smith 2129354c94deSBarry Smith #undef __FUNCT__ 2130354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ" 2131354c94deSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatConjugate_SeqAIJ(Mat mat) 2132354c94deSBarry Smith { 2133354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 2134354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2135354c94deSBarry Smith PetscInt i,nz; 2136354c94deSBarry Smith PetscScalar *a; 2137354c94deSBarry Smith 2138354c94deSBarry Smith PetscFunctionBegin; 2139354c94deSBarry Smith nz = aij->nz; 2140354c94deSBarry Smith a = aij->a; 2141354c94deSBarry Smith for (i=0; i<nz; i++) { 2142354c94deSBarry Smith a[i] = PetscConj(a[i]); 2143354c94deSBarry Smith } 2144354c94deSBarry Smith #else 2145354c94deSBarry Smith PetscFunctionBegin; 2146354c94deSBarry Smith #endif 2147354c94deSBarry Smith PetscFunctionReturn(0); 2148354c94deSBarry Smith } 2149354c94deSBarry Smith 2150e34fafa9SBarry Smith #undef __FUNCT__ 2151e34fafa9SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ" 2152e34fafa9SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v) 2153e34fafa9SBarry Smith { 2154e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2155e34fafa9SBarry Smith PetscErrorCode ierr; 2156e34fafa9SBarry Smith PetscInt i,j,m = A->m,*ai,*aj,ncols,n; 2157e34fafa9SBarry Smith PetscReal atmp; 2158e34fafa9SBarry Smith PetscScalar *x,zero = 0.0; 2159e34fafa9SBarry Smith MatScalar *aa; 2160e34fafa9SBarry Smith 2161e34fafa9SBarry Smith PetscFunctionBegin; 2162e34fafa9SBarry Smith if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2163e34fafa9SBarry Smith aa = a->a; 2164e34fafa9SBarry Smith ai = a->i; 2165e34fafa9SBarry Smith aj = a->j; 2166e34fafa9SBarry Smith 216743e18e04SHong Zhang ierr = VecSet(v,zero);CHKERRQ(ierr); 2168e34fafa9SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2169e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2170e34fafa9SBarry Smith if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2171e34fafa9SBarry Smith for (i=0; i<m; i++) { 2172e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 2173e34fafa9SBarry Smith for (j=0; j<ncols; j++){ 2174e34fafa9SBarry Smith atmp = PetscAbsScalar(*aa); aa++; 2175e34fafa9SBarry Smith if (PetscAbsScalar(x[i]) < atmp) x[i] = atmp; 2176e34fafa9SBarry Smith aj++; 2177e34fafa9SBarry Smith } 2178e34fafa9SBarry Smith } 2179e34fafa9SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2180e34fafa9SBarry Smith PetscFunctionReturn(0); 2181e34fafa9SBarry Smith } 2182e34fafa9SBarry Smith 2183682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 21840a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ, 2185cb5b572fSBarry Smith MatGetRow_SeqAIJ, 2186cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 2187cb5b572fSBarry Smith MatMult_SeqAIJ, 218897304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 21897c922b88SBarry Smith MatMultTranspose_SeqAIJ, 21907c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 2191cb5b572fSBarry Smith MatSolve_SeqAIJ, 2192cb5b572fSBarry Smith MatSolveAdd_SeqAIJ, 21937c922b88SBarry Smith MatSolveTranspose_SeqAIJ, 219497304618SKris Buschelman /*10*/ MatSolveTransposeAdd_SeqAIJ, 2195cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 2196cb5b572fSBarry Smith 0, 219717ab2063SBarry Smith MatRelax_SeqAIJ, 219817ab2063SBarry Smith MatTranspose_SeqAIJ, 219997304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ, 2200cb5b572fSBarry Smith MatEqual_SeqAIJ, 2201cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 2202cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 2203cb5b572fSBarry Smith MatNorm_SeqAIJ, 220497304618SKris Buschelman /*20*/ 0, 2205cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 220617ab2063SBarry Smith MatCompress_SeqAIJ, 2207cb5b572fSBarry Smith MatSetOption_SeqAIJ, 2208cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 220997304618SKris Buschelman /*25*/ MatZeroRows_SeqAIJ, 2210cb5b572fSBarry Smith MatLUFactorSymbolic_SeqAIJ, 2211cb5b572fSBarry Smith MatLUFactorNumeric_SeqAIJ, 2212f76d2b81SHong Zhang MatCholeskyFactorSymbolic_SeqAIJ, 2213a6175056SHong Zhang MatCholeskyFactorNumeric_SeqAIJ, 221497304618SKris Buschelman /*30*/ MatSetUpPreallocation_SeqAIJ, 2215cb5b572fSBarry Smith MatILUFactorSymbolic_SeqAIJ, 2216861ba921SHong Zhang MatICCFactorSymbolic_SeqAIJ, 22176c0721eeSBarry Smith MatGetArray_SeqAIJ, 22186c0721eeSBarry Smith MatRestoreArray_SeqAIJ, 221997304618SKris Buschelman /*35*/ MatDuplicate_SeqAIJ, 2220cb5b572fSBarry Smith 0, 2221cb5b572fSBarry Smith 0, 2222cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 2223cb5b572fSBarry Smith 0, 222497304618SKris Buschelman /*40*/ MatAXPY_SeqAIJ, 2225cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 2226cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 2227cb5b572fSBarry Smith MatGetValues_SeqAIJ, 2228cb5b572fSBarry Smith MatCopy_SeqAIJ, 222997304618SKris Buschelman /*45*/ MatPrintHelp_SeqAIJ, 2230cb5b572fSBarry Smith MatScale_SeqAIJ, 2231cb5b572fSBarry Smith 0, 2232*79299369SBarry Smith MatDiagonalSet_SeqAIJ, 22336945ee14SBarry Smith MatILUDTFactor_SeqAIJ, 2234521d7252SBarry Smith /*50*/ MatSetBlockSize_SeqAIJ, 22353b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 22363b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 22373b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 2238a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 223997304618SKris Buschelman /*55*/ MatFDColoringCreate_SeqAIJ, 2240b9617806SBarry Smith 0, 22410513a670SBarry Smith 0, 2242cda55fadSBarry Smith MatPermute_SeqAIJ, 2243cda55fadSBarry Smith 0, 224497304618SKris Buschelman /*60*/ 0, 2245b9b97703SBarry Smith MatDestroy_SeqAIJ, 2246b9b97703SBarry Smith MatView_SeqAIJ, 22478a124369SBarry Smith MatGetPetscMaps_Petsc, 2248ee4f033dSBarry Smith 0, 224997304618SKris Buschelman /*65*/ 0, 2250ee4f033dSBarry Smith 0, 2251ee4f033dSBarry Smith 0, 2252ee4f033dSBarry Smith 0, 2253ee4f033dSBarry Smith 0, 2254e34fafa9SBarry Smith /*70*/ MatGetRowMax_SeqAIJ, 2255ee4f033dSBarry Smith 0, 2256ee4f033dSBarry Smith MatSetColoring_SeqAIJ, 2257dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC) 2258ee4f033dSBarry Smith MatSetValuesAdic_SeqAIJ, 2259dcf5cc72SBarry Smith #else 2260dcf5cc72SBarry Smith 0, 2261dcf5cc72SBarry Smith #endif 2262ee4f033dSBarry Smith MatSetValuesAdifor_SeqAIJ, 226397304618SKris Buschelman /*75*/ MatFDColoringApply_SeqAIJ, 226497304618SKris Buschelman 0, 226597304618SKris Buschelman 0, 226697304618SKris Buschelman 0, 226797304618SKris Buschelman 0, 226897304618SKris Buschelman /*80*/ 0, 226997304618SKris Buschelman 0, 227097304618SKris Buschelman 0, 227197304618SKris Buschelman 0, 2272bc011b1eSHong Zhang MatLoad_SeqAIJ, 2273bc011b1eSHong Zhang /*85*/ MatIsSymmetric_SeqAIJ, 22746284ec50SHong Zhang 0, 22756284ec50SHong Zhang 0, 22766284ec50SHong Zhang 0, 2277bc011b1eSHong Zhang 0, 2278bc011b1eSHong Zhang /*90*/ MatMatMult_SeqAIJ_SeqAIJ, 227926be0446SHong Zhang MatMatMultSymbolic_SeqAIJ_SeqAIJ, 228026be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 2281d439da42SKris Buschelman MatPtAP_Basic, 22827ba1a0bfSKris Buschelman MatPtAPSymbolic_SeqAIJ, 22837ba1a0bfSKris Buschelman /*95*/ MatPtAPNumeric_SeqAIJ, 2284bc011b1eSHong Zhang MatMatMultTranspose_SeqAIJ_SeqAIJ, 2285bc011b1eSHong Zhang MatMatMultTransposeSymbolic_SeqAIJ_SeqAIJ, 2286bc011b1eSHong Zhang MatMatMultTransposeNumeric_SeqAIJ_SeqAIJ, 22877ba1a0bfSKris Buschelman MatPtAPSymbolic_SeqAIJ_SeqAIJ, 22887ba1a0bfSKris Buschelman /*100*/MatPtAPNumeric_SeqAIJ_SeqAIJ, 2289609c6c4dSKris Buschelman 0, 2290609c6c4dSKris Buschelman 0, 2291354c94deSBarry Smith MatConjugate_SeqAIJ 22929e29f15eSvictorle }; 229317ab2063SBarry Smith 2294fb2e594dSBarry Smith EXTERN_C_BEGIN 22954a2ae208SSatish Balay #undef __FUNCT__ 22964a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ" 2297be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 2298bef8e0ddSBarry Smith { 2299bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 230097f1f81fSBarry Smith PetscInt i,nz,n; 2301bef8e0ddSBarry Smith 2302bef8e0ddSBarry Smith PetscFunctionBegin; 2303bef8e0ddSBarry Smith 2304bef8e0ddSBarry Smith nz = aij->maxnz; 2305273d9f13SBarry Smith n = mat->n; 2306bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 2307bef8e0ddSBarry Smith aij->j[i] = indices[i]; 2308bef8e0ddSBarry Smith } 2309bef8e0ddSBarry Smith aij->nz = nz; 2310bef8e0ddSBarry Smith for (i=0; i<n; i++) { 2311bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 2312bef8e0ddSBarry Smith } 2313bef8e0ddSBarry Smith 2314bef8e0ddSBarry Smith PetscFunctionReturn(0); 2315bef8e0ddSBarry Smith } 2316fb2e594dSBarry Smith EXTERN_C_END 2317bef8e0ddSBarry Smith 23184a2ae208SSatish Balay #undef __FUNCT__ 23194a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices" 2320bef8e0ddSBarry Smith /*@ 2321bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 2322bef8e0ddSBarry Smith in the matrix. 2323bef8e0ddSBarry Smith 2324bef8e0ddSBarry Smith Input Parameters: 2325bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 2326bef8e0ddSBarry Smith - indices - the column indices 2327bef8e0ddSBarry Smith 232815091d37SBarry Smith Level: advanced 232915091d37SBarry Smith 2330bef8e0ddSBarry Smith Notes: 2331bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 2332bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 2333bef8e0ddSBarry Smith of the MatSetValues() operation. 2334bef8e0ddSBarry Smith 2335bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 2336d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 2337bef8e0ddSBarry Smith 2338bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 2339bef8e0ddSBarry Smith 2340b9617806SBarry Smith The indices should start with zero, not one. 2341b9617806SBarry Smith 2342bef8e0ddSBarry Smith @*/ 2343be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 2344bef8e0ddSBarry Smith { 234597f1f81fSBarry Smith PetscErrorCode ierr,(*f)(Mat,PetscInt *); 2346bef8e0ddSBarry Smith 2347bef8e0ddSBarry Smith PetscFunctionBegin; 23484482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 23494482741eSBarry Smith PetscValidPointer(indices,2); 2350c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr); 2351bef8e0ddSBarry Smith if (f) { 2352bef8e0ddSBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 2353bef8e0ddSBarry Smith } else { 2354634064b4SBarry Smith SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to set column indices"); 2355bef8e0ddSBarry Smith } 2356bef8e0ddSBarry Smith PetscFunctionReturn(0); 2357bef8e0ddSBarry Smith } 2358bef8e0ddSBarry Smith 2359be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 2360be6bf707SBarry Smith 2361fb2e594dSBarry Smith EXTERN_C_BEGIN 23624a2ae208SSatish Balay #undef __FUNCT__ 23634a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ" 2364be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatStoreValues_SeqAIJ(Mat mat) 2365be6bf707SBarry Smith { 2366be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 23676849ba73SBarry Smith PetscErrorCode ierr; 23686849ba73SBarry Smith size_t nz = aij->i[mat->m]; 2369be6bf707SBarry Smith 2370be6bf707SBarry Smith PetscFunctionBegin; 2371be6bf707SBarry Smith if (aij->nonew != 1) { 2372634064b4SBarry Smith SETERRQ(PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2373be6bf707SBarry Smith } 2374be6bf707SBarry Smith 2375be6bf707SBarry Smith /* allocate space for values if not already there */ 2376be6bf707SBarry Smith if (!aij->saved_values) { 237787828ca2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr); 2378be6bf707SBarry Smith } 2379be6bf707SBarry Smith 2380be6bf707SBarry Smith /* copy values over */ 238187828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 2382be6bf707SBarry Smith PetscFunctionReturn(0); 2383be6bf707SBarry Smith } 2384fb2e594dSBarry Smith EXTERN_C_END 2385be6bf707SBarry Smith 23864a2ae208SSatish Balay #undef __FUNCT__ 2387b9617806SBarry Smith #define __FUNCT__ "MatStoreValues" 2388be6bf707SBarry Smith /*@ 2389be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 2390be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2391be6bf707SBarry Smith nonlinear portion. 2392be6bf707SBarry Smith 2393be6bf707SBarry Smith Collect on Mat 2394be6bf707SBarry Smith 2395be6bf707SBarry Smith Input Parameters: 23960e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 2397be6bf707SBarry Smith 239815091d37SBarry Smith Level: advanced 239915091d37SBarry Smith 2400be6bf707SBarry Smith Common Usage, with SNESSolve(): 2401be6bf707SBarry Smith $ Create Jacobian matrix 2402be6bf707SBarry Smith $ Set linear terms into matrix 2403be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 2404be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 2405be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 2406be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2407be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2408be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 2409be6bf707SBarry Smith $ In your Jacobian routine 2410be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2411be6bf707SBarry Smith $ Set nonlinear terms in matrix 2412be6bf707SBarry Smith 2413be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 2414be6bf707SBarry Smith $ // build linear portion of Jacobian 2415be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2416be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2417be6bf707SBarry Smith $ loop over nonlinear iterations 2418be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2419be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 2420be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 2421be6bf707SBarry Smith $ Solve linear system with Jacobian 2422be6bf707SBarry Smith $ endloop 2423be6bf707SBarry Smith 2424be6bf707SBarry Smith Notes: 2425be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 2426be6bf707SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before 2427be6bf707SBarry Smith calling this routine. 2428be6bf707SBarry Smith 24290c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 24300c468ba9SBarry Smith and does not allocated additional space. 24310c468ba9SBarry Smith 2432be6bf707SBarry Smith .seealso: MatRetrieveValues() 2433be6bf707SBarry Smith 2434be6bf707SBarry Smith @*/ 2435be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatStoreValues(Mat mat) 2436be6bf707SBarry Smith { 2437dfbe8321SBarry Smith PetscErrorCode ierr,(*f)(Mat); 2438be6bf707SBarry Smith 2439be6bf707SBarry Smith PetscFunctionBegin; 24404482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 244129bbc08cSBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 244229bbc08cSBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2443be6bf707SBarry Smith 2444c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void (**)(void))&f);CHKERRQ(ierr); 2445be6bf707SBarry Smith if (f) { 2446be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2447be6bf707SBarry Smith } else { 2448634064b4SBarry Smith SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to store values"); 2449be6bf707SBarry Smith } 2450be6bf707SBarry Smith PetscFunctionReturn(0); 2451be6bf707SBarry Smith } 2452be6bf707SBarry Smith 2453fb2e594dSBarry Smith EXTERN_C_BEGIN 24544a2ae208SSatish Balay #undef __FUNCT__ 24554a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ" 2456be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatRetrieveValues_SeqAIJ(Mat mat) 2457be6bf707SBarry Smith { 2458be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 24596849ba73SBarry Smith PetscErrorCode ierr; 246097f1f81fSBarry Smith PetscInt nz = aij->i[mat->m]; 2461be6bf707SBarry Smith 2462be6bf707SBarry Smith PetscFunctionBegin; 2463be6bf707SBarry Smith if (aij->nonew != 1) { 2464634064b4SBarry Smith SETERRQ(PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2465be6bf707SBarry Smith } 2466be6bf707SBarry Smith if (!aij->saved_values) { 2467634064b4SBarry Smith SETERRQ(PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 2468be6bf707SBarry Smith } 2469be6bf707SBarry Smith /* copy values over */ 247087828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 2471be6bf707SBarry Smith PetscFunctionReturn(0); 2472be6bf707SBarry Smith } 2473fb2e594dSBarry Smith EXTERN_C_END 2474be6bf707SBarry Smith 24754a2ae208SSatish Balay #undef __FUNCT__ 24764a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues" 2477be6bf707SBarry Smith /*@ 2478be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 2479be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2480be6bf707SBarry Smith nonlinear portion. 2481be6bf707SBarry Smith 2482be6bf707SBarry Smith Collect on Mat 2483be6bf707SBarry Smith 2484be6bf707SBarry Smith Input Parameters: 2485be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2486be6bf707SBarry Smith 248715091d37SBarry Smith Level: advanced 248815091d37SBarry Smith 2489be6bf707SBarry Smith .seealso: MatStoreValues() 2490be6bf707SBarry Smith 2491be6bf707SBarry Smith @*/ 2492be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatRetrieveValues(Mat mat) 2493be6bf707SBarry Smith { 2494dfbe8321SBarry Smith PetscErrorCode ierr,(*f)(Mat); 2495be6bf707SBarry Smith 2496be6bf707SBarry Smith PetscFunctionBegin; 24974482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 249829bbc08cSBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 249929bbc08cSBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2500be6bf707SBarry Smith 2501c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void (**)(void))&f);CHKERRQ(ierr); 2502be6bf707SBarry Smith if (f) { 2503be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2504be6bf707SBarry Smith } else { 2505634064b4SBarry Smith SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to retrieve values"); 2506be6bf707SBarry Smith } 2507be6bf707SBarry Smith PetscFunctionReturn(0); 2508be6bf707SBarry Smith } 2509be6bf707SBarry Smith 2510f83d6046SBarry Smith 2511be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 25124a2ae208SSatish Balay #undef __FUNCT__ 25134a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ" 251417ab2063SBarry Smith /*@C 2515682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 25160d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 25176e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 251851c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 25192bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 252017ab2063SBarry Smith 2521db81eaa0SLois Curfman McInnes Collective on MPI_Comm 2522db81eaa0SLois Curfman McInnes 252317ab2063SBarry Smith Input Parameters: 2524db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 252517ab2063SBarry Smith . m - number of rows 252617ab2063SBarry Smith . n - number of columns 252717ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 252851c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 25292bd5e0b2SLois Curfman McInnes (possibly different for each row) or PETSC_NULL 253017ab2063SBarry Smith 253117ab2063SBarry Smith Output Parameter: 2532416022c9SBarry Smith . A - the matrix 253317ab2063SBarry Smith 2534b259b22eSLois Curfman McInnes Notes: 253549a6f317SBarry Smith If nnz is given then nz is ignored 253649a6f317SBarry Smith 253717ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 253817ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 25390002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 254044cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 254117ab2063SBarry Smith 254217ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2543a40aa06bSLois Curfman McInnes Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 25443d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 25456da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 254617ab2063SBarry Smith 2547682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 25484fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 2549682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 25506c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 25516c7ebb05SLois Curfman McInnes 25526c7ebb05SLois Curfman McInnes Options Database Keys: 2553698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 2554698d4c6aSKris Buschelman . -mat_inode_limit <limit> - Sets inode limit (max limit=5) 2555db81eaa0SLois Curfman McInnes - -mat_aij_oneindex - Internally use indexing starting at 1 2556db81eaa0SLois Curfman McInnes rather than 0. Note that when calling MatSetValues(), 2557db81eaa0SLois Curfman McInnes the user still MUST index entries starting at 0! 255817ab2063SBarry Smith 2559027ccd11SLois Curfman McInnes Level: intermediate 2560027ccd11SLois Curfman McInnes 256136db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 256236db0b34SBarry Smith 256317ab2063SBarry Smith @*/ 2564be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 256517ab2063SBarry Smith { 2566dfbe8321SBarry Smith PetscErrorCode ierr; 25676945ee14SBarry Smith 25683a40ed3dSBarry Smith PetscFunctionBegin; 2569f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 2570f69a0ea3SMatthew Knepley ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 2571273d9f13SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 2572ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,(PetscInt*)nnz);CHKERRQ(ierr); 2573273d9f13SBarry Smith PetscFunctionReturn(0); 2574273d9f13SBarry Smith } 2575273d9f13SBarry Smith 25764a2ae208SSatish Balay #undef __FUNCT__ 25774a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation" 2578273d9f13SBarry Smith /*@C 2579273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 2580273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 2581273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 2582273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 2583273d9f13SBarry Smith 2584273d9f13SBarry Smith Collective on MPI_Comm 2585273d9f13SBarry Smith 2586273d9f13SBarry Smith Input Parameters: 258745bfc511SMatthew Knepley + B - The matrix 2588273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 2589273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 2590273d9f13SBarry Smith (possibly different for each row) or PETSC_NULL 2591273d9f13SBarry Smith 2592273d9f13SBarry Smith Notes: 259349a6f317SBarry Smith If nnz is given then nz is ignored 259449a6f317SBarry Smith 2595273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 2596273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 2597273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 2598273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 2599273d9f13SBarry Smith 2600273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2601273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 2602273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 2603273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 2604273d9f13SBarry Smith 2605a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 2606a96a251dSBarry Smith entries or columns indices 2607a96a251dSBarry Smith 2608273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 2609273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 2610273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 2611273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 2612273d9f13SBarry Smith 2613273d9f13SBarry Smith Options Database Keys: 2614698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 2615698d4c6aSKris Buschelman . -mat_inode_limit <limit> - Sets inode limit (max limit=5) 2616273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 2617273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 2618273d9f13SBarry Smith the user still MUST index entries starting at 0! 2619273d9f13SBarry Smith 2620273d9f13SBarry Smith Level: intermediate 2621273d9f13SBarry Smith 2622273d9f13SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 2623273d9f13SBarry Smith 2624273d9f13SBarry Smith @*/ 2625be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 2626273d9f13SBarry Smith { 262797f1f81fSBarry Smith PetscErrorCode ierr,(*f)(Mat,PetscInt,const PetscInt[]); 2628a23d5eceSKris Buschelman 2629a23d5eceSKris Buschelman PetscFunctionBegin; 2630a23d5eceSKris Buschelman ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",(void (**)(void))&f);CHKERRQ(ierr); 2631a23d5eceSKris Buschelman if (f) { 2632a23d5eceSKris Buschelman ierr = (*f)(B,nz,nnz);CHKERRQ(ierr); 2633a23d5eceSKris Buschelman } 2634a23d5eceSKris Buschelman PetscFunctionReturn(0); 2635a23d5eceSKris Buschelman } 2636a23d5eceSKris Buschelman 2637a23d5eceSKris Buschelman EXTERN_C_BEGIN 2638a23d5eceSKris Buschelman #undef __FUNCT__ 2639a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ" 2640be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,PetscInt *nnz) 2641a23d5eceSKris Buschelman { 2642273d9f13SBarry Smith Mat_SeqAIJ *b; 2643a43ee2ecSKris Buschelman PetscTruth skipallocation = PETSC_FALSE; 26446849ba73SBarry Smith PetscErrorCode ierr; 264597f1f81fSBarry Smith PetscInt i; 2646273d9f13SBarry Smith 2647273d9f13SBarry Smith PetscFunctionBegin; 2648d5d45c9bSBarry Smith 2649a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 2650c461c341SBarry Smith skipallocation = PETSC_TRUE; 2651c461c341SBarry Smith nz = 0; 2652c461c341SBarry Smith } 2653c461c341SBarry Smith 2654435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 2655435da068SBarry Smith if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 2656b73539f3SBarry Smith if (nnz) { 2657273d9f13SBarry Smith for (i=0; i<B->m; i++) { 265829bbc08cSBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 26593a7fca6bSBarry 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); 2660b73539f3SBarry Smith } 2661b73539f3SBarry Smith } 2662b73539f3SBarry Smith 2663273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 2664273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 2665273d9f13SBarry Smith 2666ab93d7beSBarry Smith if (!skipallocation) { 2667ab93d7beSBarry Smith ierr = PetscMalloc2(B->m,PetscInt,&b->imax,B->m,PetscInt,&b->ilen);CHKERRQ(ierr); 2668273d9f13SBarry Smith if (!nnz) { 2669435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 2670273d9f13SBarry Smith else if (nz <= 0) nz = 1; 2671273d9f13SBarry Smith for (i=0; i<B->m; i++) b->imax[i] = nz; 2672273d9f13SBarry Smith nz = nz*B->m; 2673273d9f13SBarry Smith } else { 2674273d9f13SBarry Smith nz = 0; 2675273d9f13SBarry Smith for (i=0; i<B->m; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 2676273d9f13SBarry Smith } 2677273d9f13SBarry Smith 2678ab93d7beSBarry Smith /* b->ilen will count nonzeros in each row so far. */ 2679ab93d7beSBarry Smith for (i=0; i<B->m; i++) { b->ilen[i] = 0;} 2680ab93d7beSBarry Smith 2681273d9f13SBarry Smith /* allocate the matrix space */ 2682a96a251dSBarry Smith ierr = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->m+1,PetscInt,&b->i);CHKERRQ(ierr); 2683bfeeae90SHong Zhang b->i[0] = 0; 26845da197adSKris Buschelman for (i=1; i<B->m+1; i++) { 26855da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 26865da197adSKris Buschelman } 2687273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 2688273d9f13SBarry Smith b->freedata = PETSC_TRUE; 2689c461c341SBarry Smith } else { 2690c461c341SBarry Smith b->freedata = PETSC_FALSE; 2691c461c341SBarry Smith } 2692273d9f13SBarry Smith 2693273d9f13SBarry Smith b->nz = 0; 2694273d9f13SBarry Smith b->maxnz = nz; 2695273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 2696273d9f13SBarry Smith PetscFunctionReturn(0); 2697273d9f13SBarry Smith } 2698a23d5eceSKris Buschelman EXTERN_C_END 2699273d9f13SBarry Smith 2700a1661176SMatthew Knepley #undef __FUNCT__ 2701a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR" 2702a1661176SMatthew Knepley /*@C 2703a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 2704a1661176SMatthew Knepley 2705a1661176SMatthew Knepley Input Parameters: 2706a1661176SMatthew Knepley + B - the matrix 2707a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 2708a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 2709a1661176SMatthew Knepley - v - optional values in the matrix 2710a1661176SMatthew Knepley 2711d58b2322SMatthew Knepley Contributed by: Lisandro Dalchin 2712d58b2322SMatthew Knepley 2713a1661176SMatthew Knepley Level: developer 2714a1661176SMatthew Knepley 2715a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential 2716a1661176SMatthew Knepley 2717a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ 2718a1661176SMatthew Knepley @*/ 2719a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 2720a1661176SMatthew Knepley { 2721a1661176SMatthew Knepley PetscErrorCode (*f)(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]); 2722a1661176SMatthew Knepley PetscErrorCode ierr; 2723a1661176SMatthew Knepley 2724a1661176SMatthew Knepley PetscFunctionBegin; 2725a1661176SMatthew Knepley PetscValidHeaderSpecific(B,MAT_COOKIE,1); 2726a1661176SMatthew Knepley ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",(void (**)(void))&f);CHKERRQ(ierr); 2727a1661176SMatthew Knepley if (f) { 2728a1661176SMatthew Knepley ierr = (*f)(B,i,j,v);CHKERRQ(ierr); 2729a1661176SMatthew Knepley } 2730a1661176SMatthew Knepley PetscFunctionReturn(0); 2731a1661176SMatthew Knepley } 2732a1661176SMatthew Knepley 2733a1661176SMatthew Knepley EXTERN_C_BEGIN 2734a1661176SMatthew Knepley #undef __FUNCT__ 2735a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR_SeqAIJ" 2736a1661176SMatthew Knepley PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt I[],const PetscInt J[],const PetscScalar v[]) 2737a1661176SMatthew Knepley { 2738a1661176SMatthew Knepley PetscInt i; 2739a1661176SMatthew Knepley PetscInt m,n; 2740a1661176SMatthew Knepley PetscInt nz; 2741a1661176SMatthew Knepley PetscInt *nnz, nz_max = 0; 2742a1661176SMatthew Knepley PetscScalar *values; 2743a1661176SMatthew Knepley PetscErrorCode ierr; 2744a1661176SMatthew Knepley 2745a1661176SMatthew Knepley PetscFunctionBegin; 2746a1661176SMatthew Knepley ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 2747a1661176SMatthew Knepley 2748a1661176SMatthew Knepley if (I[0]) { 2749a1661176SMatthew Knepley SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "I[0] must be 0 it is %D", I[0]); 2750a1661176SMatthew Knepley } 2751a1661176SMatthew Knepley ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr); 2752a1661176SMatthew Knepley for(i = 0; i < m; i++) { 2753a1661176SMatthew Knepley nz = I[i+1]- I[i]; 2754a1661176SMatthew Knepley nz_max = PetscMax(nz_max, nz); 2755a1661176SMatthew Knepley if (nz < 0) { 2756a1661176SMatthew Knepley SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 2757a1661176SMatthew Knepley } 2758a1661176SMatthew Knepley nnz[i] = nz; 2759a1661176SMatthew Knepley } 2760a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 2761a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 2762a1661176SMatthew Knepley 2763a1661176SMatthew Knepley if (v) { 2764a1661176SMatthew Knepley values = (PetscScalar*) v; 2765a1661176SMatthew Knepley } else { 2766a1661176SMatthew Knepley ierr = PetscMalloc((nz_max+1)*sizeof(PetscScalar), &values);CHKERRQ(ierr); 2767a1661176SMatthew Knepley ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr); 2768a1661176SMatthew Knepley } 2769a1661176SMatthew Knepley 2770a1661176SMatthew Knepley ierr = MatSetOption(B,MAT_COLUMNS_SORTED);CHKERRQ(ierr); 2771a1661176SMatthew Knepley 2772a1661176SMatthew Knepley for(i = 0; i < m; i++) { 2773a1661176SMatthew Knepley nz = I[i+1] - I[i]; 2774a1661176SMatthew Knepley ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+I[i], values + (v ? I[i] : 0), INSERT_VALUES);CHKERRQ(ierr); 2775a1661176SMatthew Knepley } 2776a1661176SMatthew Knepley 2777a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2778a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2779a1661176SMatthew Knepley ierr = MatSetOption(B,MAT_COLUMNS_UNSORTED);CHKERRQ(ierr); 2780a1661176SMatthew Knepley 2781a1661176SMatthew Knepley if (!v) { 2782a1661176SMatthew Knepley ierr = PetscFree(values);CHKERRQ(ierr); 2783a1661176SMatthew Knepley } 2784a1661176SMatthew Knepley PetscFunctionReturn(0); 2785a1661176SMatthew Knepley } 2786a1661176SMatthew Knepley EXTERN_C_END 2787a1661176SMatthew Knepley 27880bad9183SKris Buschelman /*MC 2789fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 27900bad9183SKris Buschelman based on compressed sparse row format. 27910bad9183SKris Buschelman 27920bad9183SKris Buschelman Options Database Keys: 27930bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 27940bad9183SKris Buschelman 27950bad9183SKris Buschelman Level: beginner 27960bad9183SKris Buschelman 2797f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 27980bad9183SKris Buschelman M*/ 27990bad9183SKris Buschelman 2800a6175056SHong Zhang EXTERN_C_BEGIN 28014a2ae208SSatish Balay #undef __FUNCT__ 28024a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ" 2803be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_SeqAIJ(Mat B) 2804273d9f13SBarry Smith { 2805273d9f13SBarry Smith Mat_SeqAIJ *b; 2806dfbe8321SBarry Smith PetscErrorCode ierr; 280738baddfdSBarry Smith PetscMPIInt size; 2808273d9f13SBarry Smith 2809273d9f13SBarry Smith PetscFunctionBegin; 2810273d9f13SBarry Smith ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr); 2811273d9f13SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 2812273d9f13SBarry Smith 2813273d9f13SBarry Smith B->m = B->M = PetscMax(B->m,B->M); 2814273d9f13SBarry Smith B->n = B->N = PetscMax(B->n,B->N); 2815273d9f13SBarry Smith 2816b0a32e0cSBarry Smith ierr = PetscNew(Mat_SeqAIJ,&b);CHKERRQ(ierr); 2817b0a32e0cSBarry Smith B->data = (void*)b; 2818549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 2819416022c9SBarry Smith B->factor = 0; 282090f02eecSBarry Smith B->mapping = 0; 2821416022c9SBarry Smith b->row = 0; 2822416022c9SBarry Smith b->col = 0; 282382bf6240SBarry Smith b->icol = 0; 2824b810aeb4SBarry Smith b->reallocs = 0; 282517ab2063SBarry Smith 28268a124369SBarry Smith ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr); 28278a124369SBarry Smith ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr); 2828a5ae1ecdSBarry Smith 2829f1e2ffcdSBarry Smith b->sorted = PETSC_FALSE; 283036db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 2831f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 2832416022c9SBarry Smith b->nonew = 0; 2833416022c9SBarry Smith b->diag = 0; 2834416022c9SBarry Smith b->solve_work = 0; 28352a1b7f2aSHong Zhang B->spptr = 0; 2836be6bf707SBarry Smith b->saved_values = 0; 2837d7f994e1SBarry Smith b->idiag = 0; 2838d7f994e1SBarry Smith b->ssor = 0; 2839f1e2ffcdSBarry Smith b->keepzeroedrows = PETSC_FALSE; 2840a30b2313SHong Zhang b->xtoy = 0; 2841a30b2313SHong Zhang b->XtoY = 0; 284273e7a558SHong Zhang b->compressedrow.use = PETSC_FALSE; 2843d487561eSHong Zhang b->compressedrow.nrows = B->m; 2844d487561eSHong Zhang b->compressedrow.i = PETSC_NULL; 2845d487561eSHong Zhang b->compressedrow.rindex = PETSC_NULL; 2846d487561eSHong Zhang b->compressedrow.checked = PETSC_FALSE; 284788e51ccdSHong Zhang B->same_nonzero = PETSC_FALSE; 284817ab2063SBarry Smith 284935d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 285035d8aa7fSBarry Smith 2851f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C", 2852bef8e0ddSBarry Smith "MatSeqAIJSetColumnIndices_SeqAIJ", 2853bc4b532fSSatish Balay MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 2854f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 2855be6bf707SBarry Smith "MatStoreValues_SeqAIJ", 2856bc4b532fSSatish Balay MatStoreValues_SeqAIJ);CHKERRQ(ierr); 2857f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 2858be6bf707SBarry Smith "MatRetrieveValues_SeqAIJ", 2859bc4b532fSSatish Balay MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 2860a6175056SHong Zhang ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C", 2861a6175056SHong Zhang "MatConvert_SeqAIJ_SeqSBAIJ", 2862a6175056SHong Zhang MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 286385fc7724SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C", 286485fc7724SBarry Smith "MatConvert_SeqAIJ_SeqBAIJ", 286585fc7724SBarry Smith MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 28665fbd3699SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C", 28675fbd3699SBarry Smith "MatIsTranspose_SeqAIJ", 28685fbd3699SBarry Smith MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 2869a23d5eceSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C", 2870a23d5eceSKris Buschelman "MatSeqAIJSetPreallocation_SeqAIJ", 2871a23d5eceSKris Buschelman MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 2872a1661176SMatthew Knepley ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C", 2873a1661176SMatthew Knepley "MatSeqAIJSetPreallocationCSR_SeqAIJ", 2874a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 287505b94e36SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C", 287605b94e36SKris Buschelman "MatReorderForNonzeroDiagonal_SeqAIJ", 287705b94e36SKris Buschelman MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 28784846f1f5SKris Buschelman ierr = MatCreate_Inode(B);CHKERRQ(ierr); 28793a40ed3dSBarry Smith PetscFunctionReturn(0); 288017ab2063SBarry Smith } 2881273d9f13SBarry Smith EXTERN_C_END 288217ab2063SBarry Smith 28834a2ae208SSatish Balay #undef __FUNCT__ 28844a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqAIJ" 2885dfbe8321SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 288617ab2063SBarry Smith { 2887416022c9SBarry Smith Mat C; 2888416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 28896849ba73SBarry Smith PetscErrorCode ierr; 289097f1f81fSBarry Smith PetscInt i,m = A->m; 289117ab2063SBarry Smith 28923a40ed3dSBarry Smith PetscFunctionBegin; 28934043dd9cSLois Curfman McInnes *B = 0; 2894f69a0ea3SMatthew Knepley ierr = MatCreate(A->comm,&C);CHKERRQ(ierr); 2895f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,A->m,A->n,A->m,A->n);CHKERRQ(ierr); 2896be5d1d56SKris Buschelman ierr = MatSetType(C,A->type_name);CHKERRQ(ierr); 28971d5dac46SHong Zhang ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 28981d5dac46SHong Zhang 2899273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 2900273d9f13SBarry Smith 2901416022c9SBarry Smith C->factor = A->factor; 29026ad4291fSHong Zhang 2903416022c9SBarry Smith c->row = 0; 2904416022c9SBarry Smith c->col = 0; 290582bf6240SBarry Smith c->icol = 0; 29066ad4291fSHong Zhang c->reallocs = 0; 290717ab2063SBarry Smith 29086ad4291fSHong Zhang C->assembled = PETSC_TRUE; 290917ab2063SBarry Smith 291033b91e9fSSatish Balay ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr); 291117ab2063SBarry Smith for (i=0; i<m; i++) { 2912416022c9SBarry Smith c->imax[i] = a->imax[i]; 2913416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 291417ab2063SBarry Smith } 291517ab2063SBarry Smith 291617ab2063SBarry Smith /* allocate the matrix space */ 2917a96a251dSBarry Smith ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr); 2918f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 291997f1f81fSBarry Smith ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 292017ab2063SBarry Smith if (m > 0) { 292197f1f81fSBarry Smith ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr); 2922be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 2923bfeeae90SHong Zhang ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 2924be6bf707SBarry Smith } else { 2925bfeeae90SHong Zhang ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 292617ab2063SBarry Smith } 292708480c60SBarry Smith } 292817ab2063SBarry Smith 2929416022c9SBarry Smith c->sorted = a->sorted; 29306ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 2931416022c9SBarry Smith c->roworiented = a->roworiented; 2932416022c9SBarry Smith c->nonew = a->nonew; 2933416022c9SBarry Smith if (a->diag) { 293497f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr); 293552e6d16bSBarry Smith ierr = PetscLogObjectMemory(C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 293617ab2063SBarry Smith for (i=0; i<m; i++) { 2937416022c9SBarry Smith c->diag[i] = a->diag[i]; 293817ab2063SBarry Smith } 29393a40ed3dSBarry Smith } else c->diag = 0; 29406ad4291fSHong Zhang c->solve_work = 0; 29416ad4291fSHong Zhang c->saved_values = 0; 29426ad4291fSHong Zhang c->idiag = 0; 29436ad4291fSHong Zhang c->ssor = 0; 29446ad4291fSHong Zhang c->keepzeroedrows = a->keepzeroedrows; 29456ad4291fSHong Zhang c->freedata = PETSC_TRUE; 29466ad4291fSHong Zhang c->xtoy = 0; 29476ad4291fSHong Zhang c->XtoY = 0; 29486ad4291fSHong Zhang 2949416022c9SBarry Smith c->nz = a->nz; 2950416022c9SBarry Smith c->maxnz = a->maxnz; 2951273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 2952754ec7b1SSatish Balay 29536ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 29546ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 29556ad4291fSHong Zhang c->compressedrow.checked = a->compressedrow.checked; 29566ad4291fSHong Zhang if ( a->compressedrow.checked && a->compressedrow.use){ 29576ad4291fSHong Zhang i = a->compressedrow.nrows; 29586ad4291fSHong Zhang ierr = PetscMalloc((2*i+1)*sizeof(PetscInt),&c->compressedrow.i);CHKERRQ(ierr); 29596ad4291fSHong Zhang c->compressedrow.rindex = c->compressedrow.i + i + 1; 29606ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr); 29616ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr); 296227ea64f8SHong Zhang } else { 296327ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 296427ea64f8SHong Zhang c->compressedrow.i = PETSC_NULL; 296527ea64f8SHong Zhang c->compressedrow.rindex = PETSC_NULL; 29666ad4291fSHong Zhang } 296788e51ccdSHong Zhang C->same_nonzero = A->same_nonzero; 29686ad4291fSHong Zhang 29694846f1f5SKris Buschelman ierr = MatDuplicate_Inode(A,cpvalues,&C);CHKERRQ(ierr); 29704846f1f5SKris Buschelman 2971416022c9SBarry Smith *B = C; 2972b0a32e0cSBarry Smith ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 29733a40ed3dSBarry Smith PetscFunctionReturn(0); 297417ab2063SBarry Smith } 297517ab2063SBarry Smith 29764a2ae208SSatish Balay #undef __FUNCT__ 29774a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ" 2978f69a0ea3SMatthew Knepley PetscErrorCode MatLoad_SeqAIJ(PetscViewer viewer, MatType type,Mat *A) 297917ab2063SBarry Smith { 2980416022c9SBarry Smith Mat_SeqAIJ *a; 2981416022c9SBarry Smith Mat B; 29826849ba73SBarry Smith PetscErrorCode ierr; 29833c601197SSatish Balay PetscInt i,sum,nz,header[4],*rowlengths = 0,M,N; 298438baddfdSBarry Smith int fd; 298538baddfdSBarry Smith PetscMPIInt size; 2986bcd2baecSBarry Smith MPI_Comm comm; 298717ab2063SBarry Smith 29883a40ed3dSBarry Smith PetscFunctionBegin; 2989e864ced6SBarry Smith ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 2990d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 299129bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,"view must have one processor"); 2992b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 29930752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 2994552e946dSBarry Smith if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 299517ab2063SBarry Smith M = header[1]; N = header[2]; nz = header[3]; 299617ab2063SBarry Smith 2997d64ed03dSBarry Smith if (nz < 0) { 299829bbc08cSBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 2999d64ed03dSBarry Smith } 3000d64ed03dSBarry Smith 300117ab2063SBarry Smith /* read in row lengths */ 300297f1f81fSBarry Smith ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr); 30030752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 300417ab2063SBarry Smith 30053c601197SSatish Balay /* check if sum of rowlengths is same as nz */ 30063c601197SSatish Balay for (i=0,sum=0; i< M; i++) sum +=rowlengths[i]; 30073c601197SSatish Balay if (sum != nz) SETERRQ2(PETSC_ERR_FILE_READ,"Inconsistant matrix data in file. no-nonzeros = %d, sum-row-lengths = %d\n",nz,sum); 30083c601197SSatish Balay 300917ab2063SBarry Smith /* create our matrix */ 3010f69a0ea3SMatthew Knepley ierr = MatCreate(comm,&B);CHKERRQ(ierr); 3011f69a0ea3SMatthew Knepley ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 3012b3a1e11cSKris Buschelman ierr = MatSetType(B,type);CHKERRQ(ierr); 3013ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(B,0,rowlengths);CHKERRQ(ierr); 3014416022c9SBarry Smith a = (Mat_SeqAIJ*)B->data; 301517ab2063SBarry Smith 301617ab2063SBarry Smith /* read in column indices and adjust for Fortran indexing*/ 30170752156aSBarry Smith ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 301817ab2063SBarry Smith 301917ab2063SBarry Smith /* read in nonzero values */ 30200752156aSBarry Smith ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 302117ab2063SBarry Smith 302217ab2063SBarry Smith /* set matrix "i" values */ 3023efb16452SHong Zhang a->i[0] = 0; 302417ab2063SBarry Smith for (i=1; i<= M; i++) { 3025416022c9SBarry Smith a->i[i] = a->i[i-1] + rowlengths[i-1]; 3026416022c9SBarry Smith a->ilen[i-1] = rowlengths[i-1]; 302717ab2063SBarry Smith } 3028606d414cSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 302917ab2063SBarry Smith 30306d4a8577SBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 30316d4a8577SBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3032b3a1e11cSKris Buschelman *A = B; 30333a40ed3dSBarry Smith PetscFunctionReturn(0); 303417ab2063SBarry Smith } 303517ab2063SBarry Smith 30364a2ae208SSatish Balay #undef __FUNCT__ 3037b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ" 3038dfbe8321SBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg) 30397264ac53SSatish Balay { 30407264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data; 3041dfbe8321SBarry Smith PetscErrorCode ierr; 30427264ac53SSatish Balay 30433a40ed3dSBarry Smith PetscFunctionBegin; 3044bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 3045bfeeae90SHong Zhang if ((A->m != B->m) || (A->n != B->n) ||(a->nz != b->nz)) { 3046ca44d042SBarry Smith *flg = PETSC_FALSE; 3047ca44d042SBarry Smith PetscFunctionReturn(0); 3048bcd2baecSBarry Smith } 30497264ac53SSatish Balay 30507264ac53SSatish Balay /* if the a->i are the same */ 305197f1f81fSBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->m+1)*sizeof(PetscInt),flg);CHKERRQ(ierr); 3052abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 30537264ac53SSatish Balay 30547264ac53SSatish Balay /* if a->j are the same */ 305597f1f81fSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr); 3056abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 3057bcd2baecSBarry Smith 3058bcd2baecSBarry Smith /* if a->a are the same */ 305987828ca2SBarry Smith ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 30600f5bd95cSBarry Smith 30613a40ed3dSBarry Smith PetscFunctionReturn(0); 30627264ac53SSatish Balay 30637264ac53SSatish Balay } 306436db0b34SBarry Smith 30654a2ae208SSatish Balay #undef __FUNCT__ 30664a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays" 306705869f15SSatish Balay /*@ 306836db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 306936db0b34SBarry Smith provided by the user. 307036db0b34SBarry Smith 307136db0b34SBarry Smith Coolective on MPI_Comm 307236db0b34SBarry Smith 307336db0b34SBarry Smith Input Parameters: 307436db0b34SBarry Smith + comm - must be an MPI communicator of size 1 307536db0b34SBarry Smith . m - number of rows 307636db0b34SBarry Smith . n - number of columns 307736db0b34SBarry Smith . i - row indices 307836db0b34SBarry Smith . j - column indices 307936db0b34SBarry Smith - a - matrix values 308036db0b34SBarry Smith 308136db0b34SBarry Smith Output Parameter: 308236db0b34SBarry Smith . mat - the matrix 308336db0b34SBarry Smith 308436db0b34SBarry Smith Level: intermediate 308536db0b34SBarry Smith 308636db0b34SBarry Smith Notes: 30870551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 308836db0b34SBarry Smith once the matrix is destroyed 308936db0b34SBarry Smith 309036db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 309136db0b34SBarry Smith 3092bfeeae90SHong Zhang The i and j indices are 0 based 309336db0b34SBarry Smith 309436db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ() 309536db0b34SBarry Smith 309636db0b34SBarry Smith @*/ 3097be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat) 309836db0b34SBarry Smith { 3099dfbe8321SBarry Smith PetscErrorCode ierr; 310097f1f81fSBarry Smith PetscInt ii; 310136db0b34SBarry Smith Mat_SeqAIJ *aij; 310236db0b34SBarry Smith 310336db0b34SBarry Smith PetscFunctionBegin; 3104a96a251dSBarry Smith if (i[0]) { 3105634064b4SBarry Smith SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 310636db0b34SBarry Smith } 3107f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 3108f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 3109ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 3110ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 3111ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 3112ab93d7beSBarry Smith ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr); 3113ab93d7beSBarry Smith 311436db0b34SBarry Smith aij->i = i; 311536db0b34SBarry Smith aij->j = j; 311636db0b34SBarry Smith aij->a = a; 311736db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 311836db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 311936db0b34SBarry Smith aij->freedata = PETSC_FALSE; 312036db0b34SBarry Smith 312136db0b34SBarry Smith for (ii=0; ii<m; ii++) { 312236db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 31232515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 312479a5c55eSBarry 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]); 312536db0b34SBarry Smith #endif 312636db0b34SBarry Smith } 31272515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 312836db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 312979a5c55eSBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]); 313079a5c55eSBarry Smith if (j[ii] > n - 1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column index to large at location = %d index = %d",ii,j[ii]); 313136db0b34SBarry Smith } 313236db0b34SBarry Smith #endif 313336db0b34SBarry Smith 3134b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3135b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 313636db0b34SBarry Smith PetscFunctionReturn(0); 313736db0b34SBarry Smith } 313836db0b34SBarry Smith 3139cc8ba8e1SBarry Smith #undef __FUNCT__ 3140ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ" 3141dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring) 3142cc8ba8e1SBarry Smith { 3143dfbe8321SBarry Smith PetscErrorCode ierr; 3144cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 314536db0b34SBarry Smith 3146cc8ba8e1SBarry Smith PetscFunctionBegin; 314712c595b3SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 3148cc8ba8e1SBarry Smith ierr = ISColoringReference(coloring);CHKERRQ(ierr); 3149cc8ba8e1SBarry Smith a->coloring = coloring; 315012c595b3SBarry Smith } else if (coloring->ctype == IS_COLORING_GHOSTED) { 315197f1f81fSBarry Smith PetscInt i,*larray; 315212c595b3SBarry Smith ISColoring ocoloring; 315308b6dcc0SBarry Smith ISColoringValue *colors; 315412c595b3SBarry Smith 315512c595b3SBarry Smith /* set coloring for diagonal portion */ 315697f1f81fSBarry Smith ierr = PetscMalloc((A->n+1)*sizeof(PetscInt),&larray);CHKERRQ(ierr); 315712c595b3SBarry Smith for (i=0; i<A->n; i++) { 315812c595b3SBarry Smith larray[i] = i; 315912c595b3SBarry Smith } 316012c595b3SBarry Smith ierr = ISGlobalToLocalMappingApply(A->mapping,IS_GTOLM_MASK,A->n,larray,PETSC_NULL,larray);CHKERRQ(ierr); 316108b6dcc0SBarry Smith ierr = PetscMalloc((A->n+1)*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); 316212c595b3SBarry Smith for (i=0; i<A->n; i++) { 316312c595b3SBarry Smith colors[i] = coloring->colors[larray[i]]; 316412c595b3SBarry Smith } 316512c595b3SBarry Smith ierr = PetscFree(larray);CHKERRQ(ierr); 316612c595b3SBarry Smith ierr = ISColoringCreate(PETSC_COMM_SELF,A->n,colors,&ocoloring);CHKERRQ(ierr); 316712c595b3SBarry Smith a->coloring = ocoloring; 316812c595b3SBarry Smith } 3169cc8ba8e1SBarry Smith PetscFunctionReturn(0); 3170cc8ba8e1SBarry Smith } 3171cc8ba8e1SBarry Smith 3172dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC) 3173ee4f033dSBarry Smith EXTERN_C_BEGIN 317429c1e371SBarry Smith #include "adic/ad_utils.h" 3175ee4f033dSBarry Smith EXTERN_C_END 3176cc8ba8e1SBarry Smith 3177cc8ba8e1SBarry Smith #undef __FUNCT__ 3178ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ" 3179dfbe8321SBarry Smith PetscErrorCode MatSetValuesAdic_SeqAIJ(Mat A,void *advalues) 3180cc8ba8e1SBarry Smith { 3181cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 318297f1f81fSBarry Smith PetscInt m = A->m,*ii = a->i,*jj = a->j,nz,i,j,nlen; 31834440f671SBarry Smith PetscScalar *v = a->a,*values = ((PetscScalar*)advalues)+1; 318408b6dcc0SBarry Smith ISColoringValue *color; 3185cc8ba8e1SBarry Smith 3186cc8ba8e1SBarry Smith PetscFunctionBegin; 3187e005ede5SBarry Smith if (!a->coloring) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix"); 31884440f671SBarry Smith nlen = PetscADGetDerivTypeSize()/sizeof(PetscScalar); 3189cc8ba8e1SBarry Smith color = a->coloring->colors; 3190cc8ba8e1SBarry Smith /* loop over rows */ 3191cc8ba8e1SBarry Smith for (i=0; i<m; i++) { 3192cc8ba8e1SBarry Smith nz = ii[i+1] - ii[i]; 3193cc8ba8e1SBarry Smith /* loop over columns putting computed value into matrix */ 3194cc8ba8e1SBarry Smith for (j=0; j<nz; j++) { 3195cc8ba8e1SBarry Smith *v++ = values[color[*jj++]]; 3196cc8ba8e1SBarry Smith } 31974440f671SBarry Smith values += nlen; /* jump to next row of derivatives */ 3198ee4f033dSBarry Smith } 3199ee4f033dSBarry Smith PetscFunctionReturn(0); 3200ee4f033dSBarry Smith } 3201ee4f033dSBarry Smith #endif 3202ee4f033dSBarry Smith 3203ee4f033dSBarry Smith #undef __FUNCT__ 3204ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ" 320597f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues) 3206ee4f033dSBarry Smith { 3207ee4f033dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 320897f1f81fSBarry Smith PetscInt m = A->m,*ii = a->i,*jj = a->j,nz,i,j; 320987828ca2SBarry Smith PetscScalar *v = a->a,*values = (PetscScalar *)advalues; 321008b6dcc0SBarry Smith ISColoringValue *color; 3211ee4f033dSBarry Smith 3212ee4f033dSBarry Smith PetscFunctionBegin; 3213e005ede5SBarry Smith if (!a->coloring) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix"); 3214ee4f033dSBarry Smith color = a->coloring->colors; 3215ee4f033dSBarry Smith /* loop over rows */ 3216ee4f033dSBarry Smith for (i=0; i<m; i++) { 3217ee4f033dSBarry Smith nz = ii[i+1] - ii[i]; 3218ee4f033dSBarry Smith /* loop over columns putting computed value into matrix */ 3219ee4f033dSBarry Smith for (j=0; j<nz; j++) { 3220ee4f033dSBarry Smith *v++ = values[color[*jj++]]; 3221ee4f033dSBarry Smith } 3222ee4f033dSBarry Smith values += nl; /* jump to next row of derivatives */ 3223cc8ba8e1SBarry Smith } 3224cc8ba8e1SBarry Smith PetscFunctionReturn(0); 3225cc8ba8e1SBarry Smith } 322636db0b34SBarry Smith 3227