1992c00aaSSatish Balay #define PETSCMAT_DLL 2b3cc6726SBarry Smith 3b377110cSBarry Smith 4d5d45c9bSBarry Smith /* 53369ce9aSBarry Smith Defines the basic matrix operations for the AIJ (compressed row) 6d5d45c9bSBarry Smith matrix storage format. 7d5d45c9bSBarry Smith */ 83369ce9aSBarry Smith 97c4f633dSBarry Smith 107c4f633dSBarry Smith #include "../src/mat/impls/aij/seq/aij.h" /*I "petscmat.h" I*/ 11f3da1532SBarry Smith #include "petscblaslapack.h" 120a835dfdSSatish Balay #include "petscbt.h" 1317ab2063SBarry Smith 144a2ae208SSatish Balay #undef __FUNCT__ 1579299369SBarry Smith #define __FUNCT__ "MatDiagonalSet_SeqAIJ" 167087cfbeSBarry Smith PetscErrorCode MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is) 1779299369SBarry Smith { 1879299369SBarry Smith PetscErrorCode ierr; 1979299369SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) Y->data; 20d0f46423SBarry Smith PetscInt i,*diag, m = Y->rmap->n; 2154f21887SBarry Smith MatScalar *aa = aij->a; 2254f21887SBarry Smith PetscScalar *v; 23ace3abfcSBarry Smith PetscBool missing; 2479299369SBarry Smith 2579299369SBarry Smith PetscFunctionBegin; 2609f38230SBarry Smith if (Y->assembled) { 2709f38230SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,PETSC_NULL);CHKERRQ(ierr); 2809f38230SBarry Smith if (!missing) { 2979299369SBarry Smith diag = aij->diag; 3079299369SBarry Smith ierr = VecGetArray(D,&v);CHKERRQ(ierr); 3179299369SBarry Smith if (is == INSERT_VALUES) { 3279299369SBarry Smith for (i=0; i<m; i++) { 3379299369SBarry Smith aa[diag[i]] = v[i]; 3479299369SBarry Smith } 3579299369SBarry Smith } else { 3679299369SBarry Smith for (i=0; i<m; i++) { 3779299369SBarry Smith aa[diag[i]] += v[i]; 3879299369SBarry Smith } 3979299369SBarry Smith } 4079299369SBarry Smith ierr = VecRestoreArray(D,&v);CHKERRQ(ierr); 4179299369SBarry Smith PetscFunctionReturn(0); 4279299369SBarry Smith } 4309f38230SBarry Smith } 4409f38230SBarry Smith ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr); 4509f38230SBarry Smith PetscFunctionReturn(0); 4609f38230SBarry Smith } 4779299369SBarry Smith 4879299369SBarry Smith #undef __FUNCT__ 494a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ" 50ace3abfcSBarry Smith PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,PetscInt *ia[],PetscInt *ja[],PetscBool *done) 5117ab2063SBarry Smith { 52416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 53dfbe8321SBarry Smith PetscErrorCode ierr; 5497f1f81fSBarry Smith PetscInt i,ishift; 5517ab2063SBarry Smith 563a40ed3dSBarry Smith PetscFunctionBegin; 57d0f46423SBarry Smith *m = A->rmap->n; 583a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 59bfeeae90SHong Zhang ishift = 0; 6053e63a63SBarry Smith if (symmetric && !A->structurally_symmetric) { 61d0f46423SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr); 62bfeeae90SHong Zhang } else if (oshift == 1) { 63d0f46423SBarry Smith PetscInt nz = a->i[A->rmap->n]; 643b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 65d0f46423SBarry Smith ierr = PetscMalloc((A->rmap->n+1)*sizeof(PetscInt),ia);CHKERRQ(ierr); 66d0f46423SBarry Smith for (i=0; i<A->rmap->n+1; i++) (*ia)[i] = a->i[i] + 1; 67ecc77c7aSBarry Smith if (ja) { 6897f1f81fSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscInt),ja);CHKERRQ(ierr); 693b2fbd54SBarry Smith for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1; 70ecc77c7aSBarry Smith } 716945ee14SBarry Smith } else { 72ecc77c7aSBarry Smith *ia = a->i; 73ecc77c7aSBarry Smith if (ja) *ja = a->j; 74a2ce50c7SBarry Smith } 753a40ed3dSBarry Smith PetscFunctionReturn(0); 76a2744918SBarry Smith } 77a2744918SBarry Smith 784a2ae208SSatish Balay #undef __FUNCT__ 794a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ" 80ace3abfcSBarry Smith PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscBool *done) 816945ee14SBarry Smith { 82dfbe8321SBarry Smith PetscErrorCode ierr; 836945ee14SBarry Smith 843a40ed3dSBarry Smith PetscFunctionBegin; 853a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 86bfeeae90SHong Zhang if ((symmetric && !A->structurally_symmetric) || oshift == 1) { 87606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 88ecc77c7aSBarry Smith if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);} 89bcd2baecSBarry Smith } 903a40ed3dSBarry Smith PetscFunctionReturn(0); 9117ab2063SBarry Smith } 9217ab2063SBarry Smith 934a2ae208SSatish Balay #undef __FUNCT__ 944a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ" 95ace3abfcSBarry Smith PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,PetscInt *ia[],PetscInt *ja[],PetscBool *done) 963b2fbd54SBarry Smith { 973b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 98dfbe8321SBarry Smith PetscErrorCode ierr; 99d0f46423SBarry Smith PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 10097f1f81fSBarry Smith PetscInt nz = a->i[m],row,*jj,mr,col; 1013b2fbd54SBarry Smith 1023a40ed3dSBarry Smith PetscFunctionBegin; 103899cda47SBarry Smith *nn = n; 1043a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 1053b2fbd54SBarry Smith if (symmetric) { 106d0f46423SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr); 1073b2fbd54SBarry Smith } else { 10897f1f81fSBarry Smith ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr); 10997f1f81fSBarry Smith ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 11097f1f81fSBarry Smith ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr); 11197f1f81fSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr); 1123b2fbd54SBarry Smith jj = a->j; 1133b2fbd54SBarry Smith for (i=0; i<nz; i++) { 114bfeeae90SHong Zhang collengths[jj[i]]++; 1153b2fbd54SBarry Smith } 1163b2fbd54SBarry Smith cia[0] = oshift; 1173b2fbd54SBarry Smith for (i=0; i<n; i++) { 1183b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 1193b2fbd54SBarry Smith } 12097f1f81fSBarry Smith ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 1213b2fbd54SBarry Smith jj = a->j; 122a93ec695SBarry Smith for (row=0; row<m; row++) { 123a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 124a93ec695SBarry Smith for (i=0; i<mr; i++) { 125bfeeae90SHong Zhang col = *jj++; 1263b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 1273b2fbd54SBarry Smith } 1283b2fbd54SBarry Smith } 129606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 1303b2fbd54SBarry Smith *ia = cia; *ja = cja; 1313b2fbd54SBarry Smith } 1323a40ed3dSBarry Smith PetscFunctionReturn(0); 1333b2fbd54SBarry Smith } 1343b2fbd54SBarry Smith 1354a2ae208SSatish Balay #undef __FUNCT__ 1364a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ" 137ace3abfcSBarry Smith PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscBool *done) 1383b2fbd54SBarry Smith { 139dfbe8321SBarry Smith PetscErrorCode ierr; 140606d414cSSatish Balay 1413a40ed3dSBarry Smith PetscFunctionBegin; 1423a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 1433b2fbd54SBarry Smith 144606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 145606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 1463b2fbd54SBarry Smith 1473a40ed3dSBarry Smith PetscFunctionReturn(0); 1483b2fbd54SBarry Smith } 1493b2fbd54SBarry Smith 15087d4246cSBarry Smith #undef __FUNCT__ 15187d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ" 15287d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[]) 15387d4246cSBarry Smith { 15487d4246cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 15587d4246cSBarry Smith PetscInt *ai = a->i; 15687d4246cSBarry Smith PetscErrorCode ierr; 15787d4246cSBarry Smith 15887d4246cSBarry Smith PetscFunctionBegin; 15987d4246cSBarry Smith ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr); 16087d4246cSBarry Smith PetscFunctionReturn(0); 16187d4246cSBarry Smith } 16287d4246cSBarry Smith 1634a2ae208SSatish Balay #undef __FUNCT__ 1644a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ" 16597f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 16617ab2063SBarry Smith { 167416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 168e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 16997f1f81fSBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 1706849ba73SBarry Smith PetscErrorCode ierr; 171e2ee6c50SBarry Smith PetscInt *aj = a->j,nonew = a->nonew,lastcol = -1; 17254f21887SBarry Smith MatScalar *ap,value,*aa = a->a; 173ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 174ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 17517ab2063SBarry Smith 1763a40ed3dSBarry Smith PetscFunctionBegin; 17771fd2e92SBarry Smith if (v) PetscValidScalarPointer(v,6); 17817ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 179416022c9SBarry Smith row = im[k]; 1805ef9f2a5SBarry Smith if (row < 0) continue; 1812515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 182e32f2f54SBarry Smith if (row >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->n-1); 1833b2fbd54SBarry Smith #endif 184bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 18517ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 186416022c9SBarry Smith low = 0; 187c71e6ed7SBarry Smith high = nrow; 18817ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 1895ef9f2a5SBarry Smith if (in[l] < 0) continue; 1902515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 191e32f2f54SBarry Smith if (in[l] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->cmap->n-1); 1923b2fbd54SBarry Smith #endif 193bfeeae90SHong Zhang col = in[l]; 19416371a99SBarry Smith if (v) { 1954b0e389bSBarry Smith if (roworiented) { 1965ef9f2a5SBarry Smith value = v[l + k*n]; 197bef8e0ddSBarry Smith } else { 1984b0e389bSBarry Smith value = v[k + l*m]; 1994b0e389bSBarry Smith } 20016371a99SBarry Smith } else { 20175567043SBarry Smith value = 0.; 20216371a99SBarry Smith } 203abc0a331SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 20436db0b34SBarry Smith 2057cd84e04SBarry Smith if (col <= lastcol) low = 0; else high = nrow; 206e2ee6c50SBarry Smith lastcol = col; 207416022c9SBarry Smith while (high-low > 5) { 208416022c9SBarry Smith t = (low+high)/2; 209416022c9SBarry Smith if (rp[t] > col) high = t; 210416022c9SBarry Smith else low = t; 21117ab2063SBarry Smith } 212416022c9SBarry Smith for (i=low; i<high; i++) { 21317ab2063SBarry Smith if (rp[i] > col) break; 21417ab2063SBarry Smith if (rp[i] == col) { 215416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 21617ab2063SBarry Smith else ap[i] = value; 217e44c0bd4SBarry Smith low = i + 1; 21817ab2063SBarry Smith goto noinsert; 21917ab2063SBarry Smith } 22017ab2063SBarry Smith } 221abc0a331SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 222c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 223e32f2f54SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 224fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 225c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 226416022c9SBarry Smith /* shift up all the later entries in this row */ 227416022c9SBarry Smith for (ii=N; ii>=i; ii--) { 22817ab2063SBarry Smith rp[ii+1] = rp[ii]; 22917ab2063SBarry Smith ap[ii+1] = ap[ii]; 23017ab2063SBarry Smith } 23117ab2063SBarry Smith rp[i] = col; 23217ab2063SBarry Smith ap[i] = value; 233416022c9SBarry Smith low = i + 1; 234e44c0bd4SBarry Smith noinsert:; 23517ab2063SBarry Smith } 23617ab2063SBarry Smith ailen[row] = nrow; 23717ab2063SBarry Smith } 23888e51ccdSHong Zhang A->same_nonzero = PETSC_FALSE; 2393a40ed3dSBarry Smith PetscFunctionReturn(0); 24017ab2063SBarry Smith } 24117ab2063SBarry Smith 24281824310SBarry Smith 2434a2ae208SSatish Balay #undef __FUNCT__ 2444a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ" 245a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 2467eb43aa7SLois Curfman McInnes { 2477eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 24897f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 24997f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 25054f21887SBarry Smith MatScalar *ap,*aa = a->a; 2517eb43aa7SLois Curfman McInnes 2523a40ed3dSBarry Smith PetscFunctionBegin; 2537eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 2547eb43aa7SLois Curfman McInnes row = im[k]; 255e32f2f54SBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 256e32f2f54SBarry Smith if (row >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->n-1); 257bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 2587eb43aa7SLois Curfman McInnes nrow = ailen[row]; 2597eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 260e32f2f54SBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 261e32f2f54SBarry Smith if (in[l] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->cmap->n-1); 262bfeeae90SHong Zhang col = in[l] ; 2637eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 2647eb43aa7SLois Curfman McInnes while (high-low > 5) { 2657eb43aa7SLois Curfman McInnes t = (low+high)/2; 2667eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 2677eb43aa7SLois Curfman McInnes else low = t; 2687eb43aa7SLois Curfman McInnes } 2697eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 2707eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 2717eb43aa7SLois Curfman McInnes if (rp[i] == col) { 272b49de8d1SLois Curfman McInnes *v++ = ap[i]; 2737eb43aa7SLois Curfman McInnes goto finished; 2747eb43aa7SLois Curfman McInnes } 2757eb43aa7SLois Curfman McInnes } 27697e567efSBarry Smith *v++ = 0.0; 2777eb43aa7SLois Curfman McInnes finished:; 2787eb43aa7SLois Curfman McInnes } 2797eb43aa7SLois Curfman McInnes } 2803a40ed3dSBarry Smith PetscFunctionReturn(0); 2817eb43aa7SLois Curfman McInnes } 2827eb43aa7SLois Curfman McInnes 28317ab2063SBarry Smith 2844a2ae208SSatish Balay #undef __FUNCT__ 2854a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary" 286dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer) 28717ab2063SBarry Smith { 288416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2896849ba73SBarry Smith PetscErrorCode ierr; 2906f69ff64SBarry Smith PetscInt i,*col_lens; 2916f69ff64SBarry Smith int fd; 29217ab2063SBarry Smith 2933a40ed3dSBarry Smith PetscFunctionBegin; 294b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 295d0f46423SBarry Smith ierr = PetscMalloc((4+A->rmap->n)*sizeof(PetscInt),&col_lens);CHKERRQ(ierr); 2960700a824SBarry Smith col_lens[0] = MAT_FILE_CLASSID; 297d0f46423SBarry Smith col_lens[1] = A->rmap->n; 298d0f46423SBarry Smith col_lens[2] = A->cmap->n; 299416022c9SBarry Smith col_lens[3] = a->nz; 300416022c9SBarry Smith 301416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 302d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 303416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 30417ab2063SBarry Smith } 305d0f46423SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 306606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 307416022c9SBarry Smith 308416022c9SBarry Smith /* store column indices (zero start index) */ 3096f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 310416022c9SBarry Smith 311416022c9SBarry Smith /* store nonzero values */ 3126f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 3133a40ed3dSBarry Smith PetscFunctionReturn(0); 31417ab2063SBarry Smith } 315416022c9SBarry Smith 31609573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 317cd155464SBarry Smith 3184a2ae208SSatish Balay #undef __FUNCT__ 3194a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII" 320dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 321416022c9SBarry Smith { 322416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 323dfbe8321SBarry Smith PetscErrorCode ierr; 324d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,shift=0; 325e060cb09SBarry Smith const char *name; 326f3ef73ceSBarry Smith PetscViewerFormat format; 32717ab2063SBarry Smith 3283a40ed3dSBarry Smith PetscFunctionBegin; 329b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 33071c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 33197f1f81fSBarry Smith PetscInt nofinalvalue = 0; 332d0f46423SBarry Smith if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-!shift)) { 333d00d2cf4SBarry Smith nofinalvalue = 1; 334d00d2cf4SBarry Smith } 335d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 336d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 33777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 33877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 339b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 34017ab2063SBarry Smith 34117ab2063SBarry Smith for (i=0; i<m; i++) { 342416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 343aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 34477431f27SBarry 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); 34517ab2063SBarry Smith #else 34677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr); 34717ab2063SBarry Smith #endif 34817ab2063SBarry Smith } 34917ab2063SBarry Smith } 350d00d2cf4SBarry Smith if (nofinalvalue) { 351d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 352d00d2cf4SBarry Smith } 353317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 354fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 355d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 35668369a75SKris Buschelman } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) { 357cd155464SBarry Smith PetscFunctionReturn(0); 358fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 359d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 3607566de4bSShri Abhyankar ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr); 36144cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 36277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 36344cd7ae7SLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 364aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 36536db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 366a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 36736db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 368a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 36936db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 370a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 3716831982aSBarry Smith } 37244cd7ae7SLois Curfman McInnes #else 373a83599f4SBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);} 37444cd7ae7SLois Curfman McInnes #endif 37544cd7ae7SLois Curfman McInnes } 376b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 37744cd7ae7SLois Curfman McInnes } 378d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 379fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 38097f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 381d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 3827566de4bSShri Abhyankar ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr); 38397f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&sptr);CHKERRQ(ierr); 384496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 385496be53dSLois Curfman McInnes sptr[i] = nzd+1; 386496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 387496be53dSLois Curfman McInnes if (a->j[j] >= i) { 388aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 38936db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 390496be53dSLois Curfman McInnes #else 391496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 392496be53dSLois Curfman McInnes #endif 393496be53dSLois Curfman McInnes } 394496be53dSLois Curfman McInnes } 395496be53dSLois Curfman McInnes } 3962e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 39777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 3982e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 39977431f27SBarry 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);} 40077431f27SBarry 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);} 40177431f27SBarry 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);} 40277431f27SBarry Smith else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);} 40377431f27SBarry Smith else if (i<m) {ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);} 40477431f27SBarry Smith else {ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);} 405496be53dSLois Curfman McInnes } 406b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 407606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 408496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 409496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 41077431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 411496be53dSLois Curfman McInnes } 412b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 413496be53dSLois Curfman McInnes } 414b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 415496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 416496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 417496be53dSLois Curfman McInnes if (a->j[j] >= i) { 418aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 41936db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 420b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 4216831982aSBarry Smith } 422496be53dSLois Curfman McInnes #else 423b0a32e0cSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);} 424496be53dSLois Curfman McInnes #endif 425496be53dSLois Curfman McInnes } 426496be53dSLois Curfman McInnes } 427b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 428496be53dSLois Curfman McInnes } 429d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 430fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 43197f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 43287828ca2SBarry Smith PetscScalar value; 43302594712SBarry Smith 434d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 4357566de4bSShri Abhyankar ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr); 43602594712SBarry Smith for (i=0; i<m; i++) { 43702594712SBarry Smith jcnt = 0; 438d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 439e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 44002594712SBarry Smith value = a->a[cnt++]; 441e24b481bSBarry Smith jcnt++; 44202594712SBarry Smith } else { 44302594712SBarry Smith value = 0.0; 44402594712SBarry Smith } 445aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 446b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr); 44702594712SBarry Smith #else 448b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr); 44902594712SBarry Smith #endif 45002594712SBarry Smith } 451b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 45202594712SBarry Smith } 453d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 4543c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 455d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 4567566de4bSShri Abhyankar ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr); 4573c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 4583c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr); 4593c215bfdSMatthew Knepley #else 4603c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr); 4613c215bfdSMatthew Knepley #endif 462d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 4633c215bfdSMatthew Knepley for (i=0; i<m; i++) { 4643c215bfdSMatthew Knepley for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 4653c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 4663c215bfdSMatthew Knepley if (PetscImaginaryPart(a->a[j]) > 0.0) { 4673c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %G %G\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 4683c215bfdSMatthew Knepley } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 4693c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %G -%G\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 4703c215bfdSMatthew Knepley } else { 4713c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %G\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 4723c215bfdSMatthew Knepley } 4733c215bfdSMatthew Knepley #else 4743c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D %G\n", i+shift, a->j[j]+shift, a->a[j]);CHKERRQ(ierr); 4753c215bfdSMatthew Knepley #endif 4763c215bfdSMatthew Knepley } 4773c215bfdSMatthew Knepley } 478d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 4793a40ed3dSBarry Smith } else { 480d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 4817566de4bSShri Abhyankar ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr); 482d5f3da31SBarry Smith if (A->factortype){ 48316cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 48416cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 48516cd7e1dSShri Abhyankar /* L part */ 48616cd7e1dSShri Abhyankar for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 48716cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 48816cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 48916cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 49016cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 49116cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 49216cd7e1dSShri Abhyankar } else { 49316cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 49416cd7e1dSShri Abhyankar } 49516cd7e1dSShri Abhyankar #else 49616cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 49716cd7e1dSShri Abhyankar #endif 49816cd7e1dSShri Abhyankar } 49916cd7e1dSShri Abhyankar /* diagonal */ 50016cd7e1dSShri Abhyankar j = a->diag[i]; 50116cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 50216cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 50316cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 50416cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 50516cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 50616cd7e1dSShri Abhyankar } else { 50716cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 50816cd7e1dSShri Abhyankar } 50916cd7e1dSShri Abhyankar #else 51016cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 51116cd7e1dSShri Abhyankar #endif 51216cd7e1dSShri Abhyankar 51316cd7e1dSShri Abhyankar /* U part */ 51416cd7e1dSShri Abhyankar for (j=a->diag[i+1]+1+shift; j<a->diag[i]+shift; j++) { 51516cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 51616cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 51716cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 51816cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 51916cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 52016cd7e1dSShri Abhyankar } else { 52116cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 52216cd7e1dSShri Abhyankar } 52316cd7e1dSShri Abhyankar #else 52416cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 52516cd7e1dSShri Abhyankar #endif 52616cd7e1dSShri Abhyankar } 52716cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 52816cd7e1dSShri Abhyankar } 52916cd7e1dSShri Abhyankar } else { 53017ab2063SBarry Smith for (i=0; i<m; i++) { 53177431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 532416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 533aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 53436db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 535a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 53636db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 537a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 5383a40ed3dSBarry Smith } else { 539a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 54017ab2063SBarry Smith } 54117ab2063SBarry Smith #else 542a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 54317ab2063SBarry Smith #endif 54417ab2063SBarry Smith } 545b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 54617ab2063SBarry Smith } 54716cd7e1dSShri Abhyankar } 548d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 54917ab2063SBarry Smith } 550b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 5513a40ed3dSBarry Smith PetscFunctionReturn(0); 552416022c9SBarry Smith } 553416022c9SBarry Smith 5544a2ae208SSatish Balay #undef __FUNCT__ 5554a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom" 556dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 557416022c9SBarry Smith { 558480ef9eaSBarry Smith Mat A = (Mat) Aa; 559416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 560dfbe8321SBarry Smith PetscErrorCode ierr; 561d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,color; 56236db0b34SBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0; 563b0a32e0cSBarry Smith PetscViewer viewer; 564f3ef73ceSBarry Smith PetscViewerFormat format; 565cddf8d76SBarry Smith 5663a40ed3dSBarry Smith PetscFunctionBegin; 567480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 568b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 56919bcc07fSBarry Smith 570b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 571416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 5720513a670SBarry Smith 573fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 5740513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 575b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 576416022c9SBarry Smith for (i=0; i<m; i++) { 577cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 578bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 579bfeeae90SHong Zhang x_l = a->j[j] ; x_r = x_l + 1.0; 580aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 58136db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 582cddf8d76SBarry Smith #else 583cddf8d76SBarry Smith if (a->a[j] >= 0.) continue; 584cddf8d76SBarry Smith #endif 585b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 586cddf8d76SBarry Smith } 587cddf8d76SBarry Smith } 588b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 589cddf8d76SBarry Smith for (i=0; i<m; i++) { 590cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 591bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 592bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 593cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 594b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 595cddf8d76SBarry Smith } 596cddf8d76SBarry Smith } 597b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 598cddf8d76SBarry Smith for (i=0; i<m; i++) { 599cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 600bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 601bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 602aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 60336db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 604cddf8d76SBarry Smith #else 605cddf8d76SBarry Smith if (a->a[j] <= 0.) continue; 606cddf8d76SBarry Smith #endif 607b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 608416022c9SBarry Smith } 609416022c9SBarry Smith } 6100513a670SBarry Smith } else { 6110513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 6120513a670SBarry Smith /* first determine max of all nonzero values */ 61397f1f81fSBarry Smith PetscInt nz = a->nz,count; 614b0a32e0cSBarry Smith PetscDraw popup; 61536db0b34SBarry Smith PetscReal scale; 6160513a670SBarry Smith 6170513a670SBarry Smith for (i=0; i<nz; i++) { 6180513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 6190513a670SBarry Smith } 620b0a32e0cSBarry Smith scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv; 621b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 622b0a32e0cSBarry Smith if (popup) {ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);} 6230513a670SBarry Smith count = 0; 6240513a670SBarry Smith for (i=0; i<m; i++) { 6250513a670SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 626bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 627bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 62897f1f81fSBarry Smith color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count])); 629b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 6300513a670SBarry Smith count++; 6310513a670SBarry Smith } 6320513a670SBarry Smith } 6330513a670SBarry Smith } 634480ef9eaSBarry Smith PetscFunctionReturn(0); 635480ef9eaSBarry Smith } 636cddf8d76SBarry Smith 6374a2ae208SSatish Balay #undef __FUNCT__ 6384a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw" 639dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 640480ef9eaSBarry Smith { 641dfbe8321SBarry Smith PetscErrorCode ierr; 642b0a32e0cSBarry Smith PetscDraw draw; 64336db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 644ace3abfcSBarry Smith PetscBool isnull; 645480ef9eaSBarry Smith 646480ef9eaSBarry Smith PetscFunctionBegin; 647b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 648b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 649480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 650480ef9eaSBarry Smith 651480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 652d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 653480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 654b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 655b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 656480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 6573a40ed3dSBarry Smith PetscFunctionReturn(0); 658416022c9SBarry Smith } 659416022c9SBarry Smith 6604a2ae208SSatish Balay #undef __FUNCT__ 6614a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ" 662dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 663416022c9SBarry Smith { 664dfbe8321SBarry Smith PetscErrorCode ierr; 665ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 666416022c9SBarry Smith 6673a40ed3dSBarry Smith PetscFunctionBegin; 6682692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 6692692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 6702692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 671c45a1595SBarry Smith if (iascii) { 6723a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 6730f5bd95cSBarry Smith } else if (isbinary) { 6743a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 6750f5bd95cSBarry Smith } else if (isdraw) { 6763a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 6775cd90555SBarry Smith } else { 678e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name); 67917ab2063SBarry Smith } 6804108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 6813a40ed3dSBarry Smith PetscFunctionReturn(0); 68217ab2063SBarry Smith } 68319bcc07fSBarry Smith 6844a2ae208SSatish Balay #undef __FUNCT__ 6854a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ" 686dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 68717ab2063SBarry Smith { 688416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 6896849ba73SBarry Smith PetscErrorCode ierr; 69097f1f81fSBarry Smith PetscInt fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 691d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 69254f21887SBarry Smith MatScalar *aa = a->a,*ap; 6933447b6efSHong Zhang PetscReal ratio=0.6; 69417ab2063SBarry Smith 6953a40ed3dSBarry Smith PetscFunctionBegin; 6963a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 69717ab2063SBarry Smith 69843ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 69917ab2063SBarry Smith for (i=1; i<m; i++) { 700416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 70117ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 70294a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 70317ab2063SBarry Smith if (fshift) { 704bfeeae90SHong Zhang ip = aj + ai[i] ; 705bfeeae90SHong Zhang ap = aa + ai[i] ; 70617ab2063SBarry Smith N = ailen[i]; 70717ab2063SBarry Smith for (j=0; j<N; j++) { 70817ab2063SBarry Smith ip[j-fshift] = ip[j]; 70917ab2063SBarry Smith ap[j-fshift] = ap[j]; 71017ab2063SBarry Smith } 71117ab2063SBarry Smith } 71217ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 71317ab2063SBarry Smith } 71417ab2063SBarry Smith if (m) { 71517ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 71617ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 71717ab2063SBarry Smith } 71817ab2063SBarry Smith /* reset ilen and imax for each row */ 71917ab2063SBarry Smith for (i=0; i<m; i++) { 72017ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 72117ab2063SBarry Smith } 722bfeeae90SHong Zhang a->nz = ai[m]; 72365e19b50SBarry Smith if (fshift && a->nounused == -1) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB, "Unused space detected in matrix: %D X %D, %D unneeded", m, A->cmap->n, fshift); 72417ab2063SBarry Smith 72509f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 726d0f46423SBarry Smith ierr = PetscInfo4(A,"Matrix size: %D X %D; storage space: %D unneeded,%D used\n",m,A->cmap->n,fshift,a->nz);CHKERRQ(ierr); 727ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 728ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 7298e58a170SBarry Smith A->info.mallocs += a->reallocs; 730dd5f02e7SSatish Balay a->reallocs = 0; 7314e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift; 73236db0b34SBarry Smith a->rmax = rmax; 7334e220ebcSLois Curfman McInnes 734cd6b891eSBarry Smith ierr = MatCheckCompressedRow(A,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 73588e51ccdSHong Zhang A->same_nonzero = PETSC_TRUE; 73671c2f376SKris Buschelman 7374108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 73871f1c65dSBarry Smith 73971f1c65dSBarry Smith a->idiagvalid = PETSC_FALSE; 7403a40ed3dSBarry Smith PetscFunctionReturn(0); 74117ab2063SBarry Smith } 74217ab2063SBarry Smith 7434a2ae208SSatish Balay #undef __FUNCT__ 74499cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ" 74599cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 74699cafbc1SBarry Smith { 74799cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 74899cafbc1SBarry Smith PetscInt i,nz = a->nz; 74954f21887SBarry Smith MatScalar *aa = a->a; 75099cafbc1SBarry Smith 75199cafbc1SBarry Smith PetscFunctionBegin; 75299cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 75399cafbc1SBarry Smith PetscFunctionReturn(0); 75499cafbc1SBarry Smith } 75599cafbc1SBarry Smith 75699cafbc1SBarry Smith #undef __FUNCT__ 75799cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ" 75899cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 75999cafbc1SBarry Smith { 76099cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 76199cafbc1SBarry Smith PetscInt i,nz = a->nz; 76254f21887SBarry Smith MatScalar *aa = a->a; 76399cafbc1SBarry Smith 76499cafbc1SBarry Smith PetscFunctionBegin; 76599cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 76699cafbc1SBarry Smith PetscFunctionReturn(0); 76799cafbc1SBarry Smith } 76899cafbc1SBarry Smith 76999cafbc1SBarry Smith #undef __FUNCT__ 7704a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ" 771dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 77217ab2063SBarry Smith { 773416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 774dfbe8321SBarry Smith PetscErrorCode ierr; 7753a40ed3dSBarry Smith 7763a40ed3dSBarry Smith PetscFunctionBegin; 777d0f46423SBarry Smith ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 7783a40ed3dSBarry Smith PetscFunctionReturn(0); 77917ab2063SBarry Smith } 780416022c9SBarry Smith 7814a2ae208SSatish Balay #undef __FUNCT__ 7824a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ" 783dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 78417ab2063SBarry Smith { 785416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 786dfbe8321SBarry Smith PetscErrorCode ierr; 787d5d45c9bSBarry Smith 7883a40ed3dSBarry Smith PetscFunctionBegin; 789aa482453SBarry Smith #if defined(PETSC_USE_LOG) 790d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 79117ab2063SBarry Smith #endif 792e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 793c38d4ed2SBarry Smith if (a->row) { 794c38d4ed2SBarry Smith ierr = ISDestroy(a->row);CHKERRQ(ierr); 795c38d4ed2SBarry Smith } 796c38d4ed2SBarry Smith if (a->col) { 797c38d4ed2SBarry Smith ierr = ISDestroy(a->col);CHKERRQ(ierr); 798c38d4ed2SBarry Smith } 79905b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 80005b42c5fSBarry Smith ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr); 80171f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 80205b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 80382bf6240SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 80405b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 805cc8ba8e1SBarry Smith if (a->coloring) {ierr = ISColoringDestroy(a->coloring);CHKERRQ(ierr);} 80605b42c5fSBarry Smith ierr = PetscFree(a->xtoy);CHKERRQ(ierr); 807407f6b05SHong Zhang if (a->XtoY) {ierr = MatDestroy(a->XtoY);CHKERRQ(ierr);} 808cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 809a30b2313SHong Zhang 8104108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 8114846f1f5SKris Buschelman 812606d414cSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 813901853e0SKris Buschelman 814dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 815901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetColumnIndices_C","",PETSC_NULL);CHKERRQ(ierr); 816901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatStoreValues_C","",PETSC_NULL);CHKERRQ(ierr); 817901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatRetrieveValues_C","",PETSC_NULL);CHKERRQ(ierr); 818901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqsbaij_C","",PETSC_NULL);CHKERRQ(ierr); 819901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqbaij_C","",PETSC_NULL);CHKERRQ(ierr); 8205a11e1b2SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqaijperm_C","",PETSC_NULL);CHKERRQ(ierr); 821901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatIsTranspose_C","",PETSC_NULL);CHKERRQ(ierr); 822901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocation_C","",PETSC_NULL);CHKERRQ(ierr); 823a1661176SMatthew Knepley ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C","",PETSC_NULL);CHKERRQ(ierr); 824901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatReorderForNonzeroDiagonal_C","",PETSC_NULL);CHKERRQ(ierr); 8253a40ed3dSBarry Smith PetscFunctionReturn(0); 82617ab2063SBarry Smith } 82717ab2063SBarry Smith 8284a2ae208SSatish Balay #undef __FUNCT__ 8294a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ" 830ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 83117ab2063SBarry Smith { 832416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 8334846f1f5SKris Buschelman PetscErrorCode ierr; 8343a40ed3dSBarry Smith 8353a40ed3dSBarry Smith PetscFunctionBegin; 836a65d3064SKris Buschelman switch (op) { 837a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 8384e0d8c25SBarry Smith a->roworiented = flg; 839a65d3064SKris Buschelman break; 840a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 841a9817697SBarry Smith a->keepnonzeropattern = flg; 842a65d3064SKris Buschelman break; 843512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 844512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 845a65d3064SKris Buschelman break; 846a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 8474e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 848a65d3064SKris Buschelman break; 849a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 8504e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 851a65d3064SKris Buschelman break; 85228b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 85328b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 85428b2fa4aSMatthew Knepley break; 855a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 8564e0d8c25SBarry Smith a->ignorezeroentries = flg; 8570df259c2SBarry Smith break; 858cd6b891eSBarry Smith case MAT_CHECK_COMPRESSED_ROW: 859cd6b891eSBarry Smith a->compressedrow.check = flg; 860d487561eSHong Zhang break; 8613d472b54SHong Zhang case MAT_SPD: 8623d472b54SHong Zhang A->spd_set = PETSC_TRUE; 8633d472b54SHong Zhang A->spd = flg; 8643d472b54SHong Zhang if (flg) { 8653d472b54SHong Zhang A->symmetric = PETSC_TRUE; 8663d472b54SHong Zhang A->structurally_symmetric = PETSC_TRUE; 8673d472b54SHong Zhang A->symmetric_set = PETSC_TRUE; 8683d472b54SHong Zhang A->structurally_symmetric_set = PETSC_TRUE; 8693d472b54SHong Zhang } 8703d472b54SHong Zhang break; 871b1646e73SJed Brown case MAT_SYMMETRIC: 872b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 873b1646e73SJed Brown case MAT_HERMITIAN: 874b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 8754e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 876a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 877a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 878290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 879a65d3064SKris Buschelman break; 880b87ac2d8SJed Brown case MAT_USE_INODES: 881b87ac2d8SJed Brown /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */ 882b87ac2d8SJed Brown break; 883a65d3064SKris Buschelman default: 884e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 885a65d3064SKris Buschelman } 8864108e4d5SBarry Smith ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr); 8873a40ed3dSBarry Smith PetscFunctionReturn(0); 88817ab2063SBarry Smith } 88917ab2063SBarry Smith 8904a2ae208SSatish Balay #undef __FUNCT__ 8914a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ" 892dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 89317ab2063SBarry Smith { 894416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 8956849ba73SBarry Smith PetscErrorCode ierr; 896d3e70bfaSHong Zhang PetscInt i,j,n,*ai=a->i,*aj=a->j,nz; 89735e7444dSHong Zhang PetscScalar *aa=a->a,*x,zero=0.0; 89817ab2063SBarry Smith 8993a40ed3dSBarry Smith PetscFunctionBegin; 900d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 901e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 90235e7444dSHong Zhang 903d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU){ 904d3e70bfaSHong Zhang PetscInt *diag=a->diag; 90535e7444dSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 90635e7444dSHong Zhang for (i=0; i<n; i++) x[i] = aa[diag[i]]; 90735e7444dSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 90835e7444dSHong Zhang PetscFunctionReturn(0); 90935e7444dSHong Zhang } 91035e7444dSHong Zhang 9112dcb1b2aSMatthew Knepley ierr = VecSet(v,zero);CHKERRQ(ierr); 9121ebc52fbSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 91335e7444dSHong Zhang for (i=0; i<n; i++) { 91435e7444dSHong Zhang nz = ai[i+1] - ai[i]; 9152f5a7c2eSBarry Smith if (!nz) x[i] = 0.0; 91635e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++){ 91735e7444dSHong Zhang if (aj[j] == i) { 91835e7444dSHong Zhang x[i] = aa[j]; 91917ab2063SBarry Smith break; 92017ab2063SBarry Smith } 92117ab2063SBarry Smith } 92217ab2063SBarry Smith } 9231ebc52fbSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 9243a40ed3dSBarry Smith PetscFunctionReturn(0); 92517ab2063SBarry Smith } 92617ab2063SBarry Smith 927b377110cSBarry Smith #include "../src/mat/impls/aij/seq/ftn-kernels/fmult.h" 9284a2ae208SSatish Balay #undef __FUNCT__ 9294a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ" 930dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 93117ab2063SBarry Smith { 932416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 9335c897100SBarry Smith PetscScalar *x,*y; 934dfbe8321SBarry Smith PetscErrorCode ierr; 935d0f46423SBarry Smith PetscInt m = A->rmap->n; 9365c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 937a77337e4SBarry Smith MatScalar *v; 938a77337e4SBarry Smith PetscScalar alpha; 93904fbf559SBarry Smith PetscInt n,i,j,*idx,*ii,*ridx=PETSC_NULL; 9403447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 941ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 9425c897100SBarry Smith #endif 94317ab2063SBarry Smith 9443a40ed3dSBarry Smith PetscFunctionBegin; 9452e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 9461ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 9471ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 9485c897100SBarry Smith 9495c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 950bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 9515c897100SBarry Smith #else 9523447b6efSHong Zhang if (usecprow){ 9533447b6efSHong Zhang m = cprow.nrows; 9543447b6efSHong Zhang ii = cprow.i; 9557b2bb3b9SHong Zhang ridx = cprow.rindex; 9563447b6efSHong Zhang } else { 9573447b6efSHong Zhang ii = a->i; 9583447b6efSHong Zhang } 95917ab2063SBarry Smith for (i=0; i<m; i++) { 9603447b6efSHong Zhang idx = a->j + ii[i] ; 9613447b6efSHong Zhang v = a->a + ii[i] ; 9623447b6efSHong Zhang n = ii[i+1] - ii[i]; 9633447b6efSHong Zhang if (usecprow){ 9647b2bb3b9SHong Zhang alpha = x[ridx[i]]; 9653447b6efSHong Zhang } else { 96617ab2063SBarry Smith alpha = x[i]; 9673447b6efSHong Zhang } 96804fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 96917ab2063SBarry Smith } 9705c897100SBarry Smith #endif 971dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 9721ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 9731ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 9743a40ed3dSBarry Smith PetscFunctionReturn(0); 97517ab2063SBarry Smith } 97617ab2063SBarry Smith 9774a2ae208SSatish Balay #undef __FUNCT__ 9785c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ" 979dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 9805c897100SBarry Smith { 981dfbe8321SBarry Smith PetscErrorCode ierr; 9825c897100SBarry Smith 9835c897100SBarry Smith PetscFunctionBegin; 984170fe5c8SBarry Smith ierr = VecSet(yy,0.0);CHKERRQ(ierr); 9855c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 9865c897100SBarry Smith PetscFunctionReturn(0); 9875c897100SBarry Smith } 9885c897100SBarry Smith 989a4005a5dSBarry Smith #include "../src/mat/impls/aij/seq/ftn-kernels/fmult.h" 9905c897100SBarry Smith #undef __FUNCT__ 9914a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ" 992dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 99317ab2063SBarry Smith { 994416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 995d9fead3dSBarry Smith PetscScalar *y; 99654f21887SBarry Smith const PetscScalar *x; 99754f21887SBarry Smith const MatScalar *aa; 998dfbe8321SBarry Smith PetscErrorCode ierr; 999003131ecSBarry Smith PetscInt m=A->rmap->n; 1000003131ecSBarry Smith const PetscInt *aj,*ii,*ridx=PETSC_NULL; 10018aee2decSHong Zhang PetscInt n,i,nonzerorow=0; 1002362ced78SSatish Balay PetscScalar sum; 1003ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 100417ab2063SBarry Smith 1005b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 100697952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1007fee21e36SBarry Smith #endif 1008fee21e36SBarry Smith 10093a40ed3dSBarry Smith PetscFunctionBegin; 10103649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 10111ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 101297952fefSHong Zhang aj = a->j; 101397952fefSHong Zhang aa = a->a; 1014416022c9SBarry Smith ii = a->i; 10154eb6d288SHong Zhang if (usecprow){ /* use compressed row format */ 101697952fefSHong Zhang m = a->compressedrow.nrows; 101797952fefSHong Zhang ii = a->compressedrow.i; 101897952fefSHong Zhang ridx = a->compressedrow.rindex; 101997952fefSHong Zhang for (i=0; i<m; i++){ 102097952fefSHong Zhang n = ii[i+1] - ii[i]; 102197952fefSHong Zhang aj = a->j + ii[i]; 102297952fefSHong Zhang aa = a->a + ii[i]; 102397952fefSHong Zhang sum = 0.0; 1024a46b3154SVictor Eijkhout nonzerorow += (n>0); 1025003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1026003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 102797952fefSHong Zhang y[*ridx++] = sum; 102897952fefSHong Zhang } 102997952fefSHong Zhang } else { /* do not use compressed row format */ 1030b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 1031b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1032b05257ddSBarry Smith #else 103317ab2063SBarry Smith for (i=0; i<m; i++) { 1034003131ecSBarry Smith n = ii[i+1] - ii[i]; 1035003131ecSBarry Smith aj = a->j + ii[i]; 1036003131ecSBarry Smith aa = a->a + ii[i]; 103717ab2063SBarry Smith sum = 0.0; 1038a46b3154SVictor Eijkhout nonzerorow += (n>0); 1039003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 104017ab2063SBarry Smith y[i] = sum; 104117ab2063SBarry Smith } 10428d195f9aSBarry Smith #endif 1043b05257ddSBarry Smith } 1044dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 10453649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 10461ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 10473a40ed3dSBarry Smith PetscFunctionReturn(0); 104817ab2063SBarry Smith } 104917ab2063SBarry Smith 1050a4005a5dSBarry Smith #include "../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h" 10514a2ae208SSatish Balay #undef __FUNCT__ 10524a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ" 1053dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 105417ab2063SBarry Smith { 1055416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 105654f21887SBarry Smith PetscScalar *x,*y,*z; 105754f21887SBarry Smith const MatScalar *aa; 1058dfbe8321SBarry Smith PetscErrorCode ierr; 1059d0f46423SBarry Smith PetscInt m = A->rmap->n,*aj,*ii; 1060aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 106197952fefSHong Zhang PetscInt n,i,jrow,j,*ridx=PETSC_NULL; 1062362ced78SSatish Balay PetscScalar sum; 1063ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 1064e36a17ebSSatish Balay #endif 10659ea0dfa2SSatish Balay 10663a40ed3dSBarry Smith PetscFunctionBegin; 10671ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 10681ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 10692e8a6d31SBarry Smith if (zz != yy) { 10701ebc52fbSHong Zhang ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 10712e8a6d31SBarry Smith } else { 10722e8a6d31SBarry Smith z = y; 10732e8a6d31SBarry Smith } 1074bfeeae90SHong Zhang 107597952fefSHong Zhang aj = a->j; 107697952fefSHong Zhang aa = a->a; 1077cddf8d76SBarry Smith ii = a->i; 1078aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 107997952fefSHong Zhang fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 108002ab625aSSatish Balay #else 10814eb6d288SHong Zhang if (usecprow){ /* use compressed row format */ 10824eb6d288SHong Zhang if (zz != yy){ 10834eb6d288SHong Zhang ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 10844eb6d288SHong Zhang } 108597952fefSHong Zhang m = a->compressedrow.nrows; 108697952fefSHong Zhang ii = a->compressedrow.i; 108797952fefSHong Zhang ridx = a->compressedrow.rindex; 108897952fefSHong Zhang for (i=0; i<m; i++){ 108997952fefSHong Zhang n = ii[i+1] - ii[i]; 109097952fefSHong Zhang aj = a->j + ii[i]; 109197952fefSHong Zhang aa = a->a + ii[i]; 109297952fefSHong Zhang sum = y[*ridx]; 109397952fefSHong Zhang for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; 109497952fefSHong Zhang z[*ridx++] = sum; 109597952fefSHong Zhang } 109697952fefSHong Zhang } else { /* do not use compressed row format */ 109717ab2063SBarry Smith for (i=0; i<m; i++) { 10989ea0dfa2SSatish Balay jrow = ii[i]; 10999ea0dfa2SSatish Balay n = ii[i+1] - jrow; 110017ab2063SBarry Smith sum = y[i]; 11019ea0dfa2SSatish Balay for (j=0; j<n; j++) { 110297952fefSHong Zhang sum += aa[jrow]*x[aj[jrow]]; jrow++; 11039ea0dfa2SSatish Balay } 110417ab2063SBarry Smith z[i] = sum; 110517ab2063SBarry Smith } 110697952fefSHong Zhang } 110702ab625aSSatish Balay #endif 1108dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 11091ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 11101ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 11112e8a6d31SBarry Smith if (zz != yy) { 11121ebc52fbSHong Zhang ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 11132e8a6d31SBarry Smith } 1114918e98c3SVictor Minden #if defined(PETSC_HAVE_CUDA) 11156b375ea7SVictor Minden /* 1116918e98c3SVictor Minden ierr = VecView(xx,0);CHKERRQ(ierr); 1117918e98c3SVictor Minden ierr = VecView(zz,0);CHKERRQ(ierr); 1118918e98c3SVictor Minden ierr = MatView(A,0);CHKERRQ(ierr); 11196b375ea7SVictor Minden */ 1120918e98c3SVictor Minden #endif 11213a40ed3dSBarry Smith PetscFunctionReturn(0); 112217ab2063SBarry Smith } 112317ab2063SBarry Smith 112417ab2063SBarry Smith /* 112517ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 112617ab2063SBarry Smith */ 11274a2ae208SSatish Balay #undef __FUNCT__ 11284a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ" 1129dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 113017ab2063SBarry Smith { 1131416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11326849ba73SBarry Smith PetscErrorCode ierr; 1133d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 113417ab2063SBarry Smith 11353a40ed3dSBarry Smith PetscFunctionBegin; 113609f38230SBarry Smith if (!a->diag) { 113709f38230SBarry Smith ierr = PetscMalloc(m*sizeof(PetscInt),&a->diag);CHKERRQ(ierr); 11389518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(A, m*sizeof(PetscInt));CHKERRQ(ierr); 113909f38230SBarry Smith } 1140d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 114109f38230SBarry Smith a->diag[i] = a->i[i+1]; 1142bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1143bfeeae90SHong Zhang if (a->j[j] == i) { 114409f38230SBarry Smith a->diag[i] = j; 114517ab2063SBarry Smith break; 114617ab2063SBarry Smith } 114717ab2063SBarry Smith } 114817ab2063SBarry Smith } 11493a40ed3dSBarry Smith PetscFunctionReturn(0); 115017ab2063SBarry Smith } 115117ab2063SBarry Smith 1152be5855fcSBarry Smith /* 1153be5855fcSBarry Smith Checks for missing diagonals 1154be5855fcSBarry Smith */ 11554a2ae208SSatish Balay #undef __FUNCT__ 11564a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ" 1157ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1158be5855fcSBarry Smith { 1159be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 116097f1f81fSBarry Smith PetscInt *diag,*jj = a->j,i; 1161be5855fcSBarry Smith 1162be5855fcSBarry Smith PetscFunctionBegin; 116309f38230SBarry Smith *missing = PETSC_FALSE; 1164d0f46423SBarry Smith if (A->rmap->n > 0 && !jj) { 116509f38230SBarry Smith *missing = PETSC_TRUE; 116609f38230SBarry Smith if (d) *d = 0; 116709f38230SBarry Smith PetscInfo(A,"Matrix has no entries therefor is missing diagonal"); 116809f38230SBarry Smith } else { 1169f1e2ffcdSBarry Smith diag = a->diag; 1170d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 1171bfeeae90SHong Zhang if (jj[diag[i]] != i) { 117209f38230SBarry Smith *missing = PETSC_TRUE; 117309f38230SBarry Smith if (d) *d = i; 117409f38230SBarry Smith PetscInfo1(A,"Matrix is missing diagonal number %D",i); 117509f38230SBarry Smith } 1176be5855fcSBarry Smith } 1177be5855fcSBarry Smith } 1178be5855fcSBarry Smith PetscFunctionReturn(0); 1179be5855fcSBarry Smith } 1180be5855fcSBarry Smith 118171f1c65dSBarry Smith EXTERN_C_BEGIN 118271f1c65dSBarry Smith #undef __FUNCT__ 118371f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ" 11847087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 118571f1c65dSBarry Smith { 118671f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 118771f1c65dSBarry Smith PetscErrorCode ierr; 1188d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 118954f21887SBarry Smith MatScalar *v = a->a; 119054f21887SBarry Smith PetscScalar *idiag,*mdiag; 119171f1c65dSBarry Smith 119271f1c65dSBarry Smith PetscFunctionBegin; 119371f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 119471f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 119571f1c65dSBarry Smith diag = a->diag; 119671f1c65dSBarry Smith if (!a->idiag) { 119771f1c65dSBarry Smith ierr = PetscMalloc3(m,PetscScalar,&a->idiag,m,PetscScalar,&a->mdiag,m,PetscScalar,&a->ssor_work);CHKERRQ(ierr); 119871f1c65dSBarry Smith ierr = PetscLogObjectMemory(A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr); 119971f1c65dSBarry Smith v = a->a; 120071f1c65dSBarry Smith } 120171f1c65dSBarry Smith mdiag = a->mdiag; 120271f1c65dSBarry Smith idiag = a->idiag; 120371f1c65dSBarry Smith 1204028cd4eaSSatish Balay if (omega == 1.0 && !PetscAbsScalar(fshift)) { 120571f1c65dSBarry Smith for (i=0; i<m; i++) { 120671f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1207e32f2f54SBarry Smith if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 120871f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 120971f1c65dSBarry Smith } 121071f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 121171f1c65dSBarry Smith } else { 121271f1c65dSBarry Smith for (i=0; i<m; i++) { 121371f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 121471f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 121571f1c65dSBarry Smith } 1216dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 121771f1c65dSBarry Smith } 121871f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 121971f1c65dSBarry Smith PetscFunctionReturn(0); 122071f1c65dSBarry Smith } 12215a9745a3SMatthew Knepley EXTERN_C_END 122271f1c65dSBarry Smith 1223a4005a5dSBarry Smith #include "../src/mat/impls/aij/seq/ftn-kernels/frelax.h" 12244a2ae208SSatish Balay #undef __FUNCT__ 122541f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ" 122641f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 122717ab2063SBarry Smith { 1228416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1229e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 1230e6d1f457SBarry Smith const MatScalar *v = a->a,*idiag=0,*mdiag; 123154f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1232dfbe8321SBarry Smith PetscErrorCode ierr; 1233d0f46423SBarry Smith PetscInt n = A->cmap->n,m = A->rmap->n,i; 123497f1f81fSBarry Smith const PetscInt *idx,*diag; 123517ab2063SBarry Smith 12363a40ed3dSBarry Smith PetscFunctionBegin; 1237b965ef7fSBarry Smith its = its*lits; 123891723122SBarry Smith 123971f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 124071f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 124171f1c65dSBarry Smith a->fshift = fshift; 124271f1c65dSBarry Smith a->omega = omega; 1243ed480e8bSBarry Smith 124471f1c65dSBarry Smith diag = a->diag; 124571f1c65dSBarry Smith t = a->ssor_work; 1246ed480e8bSBarry Smith idiag = a->idiag; 124771f1c65dSBarry Smith mdiag = a->mdiag; 1248ed480e8bSBarry Smith 12491ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 12503649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 125171f1c65dSBarry Smith CHKMEMQ; 1252ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 125317ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 125417ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1255ed480e8bSBarry Smith bs = b; 125617ab2063SBarry Smith for (i=0; i<m; i++) { 125771f1c65dSBarry Smith d = fshift + mdiag[i]; 1258416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1259ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1260ed480e8bSBarry Smith v = a->a + diag[i] + 1; 126117ab2063SBarry Smith sum = b[i]*d/omega; 1262003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 126317ab2063SBarry Smith x[i] = sum; 126417ab2063SBarry Smith } 12651ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 12663649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1267efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 12683a40ed3dSBarry Smith PetscFunctionReturn(0); 126917ab2063SBarry Smith } 1270c783ea89SBarry Smith 127148af12d7SBarry Smith if (flag == SOR_APPLY_LOWER) { 1272e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 12733a40ed3dSBarry Smith } else if (flag & SOR_EISENSTAT) { 127417ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1275887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 127617ab2063SBarry Smith 127717ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 127817ab2063SBarry Smith 1279887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 128017ab2063SBarry Smith */ 128117ab2063SBarry Smith scale = (2.0/omega) - 1.0; 128217ab2063SBarry Smith 128317ab2063SBarry Smith /* x = (E + U)^{-1} b */ 128417ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1285416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1286ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1287ed480e8bSBarry Smith v = a->a + diag[i] + 1; 128817ab2063SBarry Smith sum = b[i]; 1289e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1290ed480e8bSBarry Smith x[i] = sum*idiag[i]; 129117ab2063SBarry Smith } 129217ab2063SBarry Smith 129317ab2063SBarry Smith /* t = b - (2*E - D)x */ 1294416022c9SBarry Smith v = a->a; 1295ed480e8bSBarry Smith for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; } 129617ab2063SBarry Smith 129717ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1298ed480e8bSBarry Smith ts = t; 1299416022c9SBarry Smith diag = a->diag; 130017ab2063SBarry Smith for (i=0; i<m; i++) { 1301416022c9SBarry Smith n = diag[i] - a->i[i]; 1302ed480e8bSBarry Smith idx = a->j + a->i[i]; 1303ed480e8bSBarry Smith v = a->a + a->i[i]; 130417ab2063SBarry Smith sum = t[i]; 1305003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 1306ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1307733d66baSBarry Smith /* x = x + t */ 1308733d66baSBarry Smith x[i] += t[i]; 130917ab2063SBarry Smith } 131017ab2063SBarry Smith 1311dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 13121ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 13133649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 13143a40ed3dSBarry Smith PetscFunctionReturn(0); 131517ab2063SBarry Smith } 131617ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 131717ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 131817ab2063SBarry Smith for (i=0; i<m; i++) { 1319416022c9SBarry Smith n = diag[i] - a->i[i]; 1320ed480e8bSBarry Smith idx = a->j + a->i[i]; 1321ed480e8bSBarry Smith v = a->a + a->i[i]; 132217ab2063SBarry Smith sum = b[i]; 1323e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 13245c99c7daSBarry Smith t[i] = sum; 1325ed480e8bSBarry Smith x[i] = sum*idiag[i]; 132617ab2063SBarry Smith } 13275c99c7daSBarry Smith xb = t; 1328efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 13293a40ed3dSBarry Smith } else xb = b; 133017ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 133117ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1332416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1333ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1334ed480e8bSBarry Smith v = a->a + diag[i] + 1; 133517ab2063SBarry Smith sum = xb[i]; 1336e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 13375c99c7daSBarry Smith if (xb == b) { 1338ed480e8bSBarry Smith x[i] = sum*idiag[i]; 13395c99c7daSBarry Smith } else { 13405c99c7daSBarry Smith x[i] = (1-omega)*x[i] + sum*idiag[i]; 134117ab2063SBarry Smith } 13425c99c7daSBarry Smith } 1343efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 134417ab2063SBarry Smith } 134517ab2063SBarry Smith its--; 134617ab2063SBarry Smith } 134717ab2063SBarry Smith while (its--) { 134817ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 134917ab2063SBarry Smith for (i=0; i<m; i++) { 1350416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1351ed480e8bSBarry Smith idx = a->j + a->i[i]; 1352ed480e8bSBarry Smith v = a->a + a->i[i]; 135317ab2063SBarry Smith sum = b[i]; 1354e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1355ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 135617ab2063SBarry Smith } 13579f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 135817ab2063SBarry Smith } 135917ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 136017ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1361416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1362ed480e8bSBarry Smith idx = a->j + a->i[i]; 1363ed480e8bSBarry Smith v = a->a + a->i[i]; 136417ab2063SBarry Smith sum = b[i]; 1365e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1366ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 136717ab2063SBarry Smith } 13689f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 136917ab2063SBarry Smith } 137017ab2063SBarry Smith } 13711ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 13723649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 137371f1c65dSBarry Smith CHKMEMQ; PetscFunctionReturn(0); 137417ab2063SBarry Smith } 137517ab2063SBarry Smith 13762af78befSBarry Smith 13774a2ae208SSatish Balay #undef __FUNCT__ 13784a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ" 1379dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 138017ab2063SBarry Smith { 1381416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 13824e220ebcSLois Curfman McInnes 13833a40ed3dSBarry Smith PetscFunctionBegin; 13844e220ebcSLois Curfman McInnes info->block_size = 1.0; 13854e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 13864e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 13874e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 13884e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 13898e58a170SBarry Smith info->mallocs = (double)A->info.mallocs; 13907adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 1391d5f3da31SBarry Smith if (A->factortype) { 13924e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 13934e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 13944e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 13954e220ebcSLois Curfman McInnes } else { 13964e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 13974e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 13984e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 13994e220ebcSLois Curfman McInnes } 14003a40ed3dSBarry Smith PetscFunctionReturn(0); 140117ab2063SBarry Smith } 140217ab2063SBarry Smith 14034a2ae208SSatish Balay #undef __FUNCT__ 14044a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ" 14052b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 140617ab2063SBarry Smith { 1407416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 14083b98c0a2SBarry Smith PetscInt i,m = A->rmap->n - 1,d = 0; 14096849ba73SBarry Smith PetscErrorCode ierr; 141097b48c8fSBarry Smith const PetscScalar *xx; 141197b48c8fSBarry Smith PetscScalar *bb; 1412ace3abfcSBarry Smith PetscBool missing; 141317ab2063SBarry Smith 14143a40ed3dSBarry Smith PetscFunctionBegin; 141597b48c8fSBarry Smith if (x && b) { 141697b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 141797b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 141897b48c8fSBarry Smith for (i=0; i<N; i++) { 141997b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 142097b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 142197b48c8fSBarry Smith } 142297b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 142397b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 142497b48c8fSBarry Smith } 142597b48c8fSBarry Smith 1426a9817697SBarry Smith if (a->keepnonzeropattern) { 1427f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1428e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1429bfeeae90SHong Zhang ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 1430f1e2ffcdSBarry Smith } 1431f4df32b1SMatthew Knepley if (diag != 0.0) { 143209f38230SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 1433e32f2f54SBarry Smith if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 1434f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1435f4df32b1SMatthew Knepley a->a[a->diag[rows[i]]] = diag; 1436f1e2ffcdSBarry Smith } 1437f1e2ffcdSBarry Smith } 143888e51ccdSHong Zhang A->same_nonzero = PETSC_TRUE; 1439f1e2ffcdSBarry Smith } else { 1440f4df32b1SMatthew Knepley if (diag != 0.0) { 144117ab2063SBarry Smith for (i=0; i<N; i++) { 1442e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 14437ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1444416022c9SBarry Smith a->ilen[rows[i]] = 1; 1445f4df32b1SMatthew Knepley a->a[a->i[rows[i]]] = diag; 1446bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 14477ae801bdSBarry Smith } else { /* in case row was completely empty */ 1448f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 144917ab2063SBarry Smith } 145017ab2063SBarry Smith } 14513a40ed3dSBarry Smith } else { 145217ab2063SBarry Smith for (i=0; i<N; i++) { 1453e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1454416022c9SBarry Smith a->ilen[rows[i]] = 0; 145517ab2063SBarry Smith } 145617ab2063SBarry Smith } 145788e51ccdSHong Zhang A->same_nonzero = PETSC_FALSE; 1458f1e2ffcdSBarry Smith } 145943a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14603a40ed3dSBarry Smith PetscFunctionReturn(0); 146117ab2063SBarry Smith } 146217ab2063SBarry Smith 14634a2ae208SSatish Balay #undef __FUNCT__ 14646e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ" 14656e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 14666e169961SBarry Smith { 14676e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 14686e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 14696e169961SBarry Smith PetscErrorCode ierr; 14702b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 14716e169961SBarry Smith const PetscScalar *xx; 14726e169961SBarry Smith PetscScalar *bb; 14736e169961SBarry Smith 14746e169961SBarry Smith PetscFunctionBegin; 14756e169961SBarry Smith if (x && b) { 14766e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 14776e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 14782b40b63fSBarry Smith vecs = PETSC_TRUE; 14796e169961SBarry Smith } 14806e169961SBarry Smith ierr = PetscMalloc(A->rmap->n*sizeof(PetscBool),&zeroed);CHKERRQ(ierr); 14816e169961SBarry Smith ierr = PetscMemzero(zeroed,A->rmap->n*sizeof(PetscBool));CHKERRQ(ierr); 14826e169961SBarry Smith for (i=0; i<N; i++) { 14836e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 14846e169961SBarry Smith ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 14856e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 14866e169961SBarry Smith } 14876e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 14886e169961SBarry Smith if (!zeroed[i]) { 14896e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 14906e169961SBarry Smith if (zeroed[a->j[j]]) { 14912b40b63fSBarry Smith if (vecs) bb[i] -= a->a[j]*xx[a->j[j]]; 14926e169961SBarry Smith a->a[j] = 0.0; 14936e169961SBarry Smith } 14946e169961SBarry Smith } 14952b40b63fSBarry Smith } else if (vecs) bb[i] = diag*xx[i]; 14966e169961SBarry Smith } 14976e169961SBarry Smith if (x && b) { 14986e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 14996e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 15006e169961SBarry Smith } 15016e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 15026e169961SBarry Smith if (diag != 0.0) { 15036e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 15046e169961SBarry Smith if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 15056e169961SBarry Smith for (i=0; i<N; i++) { 15066e169961SBarry Smith a->a[a->diag[rows[i]]] = diag; 15076e169961SBarry Smith } 15086e169961SBarry Smith } 15096e169961SBarry Smith A->same_nonzero = PETSC_TRUE; 15106e169961SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 15116e169961SBarry Smith PetscFunctionReturn(0); 15126e169961SBarry Smith } 15136e169961SBarry Smith 15146e169961SBarry Smith #undef __FUNCT__ 15154a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ" 1516a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 151717ab2063SBarry Smith { 1518416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 151997f1f81fSBarry Smith PetscInt *itmp; 152017ab2063SBarry Smith 15213a40ed3dSBarry Smith PetscFunctionBegin; 1522e32f2f54SBarry Smith if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 152317ab2063SBarry Smith 1524416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1525bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 152617ab2063SBarry Smith if (idx) { 1527bfeeae90SHong Zhang itmp = a->j + a->i[row]; 1528bfeeae90SHong Zhang if (*nz) { 15294e093b46SBarry Smith *idx = itmp; 153017ab2063SBarry Smith } 153117ab2063SBarry Smith else *idx = 0; 153217ab2063SBarry Smith } 15333a40ed3dSBarry Smith PetscFunctionReturn(0); 153417ab2063SBarry Smith } 153517ab2063SBarry Smith 1536bfeeae90SHong Zhang /* remove this function? */ 15374a2ae208SSatish Balay #undef __FUNCT__ 15384a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ" 1539a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 154017ab2063SBarry Smith { 15413a40ed3dSBarry Smith PetscFunctionBegin; 15423a40ed3dSBarry Smith PetscFunctionReturn(0); 154317ab2063SBarry Smith } 154417ab2063SBarry Smith 15454a2ae208SSatish Balay #undef __FUNCT__ 15464a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ" 1547dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 154817ab2063SBarry Smith { 1549416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 155054f21887SBarry Smith MatScalar *v = a->a; 155136db0b34SBarry Smith PetscReal sum = 0.0; 15526849ba73SBarry Smith PetscErrorCode ierr; 155397f1f81fSBarry Smith PetscInt i,j; 155417ab2063SBarry Smith 15553a40ed3dSBarry Smith PetscFunctionBegin; 155617ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1557416022c9SBarry Smith for (i=0; i<a->nz; i++) { 1558aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 155936db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 156017ab2063SBarry Smith #else 156117ab2063SBarry Smith sum += (*v)*(*v); v++; 156217ab2063SBarry Smith #endif 156317ab2063SBarry Smith } 1564064f8208SBarry Smith *nrm = sqrt(sum); 15653a40ed3dSBarry Smith } else if (type == NORM_1) { 156636db0b34SBarry Smith PetscReal *tmp; 156797f1f81fSBarry Smith PetscInt *jj = a->j; 1568d0f46423SBarry Smith ierr = PetscMalloc((A->cmap->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr); 1569d0f46423SBarry Smith ierr = PetscMemzero(tmp,A->cmap->n*sizeof(PetscReal));CHKERRQ(ierr); 1570064f8208SBarry Smith *nrm = 0.0; 1571416022c9SBarry Smith for (j=0; j<a->nz; j++) { 1572bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 157317ab2063SBarry Smith } 1574d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 1575064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 157617ab2063SBarry Smith } 1577606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 15783a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1579064f8208SBarry Smith *nrm = 0.0; 1580d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 1581bfeeae90SHong Zhang v = a->a + a->i[j]; 158217ab2063SBarry Smith sum = 0.0; 1583416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 1584cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 158517ab2063SBarry Smith } 1586064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 158717ab2063SBarry Smith } 15883a40ed3dSBarry Smith } else { 1589e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 159017ab2063SBarry Smith } 15913a40ed3dSBarry Smith PetscFunctionReturn(0); 159217ab2063SBarry Smith } 159317ab2063SBarry Smith 15944a2ae208SSatish Balay #undef __FUNCT__ 15954a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ" 1596fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B) 159717ab2063SBarry Smith { 1598416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1599416022c9SBarry Smith Mat C; 16006849ba73SBarry Smith PetscErrorCode ierr; 1601d0f46423SBarry Smith PetscInt i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col; 160254f21887SBarry Smith MatScalar *array = a->a; 160317ab2063SBarry Smith 16043a40ed3dSBarry Smith PetscFunctionBegin; 1605e32f2f54SBarry Smith if (reuse == MAT_REUSE_MATRIX && A == *B && m != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Square matrix only for in-place"); 1606fc4dec0aSBarry Smith 1607fc4dec0aSBarry Smith if (reuse == MAT_INITIAL_MATRIX || *B == A) { 1608d0f46423SBarry Smith ierr = PetscMalloc((1+A->cmap->n)*sizeof(PetscInt),&col);CHKERRQ(ierr); 1609d0f46423SBarry Smith ierr = PetscMemzero(col,(1+A->cmap->n)*sizeof(PetscInt));CHKERRQ(ierr); 1610bfeeae90SHong Zhang 1611bfeeae90SHong Zhang for (i=0; i<ai[m]; i++) col[aj[i]] += 1; 16127adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr); 1613d0f46423SBarry Smith ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr); 16147adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 1615ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr); 1616606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 1617a541d17aSBarry Smith } else { 1618a541d17aSBarry Smith C = *B; 1619a541d17aSBarry Smith } 1620a541d17aSBarry Smith 162117ab2063SBarry Smith for (i=0; i<m; i++) { 162217ab2063SBarry Smith len = ai[i+1]-ai[i]; 162387d4246cSBarry Smith ierr = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 1624b9b97703SBarry Smith array += len; 1625b9b97703SBarry Smith aj += len; 162617ab2063SBarry Smith } 16276d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16286d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 162917ab2063SBarry Smith 1630815cbec1SBarry Smith if (reuse == MAT_INITIAL_MATRIX || *B != A) { 1631416022c9SBarry Smith *B = C; 163217ab2063SBarry Smith } else { 1633eb6b5d47SBarry Smith ierr = MatHeaderMerge(A,C);CHKERRQ(ierr); 163417ab2063SBarry Smith } 16353a40ed3dSBarry Smith PetscFunctionReturn(0); 163617ab2063SBarry Smith } 163717ab2063SBarry Smith 1638cd0d46ebSvictorle EXTERN_C_BEGIN 1639cd0d46ebSvictorle #undef __FUNCT__ 16405fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ" 16417087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 1642cd0d46ebSvictorle { 1643cd0d46ebSvictorle Mat_SeqAIJ *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data; 164454f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 164554f21887SBarry Smith MatScalar *va,*vb; 16466849ba73SBarry Smith PetscErrorCode ierr; 164797f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 1648cd0d46ebSvictorle 1649cd0d46ebSvictorle PetscFunctionBegin; 1650cd0d46ebSvictorle bij = (Mat_SeqAIJ *) B->data; 1651cd0d46ebSvictorle 1652cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 1653cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 16545485867bSBarry Smith if (ma!=nb || na!=mb){ 16555485867bSBarry Smith *f = PETSC_FALSE; 16565485867bSBarry Smith PetscFunctionReturn(0); 16575485867bSBarry Smith } 1658cd0d46ebSvictorle aii = aij->i; bii = bij->i; 1659cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 1660cd0d46ebSvictorle va = aij->a; vb = bij->a; 166197f1f81fSBarry Smith ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr); 166297f1f81fSBarry Smith ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr); 1663cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 1664cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 1665cd0d46ebSvictorle 1666cd0d46ebSvictorle *f = PETSC_TRUE; 1667cd0d46ebSvictorle for (i=0; i<ma; i++) { 1668cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 166997f1f81fSBarry Smith PetscInt idc,idr; 16705485867bSBarry Smith PetscScalar vc,vr; 1671cd0d46ebSvictorle /* column/row index/value */ 16725485867bSBarry Smith idc = adx[aptr[i]]; 16735485867bSBarry Smith idr = bdx[bptr[idc]]; 16745485867bSBarry Smith vc = va[aptr[i]]; 16755485867bSBarry Smith vr = vb[bptr[idc]]; 16765485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 16775485867bSBarry Smith *f = PETSC_FALSE; 16785485867bSBarry Smith goto done; 1679cd0d46ebSvictorle } else { 16805485867bSBarry Smith aptr[i]++; 16815485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 1682cd0d46ebSvictorle } 1683cd0d46ebSvictorle } 1684cd0d46ebSvictorle } 1685cd0d46ebSvictorle done: 1686cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 16873aeef889SHong Zhang if (B) { 16883aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 16893aeef889SHong Zhang } 1690cd0d46ebSvictorle PetscFunctionReturn(0); 1691cd0d46ebSvictorle } 1692cd0d46ebSvictorle EXTERN_C_END 1693cd0d46ebSvictorle 16941cbb95d3SBarry Smith EXTERN_C_BEGIN 16951cbb95d3SBarry Smith #undef __FUNCT__ 16961cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ" 16977087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 16981cbb95d3SBarry Smith { 16991cbb95d3SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data; 170054f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 170154f21887SBarry Smith MatScalar *va,*vb; 17021cbb95d3SBarry Smith PetscErrorCode ierr; 17031cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 17041cbb95d3SBarry Smith 17051cbb95d3SBarry Smith PetscFunctionBegin; 17061cbb95d3SBarry Smith bij = (Mat_SeqAIJ *) B->data; 17071cbb95d3SBarry Smith 17081cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 17091cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 17101cbb95d3SBarry Smith if (ma!=nb || na!=mb){ 17111cbb95d3SBarry Smith *f = PETSC_FALSE; 17121cbb95d3SBarry Smith PetscFunctionReturn(0); 17131cbb95d3SBarry Smith } 17141cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 17151cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 17161cbb95d3SBarry Smith va = aij->a; vb = bij->a; 17171cbb95d3SBarry Smith ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr); 17181cbb95d3SBarry Smith ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr); 17191cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 17201cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 17211cbb95d3SBarry Smith 17221cbb95d3SBarry Smith *f = PETSC_TRUE; 17231cbb95d3SBarry Smith for (i=0; i<ma; i++) { 17241cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 17251cbb95d3SBarry Smith PetscInt idc,idr; 17261cbb95d3SBarry Smith PetscScalar vc,vr; 17271cbb95d3SBarry Smith /* column/row index/value */ 17281cbb95d3SBarry Smith idc = adx[aptr[i]]; 17291cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 17301cbb95d3SBarry Smith vc = va[aptr[i]]; 17311cbb95d3SBarry Smith vr = vb[bptr[idc]]; 17321cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 17331cbb95d3SBarry Smith *f = PETSC_FALSE; 17341cbb95d3SBarry Smith goto done; 17351cbb95d3SBarry Smith } else { 17361cbb95d3SBarry Smith aptr[i]++; 17371cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 17381cbb95d3SBarry Smith } 17391cbb95d3SBarry Smith } 17401cbb95d3SBarry Smith } 17411cbb95d3SBarry Smith done: 17421cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 17431cbb95d3SBarry Smith if (B) { 17441cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 17451cbb95d3SBarry Smith } 17461cbb95d3SBarry Smith PetscFunctionReturn(0); 17471cbb95d3SBarry Smith } 17481cbb95d3SBarry Smith EXTERN_C_END 17491cbb95d3SBarry Smith 17509e29f15eSvictorle #undef __FUNCT__ 17519e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ" 1752ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 17539e29f15eSvictorle { 1754dfbe8321SBarry Smith PetscErrorCode ierr; 17559e29f15eSvictorle PetscFunctionBegin; 17565485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 17579e29f15eSvictorle PetscFunctionReturn(0); 17589e29f15eSvictorle } 17599e29f15eSvictorle 17604a2ae208SSatish Balay #undef __FUNCT__ 17611cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ" 1762ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 17631cbb95d3SBarry Smith { 17641cbb95d3SBarry Smith PetscErrorCode ierr; 17651cbb95d3SBarry Smith PetscFunctionBegin; 17661cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 17671cbb95d3SBarry Smith PetscFunctionReturn(0); 17681cbb95d3SBarry Smith } 17691cbb95d3SBarry Smith 17701cbb95d3SBarry Smith #undef __FUNCT__ 17714a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ" 1772dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 177317ab2063SBarry Smith { 1774416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 177554f21887SBarry Smith PetscScalar *l,*r,x; 177654f21887SBarry Smith MatScalar *v; 1777dfbe8321SBarry Smith PetscErrorCode ierr; 1778d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj; 177917ab2063SBarry Smith 17803a40ed3dSBarry Smith PetscFunctionBegin; 178117ab2063SBarry Smith if (ll) { 17823ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 17833ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 1784e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 1785e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 17861ebc52fbSHong Zhang ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 1787416022c9SBarry Smith v = a->a; 178817ab2063SBarry Smith for (i=0; i<m; i++) { 178917ab2063SBarry Smith x = l[i]; 1790416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 179117ab2063SBarry Smith for (j=0; j<M; j++) { (*v++) *= x;} 179217ab2063SBarry Smith } 17931ebc52fbSHong Zhang ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 1794efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 179517ab2063SBarry Smith } 179617ab2063SBarry Smith if (rr) { 1797e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 1798e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 17991ebc52fbSHong Zhang ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 1800416022c9SBarry Smith v = a->a; jj = a->j; 180117ab2063SBarry Smith for (i=0; i<nz; i++) { 1802bfeeae90SHong Zhang (*v++) *= r[*jj++]; 180317ab2063SBarry Smith } 18041ebc52fbSHong Zhang ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 1805efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 180617ab2063SBarry Smith } 18073a40ed3dSBarry Smith PetscFunctionReturn(0); 180817ab2063SBarry Smith } 180917ab2063SBarry Smith 18104a2ae208SSatish Balay #undef __FUNCT__ 18114a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ" 181297f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 181317ab2063SBarry Smith { 1814db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 18156849ba73SBarry Smith PetscErrorCode ierr; 1816d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 181797f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 18185d0c19d7SBarry Smith const PetscInt *irow,*icol; 18195d0c19d7SBarry Smith PetscInt nrows,ncols; 182097f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 182154f21887SBarry Smith MatScalar *a_new,*mat_a; 1822416022c9SBarry Smith Mat C; 1823ace3abfcSBarry Smith PetscBool stride,sorted; 182417ab2063SBarry Smith 18253a40ed3dSBarry Smith PetscFunctionBegin; 182614ca34e6SBarry Smith ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr); 1827e32f2f54SBarry Smith if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted"); 182814ca34e6SBarry Smith ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr); 1829e32f2f54SBarry Smith if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted"); 183099141d43SSatish Balay 183117ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 1832b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 1833b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 183417ab2063SBarry Smith 1835fee21e36SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 18360dbe5b1eSSatish Balay ierr = PetscTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 1837fee21e36SBarry Smith if (stride && step == 1) { 183802834360SBarry Smith /* special case of contiguous rows */ 18390e83c824SBarry Smith ierr = PetscMalloc2(nrows,PetscInt,&lens,nrows,PetscInt,&starts);CHKERRQ(ierr); 184002834360SBarry Smith /* loop over new rows determining lens and starting points */ 184102834360SBarry Smith for (i=0; i<nrows; i++) { 1842bfeeae90SHong Zhang kstart = ai[irow[i]]; 1843a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 184402834360SBarry Smith for (k=kstart; k<kend; k++) { 1845bfeeae90SHong Zhang if (aj[k] >= first) { 184602834360SBarry Smith starts[i] = k; 184702834360SBarry Smith break; 184802834360SBarry Smith } 184902834360SBarry Smith } 1850a2744918SBarry Smith sum = 0; 185102834360SBarry Smith while (k < kend) { 1852bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 1853a2744918SBarry Smith sum++; 185402834360SBarry Smith } 1855a2744918SBarry Smith lens[i] = sum; 185602834360SBarry Smith } 185702834360SBarry Smith /* create submatrix */ 1858cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 185997f1f81fSBarry Smith PetscInt n_cols,n_rows; 186008480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 1861e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 1862d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 186308480c60SBarry Smith C = *B; 18643a40ed3dSBarry Smith } else { 18657adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr); 1866f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 18677adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 1868ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 186908480c60SBarry Smith } 1870db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 1871db02288aSLois Curfman McInnes 187202834360SBarry Smith /* loop over rows inserting into submatrix */ 1873db02288aSLois Curfman McInnes a_new = c->a; 1874db02288aSLois Curfman McInnes j_new = c->j; 1875db02288aSLois Curfman McInnes i_new = c->i; 1876bfeeae90SHong Zhang 187702834360SBarry Smith for (i=0; i<nrows; i++) { 1878a2744918SBarry Smith ii = starts[i]; 1879a2744918SBarry Smith lensi = lens[i]; 1880a2744918SBarry Smith for (k=0; k<lensi; k++) { 1881a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 188202834360SBarry Smith } 188387828ca2SBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr); 1884a2744918SBarry Smith a_new += lensi; 1885a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 1886a2744918SBarry Smith c->ilen[i] = lensi; 188702834360SBarry Smith } 18880e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 18893a40ed3dSBarry Smith } else { 189002834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 18910e83c824SBarry Smith ierr = PetscMalloc(oldcols*sizeof(PetscInt),&smap);CHKERRQ(ierr); 189297f1f81fSBarry Smith ierr = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr); 18930e83c824SBarry Smith ierr = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 189417ab2063SBarry Smith for (i=0; i<ncols; i++) smap[icol[i]] = i+1; 189502834360SBarry Smith /* determine lens of each row */ 189602834360SBarry Smith for (i=0; i<nrows; i++) { 1897bfeeae90SHong Zhang kstart = ai[irow[i]]; 189802834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 189902834360SBarry Smith lens[i] = 0; 190002834360SBarry Smith for (k=kstart; k<kend; k++) { 1901bfeeae90SHong Zhang if (smap[aj[k]]) { 190202834360SBarry Smith lens[i]++; 190302834360SBarry Smith } 190402834360SBarry Smith } 190502834360SBarry Smith } 190617ab2063SBarry Smith /* Create and fill new matrix */ 1907a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 1908ace3abfcSBarry Smith PetscBool equal; 19090f5bd95cSBarry Smith 191099141d43SSatish Balay c = (Mat_SeqAIJ *)((*B)->data); 1911e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 1912d0f46423SBarry Smith ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr); 19130f5bd95cSBarry Smith if (!equal) { 1914e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 191599141d43SSatish Balay } 1916d0f46423SBarry Smith ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 191708480c60SBarry Smith C = *B; 19183a40ed3dSBarry Smith } else { 19197adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr); 1920f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 19217adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 1922ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 192308480c60SBarry Smith } 192499141d43SSatish Balay c = (Mat_SeqAIJ *)(C->data); 192517ab2063SBarry Smith for (i=0; i<nrows; i++) { 192699141d43SSatish Balay row = irow[i]; 1927bfeeae90SHong Zhang kstart = ai[row]; 192899141d43SSatish Balay kend = kstart + a->ilen[row]; 1929bfeeae90SHong Zhang mat_i = c->i[i]; 193099141d43SSatish Balay mat_j = c->j + mat_i; 193199141d43SSatish Balay mat_a = c->a + mat_i; 193299141d43SSatish Balay mat_ilen = c->ilen + i; 193317ab2063SBarry Smith for (k=kstart; k<kend; k++) { 1934bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 1935ed480e8bSBarry Smith *mat_j++ = tcol - 1; 193699141d43SSatish Balay *mat_a++ = a->a[k]; 193799141d43SSatish Balay (*mat_ilen)++; 193899141d43SSatish Balay 193917ab2063SBarry Smith } 194017ab2063SBarry Smith } 194117ab2063SBarry Smith } 194202834360SBarry Smith /* Free work space */ 194302834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 1944606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 1945606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 194602834360SBarry Smith } 19476d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 19486d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 194917ab2063SBarry Smith 195017ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 1951416022c9SBarry Smith *B = C; 19523a40ed3dSBarry Smith PetscFunctionReturn(0); 195317ab2063SBarry Smith } 195417ab2063SBarry Smith 19551df811f5SHong Zhang #undef __FUNCT__ 195682d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ" 195782d44351SHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,Mat* subMat) 195882d44351SHong Zhang { 195982d44351SHong Zhang PetscErrorCode ierr; 196082d44351SHong Zhang Mat B; 196182d44351SHong Zhang 196282d44351SHong Zhang PetscFunctionBegin; 196382d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 196482d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 196582d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 196682d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 196782d44351SHong Zhang *subMat = B; 196882d44351SHong Zhang PetscFunctionReturn(0); 196982d44351SHong Zhang } 197082d44351SHong Zhang 197182d44351SHong Zhang #undef __FUNCT__ 19724a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ" 19730481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 1974a871dcd8SBarry Smith { 197563b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 1976dfbe8321SBarry Smith PetscErrorCode ierr; 197763b91edcSBarry Smith Mat outA; 1978ace3abfcSBarry Smith PetscBool row_identity,col_identity; 197963b91edcSBarry Smith 19803a40ed3dSBarry Smith PetscFunctionBegin; 1981e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 19821df811f5SHong Zhang 1983b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 1984b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 1985a871dcd8SBarry Smith 198663b91edcSBarry Smith outA = inA; 1987d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 1988c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1989c3122656SLisandro Dalcin if (a->row) { ierr = ISDestroy(a->row);CHKERRQ(ierr);} 1990c3122656SLisandro Dalcin a->row = row; 1991c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 1992c3122656SLisandro Dalcin if (a->col) { ierr = ISDestroy(a->col);CHKERRQ(ierr);} 1993c3122656SLisandro Dalcin a->col = col; 199463b91edcSBarry Smith 199536db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 1996b9b97703SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */ 19974c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 199852e6d16bSBarry Smith ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr); 1999f0ec6fceSSatish Balay 200094a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2001d0f46423SBarry Smith ierr = PetscMalloc((inA->rmap->n+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr); 2002d0f46423SBarry Smith ierr = PetscLogObjectMemory(inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 200394a9d846SBarry Smith } 200463b91edcSBarry Smith 2005f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2006137fb511SHong Zhang if (row_identity && col_identity) { 2007ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2008137fb511SHong Zhang } else { 2009719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2010137fb511SHong Zhang } 20113a40ed3dSBarry Smith PetscFunctionReturn(0); 2012a871dcd8SBarry Smith } 2013a871dcd8SBarry Smith 20144a2ae208SSatish Balay #undef __FUNCT__ 20154a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ" 2016f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2017f0b747eeSBarry Smith { 2018f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2019f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 2020efee365bSSatish Balay PetscErrorCode ierr; 20210805154bSBarry Smith PetscBLASInt one = 1,bnz = PetscBLASIntCast(a->nz); 20223a40ed3dSBarry Smith 20233a40ed3dSBarry Smith PetscFunctionBegin; 2024f4df32b1SMatthew Knepley BLASscal_(&bnz,&oalpha,a->a,&one); 2025efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 20263a40ed3dSBarry Smith PetscFunctionReturn(0); 2027f0b747eeSBarry Smith } 2028f0b747eeSBarry Smith 20294a2ae208SSatish Balay #undef __FUNCT__ 20304a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ" 203197f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2032cddf8d76SBarry Smith { 2033dfbe8321SBarry Smith PetscErrorCode ierr; 203497f1f81fSBarry Smith PetscInt i; 2035cddf8d76SBarry Smith 20363a40ed3dSBarry Smith PetscFunctionBegin; 2037cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2038b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr); 2039cddf8d76SBarry Smith } 2040cddf8d76SBarry Smith 2041cddf8d76SBarry Smith for (i=0; i<n; i++) { 20426a6a5d1dSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2043cddf8d76SBarry Smith } 20443a40ed3dSBarry Smith PetscFunctionReturn(0); 2045cddf8d76SBarry Smith } 2046cddf8d76SBarry Smith 20474a2ae208SSatish Balay #undef __FUNCT__ 20484a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ" 204997f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 20504dcbc457SBarry Smith { 2051e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 20526849ba73SBarry Smith PetscErrorCode ierr; 20535d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 20545d0c19d7SBarry Smith const PetscInt *idx; 205597f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2056f1af5d2fSBarry Smith PetscBT table; 2057bbd702dbSSatish Balay 20583a40ed3dSBarry Smith PetscFunctionBegin; 2059d0f46423SBarry Smith m = A->rmap->n; 2060e4d965acSSatish Balay ai = a->i; 2061bfeeae90SHong Zhang aj = a->j; 20628a047759SSatish Balay 2063e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 206406763907SSatish Balay 206597f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr); 20666831982aSBarry Smith ierr = PetscBTCreate(m,table);CHKERRQ(ierr); 206706763907SSatish Balay 2068e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2069b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2070e4d965acSSatish Balay isz = 0; 20716831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 2072e4d965acSSatish Balay 2073e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 20744dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 2075b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 2076e4d965acSSatish Balay 2077dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2078e4d965acSSatish Balay for (j=0; j<n ; ++j){ 2079f1af5d2fSBarry Smith if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];} 20804dcbc457SBarry Smith } 208106763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 208206763907SSatish Balay ierr = ISDestroy(is[i]);CHKERRQ(ierr); 2083e4d965acSSatish Balay 208404a348a9SBarry Smith k = 0; 208504a348a9SBarry Smith for (j=0; j<ov; j++){ /* for each overlap */ 208604a348a9SBarry Smith n = isz; 208706763907SSatish Balay for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */ 2088e4d965acSSatish Balay row = nidx[k]; 2089e4d965acSSatish Balay start = ai[row]; 2090e4d965acSSatish Balay end = ai[row+1]; 209104a348a9SBarry Smith for (l = start; l<end ; l++){ 2092efb16452SHong Zhang val = aj[l] ; 2093f1af5d2fSBarry Smith if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;} 2094e4d965acSSatish Balay } 2095e4d965acSSatish Balay } 2096e4d965acSSatish Balay } 209770b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 2098e4d965acSSatish Balay } 20996831982aSBarry Smith ierr = PetscBTDestroy(table);CHKERRQ(ierr); 2100606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 21013a40ed3dSBarry Smith PetscFunctionReturn(0); 21024dcbc457SBarry Smith } 210317ab2063SBarry Smith 21040513a670SBarry Smith /* -------------------------------------------------------------- */ 21054a2ae208SSatish Balay #undef __FUNCT__ 21064a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ" 2107dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 21080513a670SBarry Smith { 21090513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 21106849ba73SBarry Smith PetscErrorCode ierr; 21113b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 21125d0c19d7SBarry Smith const PetscInt *row,*col; 21135d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 211456cd22aeSBarry Smith IS icolp,irowp; 21153b98c0a2SBarry Smith PetscInt *cwork = PETSC_NULL; 21163b98c0a2SBarry Smith PetscScalar *vwork = PETSC_NULL; 21170513a670SBarry Smith 21183a40ed3dSBarry Smith PetscFunctionBegin; 21194c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 212056cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 21214c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 212256cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 21230513a670SBarry Smith 21240513a670SBarry Smith /* determine lengths of permuted rows */ 212597f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 21260513a670SBarry Smith for (i=0; i<m; i++) { 21270513a670SBarry Smith lens[row[i]] = a->i[i+1] - a->i[i]; 21280513a670SBarry Smith } 21297adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr); 2130f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 21317adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2132ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 2133606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 21340513a670SBarry Smith 213597f1f81fSBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr); 21360513a670SBarry Smith for (i=0; i<m; i++) { 213732ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 21380513a670SBarry Smith for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];} 2139cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 214032ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 21410513a670SBarry Smith } 2142606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 21433c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 21440513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 21450513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 214656cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 214756cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 214856cd22aeSBarry Smith ierr = ISDestroy(irowp);CHKERRQ(ierr); 214956cd22aeSBarry Smith ierr = ISDestroy(icolp);CHKERRQ(ierr); 21503a40ed3dSBarry Smith PetscFunctionReturn(0); 21510513a670SBarry Smith } 21520513a670SBarry Smith 21534a2ae208SSatish Balay #undef __FUNCT__ 21544a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ" 2155dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 2156cb5b572fSBarry Smith { 2157dfbe8321SBarry Smith PetscErrorCode ierr; 2158cb5b572fSBarry Smith 2159cb5b572fSBarry Smith PetscFunctionBegin; 216033f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 216133f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 2162be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2163be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 2164be6bf707SBarry Smith 2165700c5bfcSBarry Smith if (a->i[A->rmap->n] != b->i[B->rmap->n]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of nonzeros in two matrices are different"); 2166d0f46423SBarry Smith ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 2167cb5b572fSBarry Smith } else { 2168cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 2169cb5b572fSBarry Smith } 2170cb5b572fSBarry Smith PetscFunctionReturn(0); 2171cb5b572fSBarry Smith } 2172cb5b572fSBarry Smith 21734a2ae208SSatish Balay #undef __FUNCT__ 21744a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ" 2175dfbe8321SBarry Smith PetscErrorCode MatSetUpPreallocation_SeqAIJ(Mat A) 2176273d9f13SBarry Smith { 2177dfbe8321SBarry Smith PetscErrorCode ierr; 2178273d9f13SBarry Smith 2179273d9f13SBarry Smith PetscFunctionBegin; 2180ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 2181273d9f13SBarry Smith PetscFunctionReturn(0); 2182273d9f13SBarry Smith } 2183273d9f13SBarry Smith 21844a2ae208SSatish Balay #undef __FUNCT__ 21854a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ" 2186a77337e4SBarry Smith PetscErrorCode MatGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 21876c0721eeSBarry Smith { 21886c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 21896c0721eeSBarry Smith PetscFunctionBegin; 21906c0721eeSBarry Smith *array = a->a; 21916c0721eeSBarry Smith PetscFunctionReturn(0); 21926c0721eeSBarry Smith } 21936c0721eeSBarry Smith 21944a2ae208SSatish Balay #undef __FUNCT__ 21954a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ" 2196dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 21976c0721eeSBarry Smith { 21986c0721eeSBarry Smith PetscFunctionBegin; 21996c0721eeSBarry Smith PetscFunctionReturn(0); 22006c0721eeSBarry Smith } 2201273d9f13SBarry Smith 2202ee4f033dSBarry Smith #undef __FUNCT__ 2203ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ" 2204dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 2205ee4f033dSBarry Smith { 22066849ba73SBarry Smith PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f; 22076849ba73SBarry Smith PetscErrorCode ierr; 220897f1f81fSBarry Smith PetscInt k,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2; 2209efb30889SBarry Smith PetscScalar dx,*y,*xx,*w3_array; 221087828ca2SBarry Smith PetscScalar *vscale_array; 2211ee4f033dSBarry Smith PetscReal epsilon = coloring->error_rel,umin = coloring->umin; 2212ee4f033dSBarry Smith Vec w1,w2,w3; 2213ee4f033dSBarry Smith void *fctx = coloring->fctx; 2214ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 2215ee4f033dSBarry Smith 2216ee4f033dSBarry Smith PetscFunctionBegin; 2217ee4f033dSBarry Smith if (!coloring->w1) { 2218ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr); 221952e6d16bSBarry Smith ierr = PetscLogObjectParent(coloring,coloring->w1);CHKERRQ(ierr); 2220ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr); 222152e6d16bSBarry Smith ierr = PetscLogObjectParent(coloring,coloring->w2);CHKERRQ(ierr); 2222ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr); 222352e6d16bSBarry Smith ierr = PetscLogObjectParent(coloring,coloring->w3);CHKERRQ(ierr); 2224ee4f033dSBarry Smith } 2225ee4f033dSBarry Smith w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3; 2226ee4f033dSBarry Smith 2227ee4f033dSBarry Smith ierr = MatSetUnfactored(J);CHKERRQ(ierr); 2228acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)coloring)->prefix,"-mat_fd_coloring_dont_rezero",&flg,PETSC_NULL);CHKERRQ(ierr); 2229ee4f033dSBarry Smith if (flg) { 2230ae15b995SBarry Smith ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr); 2231ee4f033dSBarry Smith } else { 2232ace3abfcSBarry Smith PetscBool assembled; 22330b9b6f31SBarry Smith ierr = MatAssembled(J,&assembled);CHKERRQ(ierr); 22340b9b6f31SBarry Smith if (assembled) { 2235ee4f033dSBarry Smith ierr = MatZeroEntries(J);CHKERRQ(ierr); 2236ee4f033dSBarry Smith } 22370b9b6f31SBarry Smith } 2238ee4f033dSBarry Smith 2239ee4f033dSBarry Smith ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr); 2240ee4f033dSBarry Smith ierr = VecGetSize(x1,&N);CHKERRQ(ierr); 2241ee4f033dSBarry Smith 2242ee4f033dSBarry Smith /* 2243ee4f033dSBarry Smith This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets 2244ee4f033dSBarry Smith coloring->F for the coarser grids from the finest 2245ee4f033dSBarry Smith */ 2246ee4f033dSBarry Smith if (coloring->F) { 2247ee4f033dSBarry Smith ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr); 2248ee4f033dSBarry Smith ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr); 2249ee4f033dSBarry Smith if (m1 != m2) { 2250ee4f033dSBarry Smith coloring->F = 0; 2251ee4f033dSBarry Smith } 2252ee4f033dSBarry Smith } 2253ee4f033dSBarry Smith 2254ee4f033dSBarry Smith if (coloring->F) { 2255ee4f033dSBarry Smith w1 = coloring->F; 2256ee4f033dSBarry Smith coloring->F = 0; 2257ee4f033dSBarry Smith } else { 225866f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2259ee4f033dSBarry Smith ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr); 226066f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2261ee4f033dSBarry Smith } 2262ee4f033dSBarry Smith 2263ee4f033dSBarry Smith /* 2264ee4f033dSBarry Smith Compute all the scale factors and share with other processors 2265ee4f033dSBarry Smith */ 22661ebc52fbSHong Zhang ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start; 22671ebc52fbSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start; 2268ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 2269ee4f033dSBarry Smith /* 2270ee4f033dSBarry Smith Loop over each column associated with color adding the 2271ee4f033dSBarry Smith perturbation to the vector w3. 2272ee4f033dSBarry Smith */ 2273ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 2274ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 2275ee4f033dSBarry Smith dx = xx[col]; 2276ee4f033dSBarry Smith if (dx == 0.0) dx = 1.0; 2277ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 2278ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 2279ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 2280ee4f033dSBarry Smith #else 2281ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2282ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2283ee4f033dSBarry Smith #endif 2284ee4f033dSBarry Smith dx *= epsilon; 2285ee4f033dSBarry Smith vscale_array[col] = 1.0/dx; 2286ee4f033dSBarry Smith } 2287ee4f033dSBarry Smith } 22881ebc52fbSHong Zhang vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2289ee4f033dSBarry Smith ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2290ee4f033dSBarry Smith ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2291ee4f033dSBarry Smith 2292ee4f033dSBarry Smith /* ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD); 2293ee4f033dSBarry Smith ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/ 2294ee4f033dSBarry Smith 2295ee4f033dSBarry Smith if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow; 2296ee4f033dSBarry Smith else vscaleforrow = coloring->columnsforrow; 2297ee4f033dSBarry Smith 22981ebc52fbSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2299ee4f033dSBarry Smith /* 2300ee4f033dSBarry Smith Loop over each color 2301ee4f033dSBarry Smith */ 2302ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 230349b058dcSBarry Smith coloring->currentcolor = k; 2304ee4f033dSBarry Smith ierr = VecCopy(x1,w3);CHKERRQ(ierr); 23051ebc52fbSHong Zhang ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start; 2306ee4f033dSBarry Smith /* 2307ee4f033dSBarry Smith Loop over each column associated with color adding the 2308ee4f033dSBarry Smith perturbation to the vector w3. 2309ee4f033dSBarry Smith */ 2310ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 2311ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 2312ee4f033dSBarry Smith dx = xx[col]; 23135b8514ebSBarry Smith if (dx == 0.0) dx = 1.0; 2314ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 2315ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 2316ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 2317ee4f033dSBarry Smith #else 2318ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2319ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2320ee4f033dSBarry Smith #endif 2321ee4f033dSBarry Smith dx *= epsilon; 2322e32f2f54SBarry Smith if (!PetscAbsScalar(dx)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Computed 0 differencing parameter"); 2323ee4f033dSBarry Smith w3_array[col] += dx; 2324ee4f033dSBarry Smith } 23251ebc52fbSHong Zhang w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr); 2326ee4f033dSBarry Smith 2327ee4f033dSBarry Smith /* 2328ee4f033dSBarry Smith Evaluate function at x1 + dx (here dx is a vector of perturbations) 2329ee4f033dSBarry Smith */ 2330ee4f033dSBarry Smith 233166f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2332ee4f033dSBarry Smith ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr); 233366f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2334efb30889SBarry Smith ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr); 2335ee4f033dSBarry Smith 2336ee4f033dSBarry Smith /* 2337ee4f033dSBarry Smith Loop over rows of vector, putting results into Jacobian matrix 2338ee4f033dSBarry Smith */ 23391ebc52fbSHong Zhang ierr = VecGetArray(w2,&y);CHKERRQ(ierr); 2340ee4f033dSBarry Smith for (l=0; l<coloring->nrows[k]; l++) { 2341ee4f033dSBarry Smith row = coloring->rows[k][l]; 2342ee4f033dSBarry Smith col = coloring->columnsforrow[k][l]; 2343ee4f033dSBarry Smith y[row] *= vscale_array[vscaleforrow[k][l]]; 2344ee4f033dSBarry Smith srow = row + start; 2345ee4f033dSBarry Smith ierr = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr); 2346ee4f033dSBarry Smith } 23471ebc52fbSHong Zhang ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr); 2348ee4f033dSBarry Smith } 234949b058dcSBarry Smith coloring->currentcolor = k; 23501ebc52fbSHong Zhang ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 23511ebc52fbSHong Zhang xx = xx + start; ierr = VecRestoreArray(x1,&xx);CHKERRQ(ierr); 2352ee4f033dSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2353ee4f033dSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2354ee4f033dSBarry Smith PetscFunctionReturn(0); 2355ee4f033dSBarry Smith } 2356ee4f033dSBarry Smith 23578229c054SShri Abhyankar /* 23588229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 23598229c054SShri Abhyankar have different nonzero structure. 23608229c054SShri Abhyankar */ 2361ac90fabeSBarry Smith #undef __FUNCT__ 23628229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ" 23638229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt* nnz) 2364ec7775f6SShri Abhyankar { 23658229c054SShri Abhyankar PetscInt i,m=Y->rmap->N; 2366ec7775f6SShri Abhyankar Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 2367ec7775f6SShri Abhyankar Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 2368ec7775f6SShri Abhyankar const PetscInt *xi = x->i,*yi = y->i; 2369ec7775f6SShri Abhyankar 2370ec7775f6SShri Abhyankar PetscFunctionBegin; 2371ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 2372ec7775f6SShri Abhyankar for(i=0; i<m; i++) { 23738af7cee1SJed Brown PetscInt j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i]; 23748af7cee1SJed Brown const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i]; 23758af7cee1SJed Brown nnz[i] = 0; 23768af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 23778af7cee1SJed Brown for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */ 23788af7cee1SJed Brown if (k<nzy && yj[k]==xj[j]) k++; /* Skip duplicate */ 23798af7cee1SJed Brown nnz[i]++; 23808af7cee1SJed Brown } 23818af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 2382ec7775f6SShri Abhyankar } 2383ec7775f6SShri Abhyankar PetscFunctionReturn(0); 2384ec7775f6SShri Abhyankar } 2385ec7775f6SShri Abhyankar 2386ec7775f6SShri Abhyankar #undef __FUNCT__ 2387ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ" 2388f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 2389ac90fabeSBarry Smith { 2390dfbe8321SBarry Smith PetscErrorCode ierr; 239197f1f81fSBarry Smith PetscInt i; 2392ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data; 23930805154bSBarry Smith PetscBLASInt one=1,bnz = PetscBLASIntCast(x->nz); 2394ac90fabeSBarry Smith 2395ac90fabeSBarry Smith PetscFunctionBegin; 2396ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 2397f4df32b1SMatthew Knepley PetscScalar alpha = a; 2398f4df32b1SMatthew Knepley BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one); 2399c537a176SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 2400a30b2313SHong Zhang if (y->xtoy && y->XtoY != X) { 2401a30b2313SHong Zhang ierr = PetscFree(y->xtoy);CHKERRQ(ierr); 2402a30b2313SHong Zhang ierr = MatDestroy(y->XtoY);CHKERRQ(ierr); 2403a30b2313SHong Zhang } 2404a30b2313SHong Zhang if (!y->xtoy) { /* get xtoy */ 2405d0f46423SBarry Smith ierr = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr); 2406a30b2313SHong Zhang y->XtoY = X; 2407407f6b05SHong Zhang ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 2408c537a176SHong Zhang } 2409f4df32b1SMatthew Knepley for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]); 24101e2582c4SBarry Smith ierr = PetscInfo3(Y,"ratio of nnz(X)/nnz(Y): %d/%d = %G\n",x->nz,y->nz,(PetscReal)(x->nz)/y->nz);CHKERRQ(ierr); 2411ac90fabeSBarry Smith } else { 24128229c054SShri Abhyankar Mat B; 24138229c054SShri Abhyankar PetscInt *nnz; 241416b2e9dcSShri Abhyankar ierr = PetscMalloc(Y->rmap->N*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 2415ec7775f6SShri Abhyankar ierr = MatCreate(((PetscObject)Y)->comm,&B);CHKERRQ(ierr); 2416bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 24174aa94f47SShri Abhyankar ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr); 2418ec7775f6SShri Abhyankar ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 24198229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 24208229c054SShri Abhyankar ierr = MatSeqAIJSetPreallocation(B,PETSC_NULL,nnz);CHKERRQ(ierr); 2421ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 2422ec7775f6SShri Abhyankar ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr); 24238229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 2424ac90fabeSBarry Smith } 2425ac90fabeSBarry Smith PetscFunctionReturn(0); 2426ac90fabeSBarry Smith } 2427ac90fabeSBarry Smith 2428521d7252SBarry Smith #undef __FUNCT__ 2429521d7252SBarry Smith #define __FUNCT__ "MatSetBlockSize_SeqAIJ" 2430521d7252SBarry Smith PetscErrorCode MatSetBlockSize_SeqAIJ(Mat A,PetscInt bs) 2431521d7252SBarry Smith { 243241c166b1SJed Brown PetscErrorCode ierr; 243341c166b1SJed Brown 2434521d7252SBarry Smith PetscFunctionBegin; 243541c166b1SJed Brown ierr = PetscLayoutSetBlockSize(A->rmap,bs);CHKERRQ(ierr); 243641c166b1SJed Brown ierr = PetscLayoutSetBlockSize(A->cmap,bs);CHKERRQ(ierr); 2437521d7252SBarry Smith PetscFunctionReturn(0); 2438521d7252SBarry Smith } 2439521d7252SBarry Smith 2440354c94deSBarry Smith #undef __FUNCT__ 2441354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ" 24427087cfbeSBarry Smith PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 2443354c94deSBarry Smith { 2444354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 2445354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2446354c94deSBarry Smith PetscInt i,nz; 2447354c94deSBarry Smith PetscScalar *a; 2448354c94deSBarry Smith 2449354c94deSBarry Smith PetscFunctionBegin; 2450354c94deSBarry Smith nz = aij->nz; 2451354c94deSBarry Smith a = aij->a; 2452354c94deSBarry Smith for (i=0; i<nz; i++) { 2453354c94deSBarry Smith a[i] = PetscConj(a[i]); 2454354c94deSBarry Smith } 2455354c94deSBarry Smith #else 2456354c94deSBarry Smith PetscFunctionBegin; 2457354c94deSBarry Smith #endif 2458354c94deSBarry Smith PetscFunctionReturn(0); 2459354c94deSBarry Smith } 2460354c94deSBarry Smith 2461e34fafa9SBarry Smith #undef __FUNCT__ 2462985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ" 2463985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2464e34fafa9SBarry Smith { 2465e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2466e34fafa9SBarry Smith PetscErrorCode ierr; 2467d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2468e34fafa9SBarry Smith PetscReal atmp; 2469985db425SBarry Smith PetscScalar *x; 2470e34fafa9SBarry Smith MatScalar *aa; 2471e34fafa9SBarry Smith 2472e34fafa9SBarry Smith PetscFunctionBegin; 2473e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2474e34fafa9SBarry Smith aa = a->a; 2475e34fafa9SBarry Smith ai = a->i; 2476e34fafa9SBarry Smith aj = a->j; 2477e34fafa9SBarry Smith 2478985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2479e34fafa9SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2480e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2481e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2482e34fafa9SBarry Smith for (i=0; i<m; i++) { 2483e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 24849189402eSHong Zhang x[i] = 0.0; 2485e34fafa9SBarry Smith for (j=0; j<ncols; j++){ 2486985db425SBarry Smith atmp = PetscAbsScalar(*aa); 2487985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2488985db425SBarry Smith aa++; aj++; 2489985db425SBarry Smith } 2490985db425SBarry Smith } 2491985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2492985db425SBarry Smith PetscFunctionReturn(0); 2493985db425SBarry Smith } 2494985db425SBarry Smith 2495985db425SBarry Smith #undef __FUNCT__ 2496985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ" 2497985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2498985db425SBarry Smith { 2499985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2500985db425SBarry Smith PetscErrorCode ierr; 2501d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2502985db425SBarry Smith PetscScalar *x; 2503985db425SBarry Smith MatScalar *aa; 2504985db425SBarry Smith 2505985db425SBarry Smith PetscFunctionBegin; 2506e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2507985db425SBarry Smith aa = a->a; 2508985db425SBarry Smith ai = a->i; 2509985db425SBarry Smith aj = a->j; 2510985db425SBarry Smith 2511985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2512985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2513985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2514e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2515985db425SBarry Smith for (i=0; i<m; i++) { 2516985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 2517d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 2518985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 2519985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 2520985db425SBarry Smith x[i] = 0.0; 2521985db425SBarry Smith if (idx) { 2522985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2523985db425SBarry Smith for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */ 2524985db425SBarry Smith if (aj[j] > j) { 2525985db425SBarry Smith idx[i] = j; 2526985db425SBarry Smith break; 2527985db425SBarry Smith } 2528985db425SBarry Smith } 2529985db425SBarry Smith } 2530985db425SBarry Smith } 2531985db425SBarry Smith for (j=0; j<ncols; j++){ 2532985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 2533985db425SBarry Smith aa++; aj++; 2534985db425SBarry Smith } 2535985db425SBarry Smith } 2536985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2537985db425SBarry Smith PetscFunctionReturn(0); 2538985db425SBarry Smith } 2539985db425SBarry Smith 2540985db425SBarry Smith #undef __FUNCT__ 2541c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ" 2542c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2543c87e5d42SMatthew Knepley { 2544c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2545c87e5d42SMatthew Knepley PetscErrorCode ierr; 2546c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2547c87e5d42SMatthew Knepley PetscReal atmp; 2548c87e5d42SMatthew Knepley PetscScalar *x; 2549c87e5d42SMatthew Knepley MatScalar *aa; 2550c87e5d42SMatthew Knepley 2551c87e5d42SMatthew Knepley PetscFunctionBegin; 2552e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2553c87e5d42SMatthew Knepley aa = a->a; 2554c87e5d42SMatthew Knepley ai = a->i; 2555c87e5d42SMatthew Knepley aj = a->j; 2556c87e5d42SMatthew Knepley 2557c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 2558c87e5d42SMatthew Knepley ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2559c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2560e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2561c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 2562c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 2563289a08f5SMatthew Knepley if (ncols) { 2564289a08f5SMatthew Knepley /* Get first nonzero */ 2565289a08f5SMatthew Knepley for(j = 0; j < ncols; j++) { 2566289a08f5SMatthew Knepley atmp = PetscAbsScalar(aa[j]); 2567289a08f5SMatthew Knepley if (atmp > 1.0e-12) {x[i] = atmp; if (idx) idx[i] = aj[j]; break;} 2568289a08f5SMatthew Knepley } 2569289a08f5SMatthew Knepley if (j == ncols) {x[i] = *aa; if (idx) idx[i] = *aj;} 2570289a08f5SMatthew Knepley } else { 2571289a08f5SMatthew Knepley x[i] = 0.0; if (idx) idx[i] = 0; 2572289a08f5SMatthew Knepley } 2573c87e5d42SMatthew Knepley for(j = 0; j < ncols; j++) { 2574c87e5d42SMatthew Knepley atmp = PetscAbsScalar(*aa); 2575289a08f5SMatthew Knepley if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2576c87e5d42SMatthew Knepley aa++; aj++; 2577c87e5d42SMatthew Knepley } 2578c87e5d42SMatthew Knepley } 2579c87e5d42SMatthew Knepley ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2580c87e5d42SMatthew Knepley PetscFunctionReturn(0); 2581c87e5d42SMatthew Knepley } 2582c87e5d42SMatthew Knepley 2583c87e5d42SMatthew Knepley #undef __FUNCT__ 2584985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ" 2585985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2586985db425SBarry Smith { 2587985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2588985db425SBarry Smith PetscErrorCode ierr; 2589d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2590985db425SBarry Smith PetscScalar *x; 2591985db425SBarry Smith MatScalar *aa; 2592985db425SBarry Smith 2593985db425SBarry Smith PetscFunctionBegin; 2594e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2595985db425SBarry Smith aa = a->a; 2596985db425SBarry Smith ai = a->i; 2597985db425SBarry Smith aj = a->j; 2598985db425SBarry Smith 2599985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2600985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2601985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2602e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2603985db425SBarry Smith for (i=0; i<m; i++) { 2604985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 2605d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 2606985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 2607985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 2608985db425SBarry Smith x[i] = 0.0; 2609985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 2610985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2611985db425SBarry Smith for (j=0;j<ncols;j++) { 2612985db425SBarry Smith if (aj[j] > j) { 2613985db425SBarry Smith idx[i] = j; 2614985db425SBarry Smith break; 2615985db425SBarry Smith } 2616985db425SBarry Smith } 2617985db425SBarry Smith } 2618985db425SBarry Smith } 2619985db425SBarry Smith for (j=0; j<ncols; j++){ 2620985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 2621985db425SBarry Smith aa++; aj++; 2622e34fafa9SBarry Smith } 2623e34fafa9SBarry Smith } 2624e34fafa9SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2625e34fafa9SBarry Smith PetscFunctionReturn(0); 2626e34fafa9SBarry Smith } 26277087cfbeSBarry Smith extern PetscErrorCode MatFDColoringApply_AIJ(Mat,MatFDColoring,Vec,MatStructure*,void*); 2628682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 26290a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ, 2630cb5b572fSBarry Smith MatGetRow_SeqAIJ, 2631cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 2632cb5b572fSBarry Smith MatMult_SeqAIJ, 263397304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 26347c922b88SBarry Smith MatMultTranspose_SeqAIJ, 26357c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 2636db4efbfdSBarry Smith 0, 2637db4efbfdSBarry Smith 0, 2638db4efbfdSBarry Smith 0, 2639db4efbfdSBarry Smith /*10*/ 0, 2640cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 2641cb5b572fSBarry Smith 0, 264241f059aeSBarry Smith MatSOR_SeqAIJ, 264317ab2063SBarry Smith MatTranspose_SeqAIJ, 264497304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ, 2645cb5b572fSBarry Smith MatEqual_SeqAIJ, 2646cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 2647cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 2648cb5b572fSBarry Smith MatNorm_SeqAIJ, 264997304618SKris Buschelman /*20*/ 0, 2650cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 2651cb5b572fSBarry Smith MatSetOption_SeqAIJ, 2652cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 2653d519adbfSMatthew Knepley /*24*/ MatZeroRows_SeqAIJ, 2654db4efbfdSBarry Smith 0, 2655db4efbfdSBarry Smith 0, 2656db4efbfdSBarry Smith 0, 2657db4efbfdSBarry Smith 0, 2658d519adbfSMatthew Knepley /*29*/ MatSetUpPreallocation_SeqAIJ, 2659db4efbfdSBarry Smith 0, 2660db4efbfdSBarry Smith 0, 26616c0721eeSBarry Smith MatGetArray_SeqAIJ, 26626c0721eeSBarry Smith MatRestoreArray_SeqAIJ, 2663d519adbfSMatthew Knepley /*34*/ MatDuplicate_SeqAIJ, 2664cb5b572fSBarry Smith 0, 2665cb5b572fSBarry Smith 0, 2666cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 2667cb5b572fSBarry Smith 0, 2668d519adbfSMatthew Knepley /*39*/ MatAXPY_SeqAIJ, 2669cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 2670cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 2671cb5b572fSBarry Smith MatGetValues_SeqAIJ, 2672cb5b572fSBarry Smith MatCopy_SeqAIJ, 2673d519adbfSMatthew Knepley /*44*/ MatGetRowMax_SeqAIJ, 2674cb5b572fSBarry Smith MatScale_SeqAIJ, 2675cb5b572fSBarry Smith 0, 267679299369SBarry Smith MatDiagonalSet_SeqAIJ, 26776e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 2678d519adbfSMatthew Knepley /*49*/ MatSetBlockSize_SeqAIJ, 26793b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 26803b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 26813b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 2682a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 2683d519adbfSMatthew Knepley /*54*/ MatFDColoringCreate_SeqAIJ, 2684b9617806SBarry Smith 0, 26850513a670SBarry Smith 0, 2686cda55fadSBarry Smith MatPermute_SeqAIJ, 2687cda55fadSBarry Smith 0, 2688d519adbfSMatthew Knepley /*59*/ 0, 2689b9b97703SBarry Smith MatDestroy_SeqAIJ, 2690b9b97703SBarry Smith MatView_SeqAIJ, 2691357abbc8SBarry Smith 0, 2692ee4f033dSBarry Smith 0, 2693d519adbfSMatthew Knepley /*64*/ 0, 2694ee4f033dSBarry Smith 0, 2695ee4f033dSBarry Smith 0, 2696ee4f033dSBarry Smith 0, 2697ee4f033dSBarry Smith 0, 2698d519adbfSMatthew Knepley /*69*/ MatGetRowMaxAbs_SeqAIJ, 2699c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 2700ee4f033dSBarry Smith 0, 2701ee4f033dSBarry Smith MatSetColoring_SeqAIJ, 2702dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC) 2703ee4f033dSBarry Smith MatSetValuesAdic_SeqAIJ, 2704dcf5cc72SBarry Smith #else 2705dcf5cc72SBarry Smith 0, 2706dcf5cc72SBarry Smith #endif 2707d519adbfSMatthew Knepley /*74*/ MatSetValuesAdifor_SeqAIJ, 27083acb8795SBarry Smith MatFDColoringApply_AIJ, 270997304618SKris Buschelman 0, 271097304618SKris Buschelman 0, 271197304618SKris Buschelman 0, 2712d519adbfSMatthew Knepley /*79*/ 0, 271397304618SKris Buschelman 0, 271497304618SKris Buschelman 0, 271597304618SKris Buschelman 0, 2716bc011b1eSHong Zhang MatLoad_SeqAIJ, 2717d519adbfSMatthew Knepley /*84*/ MatIsSymmetric_SeqAIJ, 27181cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 27196284ec50SHong Zhang 0, 27206284ec50SHong Zhang 0, 2721bc011b1eSHong Zhang 0, 2722d519adbfSMatthew Knepley /*89*/ MatMatMult_SeqAIJ_SeqAIJ, 272326be0446SHong Zhang MatMatMultSymbolic_SeqAIJ_SeqAIJ, 272426be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 2725d439da42SKris Buschelman MatPtAP_Basic, 27267ba1a0bfSKris Buschelman MatPtAPSymbolic_SeqAIJ, 2727d519adbfSMatthew Knepley /*94*/ MatPtAPNumeric_SeqAIJ, 2728bc011b1eSHong Zhang MatMatMultTranspose_SeqAIJ_SeqAIJ, 2729bc011b1eSHong Zhang MatMatMultTransposeSymbolic_SeqAIJ_SeqAIJ, 2730bc011b1eSHong Zhang MatMatMultTransposeNumeric_SeqAIJ_SeqAIJ, 27317ba1a0bfSKris Buschelman MatPtAPSymbolic_SeqAIJ_SeqAIJ, 2732d519adbfSMatthew Knepley /*99*/ MatPtAPNumeric_SeqAIJ_SeqAIJ, 2733609c6c4dSKris Buschelman 0, 2734609c6c4dSKris Buschelman 0, 273587d4246cSBarry Smith MatConjugate_SeqAIJ, 273687d4246cSBarry Smith 0, 2737d519adbfSMatthew Knepley /*104*/MatSetValuesRow_SeqAIJ, 273899cafbc1SBarry Smith MatRealPart_SeqAIJ, 2739f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 2740f5edf698SHong Zhang 0, 27412bebee5dSHong Zhang 0, 2742d519adbfSMatthew Knepley /*109*/0, 2743985db425SBarry Smith 0, 27442af78befSBarry Smith MatGetRowMin_SeqAIJ, 27452af78befSBarry Smith 0, 2746599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 2747d519adbfSMatthew Knepley /*114*/0, 2748599ef60dSHong Zhang 0, 27493c2a7987SHong Zhang 0, 2750fe97e370SBarry Smith 0, 2751fbdbba38SShri Abhyankar 0, 2752fbdbba38SShri Abhyankar /*119*/0, 2753fbdbba38SShri Abhyankar 0, 2754fbdbba38SShri Abhyankar 0, 275582d44351SHong Zhang 0, 275682d44351SHong Zhang MatGetMultiProcBlock_SeqAIJ 27579e29f15eSvictorle }; 275817ab2063SBarry Smith 2759fb2e594dSBarry Smith EXTERN_C_BEGIN 27604a2ae208SSatish Balay #undef __FUNCT__ 27614a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ" 27627087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 2763bef8e0ddSBarry Smith { 2764bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 276597f1f81fSBarry Smith PetscInt i,nz,n; 2766bef8e0ddSBarry Smith 2767bef8e0ddSBarry Smith PetscFunctionBegin; 2768bef8e0ddSBarry Smith 2769bef8e0ddSBarry Smith nz = aij->maxnz; 2770d0f46423SBarry Smith n = mat->rmap->n; 2771bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 2772bef8e0ddSBarry Smith aij->j[i] = indices[i]; 2773bef8e0ddSBarry Smith } 2774bef8e0ddSBarry Smith aij->nz = nz; 2775bef8e0ddSBarry Smith for (i=0; i<n; i++) { 2776bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 2777bef8e0ddSBarry Smith } 2778bef8e0ddSBarry Smith 2779bef8e0ddSBarry Smith PetscFunctionReturn(0); 2780bef8e0ddSBarry Smith } 2781fb2e594dSBarry Smith EXTERN_C_END 2782bef8e0ddSBarry Smith 27834a2ae208SSatish Balay #undef __FUNCT__ 27844a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices" 2785bef8e0ddSBarry Smith /*@ 2786bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 2787bef8e0ddSBarry Smith in the matrix. 2788bef8e0ddSBarry Smith 2789bef8e0ddSBarry Smith Input Parameters: 2790bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 2791bef8e0ddSBarry Smith - indices - the column indices 2792bef8e0ddSBarry Smith 279315091d37SBarry Smith Level: advanced 279415091d37SBarry Smith 2795bef8e0ddSBarry Smith Notes: 2796bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 2797bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 2798bef8e0ddSBarry Smith of the MatSetValues() operation. 2799bef8e0ddSBarry Smith 2800bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 2801d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 2802bef8e0ddSBarry Smith 2803bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 2804bef8e0ddSBarry Smith 2805b9617806SBarry Smith The indices should start with zero, not one. 2806b9617806SBarry Smith 2807bef8e0ddSBarry Smith @*/ 28087087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 2809bef8e0ddSBarry Smith { 28104ac538c5SBarry Smith PetscErrorCode ierr; 2811bef8e0ddSBarry Smith 2812bef8e0ddSBarry Smith PetscFunctionBegin; 28130700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 28144482741eSBarry Smith PetscValidPointer(indices,2); 28154ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt *),(mat,indices));CHKERRQ(ierr); 2816bef8e0ddSBarry Smith PetscFunctionReturn(0); 2817bef8e0ddSBarry Smith } 2818bef8e0ddSBarry Smith 2819be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 2820be6bf707SBarry Smith 2821fb2e594dSBarry Smith EXTERN_C_BEGIN 28224a2ae208SSatish Balay #undef __FUNCT__ 28234a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ" 28247087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 2825be6bf707SBarry Smith { 2826be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 28276849ba73SBarry Smith PetscErrorCode ierr; 2828d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 2829be6bf707SBarry Smith 2830be6bf707SBarry Smith PetscFunctionBegin; 2831be6bf707SBarry Smith if (aij->nonew != 1) { 2832e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 2833be6bf707SBarry Smith } 2834be6bf707SBarry Smith 2835be6bf707SBarry Smith /* allocate space for values if not already there */ 2836be6bf707SBarry Smith if (!aij->saved_values) { 283787828ca2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr); 28389518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 2839be6bf707SBarry Smith } 2840be6bf707SBarry Smith 2841be6bf707SBarry Smith /* copy values over */ 284287828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 2843be6bf707SBarry Smith PetscFunctionReturn(0); 2844be6bf707SBarry Smith } 2845fb2e594dSBarry Smith EXTERN_C_END 2846be6bf707SBarry Smith 28474a2ae208SSatish Balay #undef __FUNCT__ 2848b9617806SBarry Smith #define __FUNCT__ "MatStoreValues" 2849be6bf707SBarry Smith /*@ 2850be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 2851be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2852be6bf707SBarry Smith nonlinear portion. 2853be6bf707SBarry Smith 2854be6bf707SBarry Smith Collect on Mat 2855be6bf707SBarry Smith 2856be6bf707SBarry Smith Input Parameters: 28570e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 2858be6bf707SBarry Smith 285915091d37SBarry Smith Level: advanced 286015091d37SBarry Smith 2861be6bf707SBarry Smith Common Usage, with SNESSolve(): 2862be6bf707SBarry Smith $ Create Jacobian matrix 2863be6bf707SBarry Smith $ Set linear terms into matrix 2864be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 2865be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 2866be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 2867512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 2868be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2869be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 2870be6bf707SBarry Smith $ In your Jacobian routine 2871be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2872be6bf707SBarry Smith $ Set nonlinear terms in matrix 2873be6bf707SBarry Smith 2874be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 2875be6bf707SBarry Smith $ // build linear portion of Jacobian 2876512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 2877be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2878be6bf707SBarry Smith $ loop over nonlinear iterations 2879be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2880be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 2881be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 2882be6bf707SBarry Smith $ Solve linear system with Jacobian 2883be6bf707SBarry Smith $ endloop 2884be6bf707SBarry Smith 2885be6bf707SBarry Smith Notes: 2886be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 2887512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 2888be6bf707SBarry Smith calling this routine. 2889be6bf707SBarry Smith 28900c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 28910c468ba9SBarry Smith and does not allocated additional space. 28920c468ba9SBarry Smith 2893be6bf707SBarry Smith .seealso: MatRetrieveValues() 2894be6bf707SBarry Smith 2895be6bf707SBarry Smith @*/ 28967087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 2897be6bf707SBarry Smith { 28984ac538c5SBarry Smith PetscErrorCode ierr; 2899be6bf707SBarry Smith 2900be6bf707SBarry Smith PetscFunctionBegin; 29010700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2902e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2903e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 29044ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 2905be6bf707SBarry Smith PetscFunctionReturn(0); 2906be6bf707SBarry Smith } 2907be6bf707SBarry Smith 2908fb2e594dSBarry Smith EXTERN_C_BEGIN 29094a2ae208SSatish Balay #undef __FUNCT__ 29104a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ" 29117087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 2912be6bf707SBarry Smith { 2913be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 29146849ba73SBarry Smith PetscErrorCode ierr; 2915d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 2916be6bf707SBarry Smith 2917be6bf707SBarry Smith PetscFunctionBegin; 2918be6bf707SBarry Smith if (aij->nonew != 1) { 2919e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 2920be6bf707SBarry Smith } 2921be6bf707SBarry Smith if (!aij->saved_values) { 2922e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 2923be6bf707SBarry Smith } 2924be6bf707SBarry Smith /* copy values over */ 292587828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 2926be6bf707SBarry Smith PetscFunctionReturn(0); 2927be6bf707SBarry Smith } 2928fb2e594dSBarry Smith EXTERN_C_END 2929be6bf707SBarry Smith 29304a2ae208SSatish Balay #undef __FUNCT__ 29314a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues" 2932be6bf707SBarry Smith /*@ 2933be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 2934be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2935be6bf707SBarry Smith nonlinear portion. 2936be6bf707SBarry Smith 2937be6bf707SBarry Smith Collect on Mat 2938be6bf707SBarry Smith 2939be6bf707SBarry Smith Input Parameters: 2940be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2941be6bf707SBarry Smith 294215091d37SBarry Smith Level: advanced 294315091d37SBarry Smith 2944be6bf707SBarry Smith .seealso: MatStoreValues() 2945be6bf707SBarry Smith 2946be6bf707SBarry Smith @*/ 29477087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 2948be6bf707SBarry Smith { 29494ac538c5SBarry Smith PetscErrorCode ierr; 2950be6bf707SBarry Smith 2951be6bf707SBarry Smith PetscFunctionBegin; 29520700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2953e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2954e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 29554ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 2956be6bf707SBarry Smith PetscFunctionReturn(0); 2957be6bf707SBarry Smith } 2958be6bf707SBarry Smith 2959f83d6046SBarry Smith 2960be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 29614a2ae208SSatish Balay #undef __FUNCT__ 29624a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ" 296317ab2063SBarry Smith /*@C 2964682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 29650d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 29666e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 296751c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 29682bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 296917ab2063SBarry Smith 2970db81eaa0SLois Curfman McInnes Collective on MPI_Comm 2971db81eaa0SLois Curfman McInnes 297217ab2063SBarry Smith Input Parameters: 2973db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 297417ab2063SBarry Smith . m - number of rows 297517ab2063SBarry Smith . n - number of columns 297617ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 297751c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 29782bd5e0b2SLois Curfman McInnes (possibly different for each row) or PETSC_NULL 297917ab2063SBarry Smith 298017ab2063SBarry Smith Output Parameter: 2981416022c9SBarry Smith . A - the matrix 298217ab2063SBarry Smith 2983175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 2984ae1d86c5SBarry Smith MatXXXXSetPreallocation() paradgm instead of this routine directly. 2985175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 2986175b88e8SBarry Smith 2987b259b22eSLois Curfman McInnes Notes: 298849a6f317SBarry Smith If nnz is given then nz is ignored 298949a6f317SBarry Smith 299017ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 299117ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 29920002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 299344cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 299417ab2063SBarry Smith 299517ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2996a40aa06bSLois Curfman McInnes Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 29973d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 29986da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 299917ab2063SBarry Smith 3000682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 30014fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3002682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 30036c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 30046c7ebb05SLois Curfman McInnes 30056c7ebb05SLois Curfman McInnes Options Database Keys: 3006698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 30079db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 300817ab2063SBarry Smith 3009027ccd11SLois Curfman McInnes Level: intermediate 3010027ccd11SLois Curfman McInnes 301136db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 301236db0b34SBarry Smith 301317ab2063SBarry Smith @*/ 30147087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 301517ab2063SBarry Smith { 3016dfbe8321SBarry Smith PetscErrorCode ierr; 30176945ee14SBarry Smith 30183a40ed3dSBarry Smith PetscFunctionBegin; 3019f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 3020117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 3021c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 3022d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 3023273d9f13SBarry Smith PetscFunctionReturn(0); 3024273d9f13SBarry Smith } 3025273d9f13SBarry Smith 30264a2ae208SSatish Balay #undef __FUNCT__ 30274a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation" 3028273d9f13SBarry Smith /*@C 3029273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 3030273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 3031273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 3032273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 3033273d9f13SBarry Smith 3034273d9f13SBarry Smith Collective on MPI_Comm 3035273d9f13SBarry Smith 3036273d9f13SBarry Smith Input Parameters: 3037117016b1SBarry Smith + B - The matrix-free 3038273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 3039273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 3040273d9f13SBarry Smith (possibly different for each row) or PETSC_NULL 3041273d9f13SBarry Smith 3042273d9f13SBarry Smith Notes: 304349a6f317SBarry Smith If nnz is given then nz is ignored 304449a6f317SBarry Smith 3045273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 3046273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 3047273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 3048273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 3049273d9f13SBarry Smith 3050273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 3051273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 3052273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 3053273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 3054273d9f13SBarry Smith 3055aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 3056aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 3057aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 3058aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 3059aa95bbe8SBarry Smith 3060a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 3061a96a251dSBarry Smith entries or columns indices 3062a96a251dSBarry Smith 3063273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 3064273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 3065273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 3066273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 3067273d9f13SBarry Smith 3068273d9f13SBarry Smith Options Database Keys: 3069698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 3070698d4c6aSKris Buschelman . -mat_inode_limit <limit> - Sets inode limit (max limit=5) 3071273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 3072273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 3073273d9f13SBarry Smith the user still MUST index entries starting at 0! 3074273d9f13SBarry Smith 3075273d9f13SBarry Smith Level: intermediate 3076273d9f13SBarry Smith 3077aa95bbe8SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo() 3078273d9f13SBarry Smith 3079273d9f13SBarry Smith @*/ 30807087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 3081273d9f13SBarry Smith { 30824ac538c5SBarry Smith PetscErrorCode ierr; 3083a23d5eceSKris Buschelman 3084a23d5eceSKris Buschelman PetscFunctionBegin; 30854ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 3086a23d5eceSKris Buschelman PetscFunctionReturn(0); 3087a23d5eceSKris Buschelman } 3088a23d5eceSKris Buschelman 3089a23d5eceSKris Buschelman EXTERN_C_BEGIN 3090a23d5eceSKris Buschelman #undef __FUNCT__ 3091a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ" 30927087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 3093a23d5eceSKris Buschelman { 3094273d9f13SBarry Smith Mat_SeqAIJ *b; 3095ace3abfcSBarry Smith PetscBool skipallocation = PETSC_FALSE; 30966849ba73SBarry Smith PetscErrorCode ierr; 309797f1f81fSBarry Smith PetscInt i; 3098273d9f13SBarry Smith 3099273d9f13SBarry Smith PetscFunctionBegin; 3100d5d45c9bSBarry Smith 3101a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 3102c461c341SBarry Smith skipallocation = PETSC_TRUE; 3103c461c341SBarry Smith nz = 0; 3104c461c341SBarry Smith } 3105c461c341SBarry Smith 310626283091SBarry Smith ierr = PetscLayoutSetBlockSize(B->rmap,1);CHKERRQ(ierr); 310726283091SBarry Smith ierr = PetscLayoutSetBlockSize(B->cmap,1);CHKERRQ(ierr); 310826283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 310926283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3110899cda47SBarry Smith 3111435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 3112e32f2f54SBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 3113b73539f3SBarry Smith if (nnz) { 3114d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 3115e32f2f54SBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 3116e32f2f54SBarry Smith if (nnz[i] > B->cmap->n) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than row length: local row %d value %d rowlength %d",i,nnz[i],B->cmap->n); 3117b73539f3SBarry Smith } 3118b73539f3SBarry Smith } 3119b73539f3SBarry Smith 3120273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 3121273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 3122273d9f13SBarry Smith 3123ab93d7beSBarry Smith if (!skipallocation) { 31242ee49352SLisandro Dalcin if (!b->imax) { 3125d0f46423SBarry Smith ierr = PetscMalloc2(B->rmap->n,PetscInt,&b->imax,B->rmap->n,PetscInt,&b->ilen);CHKERRQ(ierr); 3126d0f46423SBarry Smith ierr = PetscLogObjectMemory(B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 31272ee49352SLisandro Dalcin } 3128273d9f13SBarry Smith if (!nnz) { 3129435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 3130c62bd62aSJed Brown else if (nz < 0) nz = 1; 3131d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 3132d0f46423SBarry Smith nz = nz*B->rmap->n; 3133273d9f13SBarry Smith } else { 3134273d9f13SBarry Smith nz = 0; 3135d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 3136273d9f13SBarry Smith } 3137ab93d7beSBarry Smith /* b->ilen will count nonzeros in each row so far. */ 3138d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { b->ilen[i] = 0; } 3139ab93d7beSBarry Smith 3140273d9f13SBarry Smith /* allocate the matrix space */ 31412ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 3142d0f46423SBarry Smith ierr = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->n+1,PetscInt,&b->i);CHKERRQ(ierr); 3143d0f46423SBarry Smith ierr = PetscLogObjectMemory(B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 3144bfeeae90SHong Zhang b->i[0] = 0; 3145d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 31465da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 31475da197adSKris Buschelman } 3148273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 3149e6b907acSBarry Smith b->free_a = PETSC_TRUE; 3150e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 3151c461c341SBarry Smith } else { 3152e6b907acSBarry Smith b->free_a = PETSC_FALSE; 3153e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 3154c461c341SBarry Smith } 3155273d9f13SBarry Smith 3156273d9f13SBarry Smith b->nz = 0; 3157273d9f13SBarry Smith b->maxnz = nz; 3158273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 3159273d9f13SBarry Smith PetscFunctionReturn(0); 3160273d9f13SBarry Smith } 3161a23d5eceSKris Buschelman EXTERN_C_END 3162273d9f13SBarry Smith 3163a1661176SMatthew Knepley #undef __FUNCT__ 3164a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR" 316558d36128SBarry Smith /*@ 3166a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 3167a1661176SMatthew Knepley 3168a1661176SMatthew Knepley Input Parameters: 3169a1661176SMatthew Knepley + B - the matrix 3170a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 3171a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 3172a1661176SMatthew Knepley - v - optional values in the matrix 3173a1661176SMatthew Knepley 3174a1661176SMatthew Knepley Level: developer 3175a1661176SMatthew Knepley 317658d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 317758d36128SBarry Smith 3178a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential 3179a1661176SMatthew Knepley 3180a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ 3181a1661176SMatthew Knepley @*/ 3182a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 3183a1661176SMatthew Knepley { 3184a1661176SMatthew Knepley PetscErrorCode ierr; 3185a1661176SMatthew Knepley 3186a1661176SMatthew Knepley PetscFunctionBegin; 31870700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 31884ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 3189a1661176SMatthew Knepley PetscFunctionReturn(0); 3190a1661176SMatthew Knepley } 3191a1661176SMatthew Knepley 3192a1661176SMatthew Knepley EXTERN_C_BEGIN 3193a1661176SMatthew Knepley #undef __FUNCT__ 3194a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR_SeqAIJ" 31957087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 3196a1661176SMatthew Knepley { 3197a1661176SMatthew Knepley PetscInt i; 3198a1661176SMatthew Knepley PetscInt m,n; 3199a1661176SMatthew Knepley PetscInt nz; 3200a1661176SMatthew Knepley PetscInt *nnz, nz_max = 0; 3201a1661176SMatthew Knepley PetscScalar *values; 3202a1661176SMatthew Knepley PetscErrorCode ierr; 3203a1661176SMatthew Knepley 3204a1661176SMatthew Knepley PetscFunctionBegin; 3205a1661176SMatthew Knepley ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 3206a1661176SMatthew Knepley 320765e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 3208a1661176SMatthew Knepley ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr); 3209a1661176SMatthew Knepley for(i = 0; i < m; i++) { 3210b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 3211a1661176SMatthew Knepley nz_max = PetscMax(nz_max, nz); 321265e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 3213a1661176SMatthew Knepley nnz[i] = nz; 3214a1661176SMatthew Knepley } 3215a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 3216a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 3217a1661176SMatthew Knepley 3218a1661176SMatthew Knepley if (v) { 3219a1661176SMatthew Knepley values = (PetscScalar*) v; 3220a1661176SMatthew Knepley } else { 32210e83c824SBarry Smith ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr); 3222a1661176SMatthew Knepley ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr); 3223a1661176SMatthew Knepley } 3224a1661176SMatthew Knepley 3225a1661176SMatthew Knepley for(i = 0; i < m; i++) { 3226b7940d39SSatish Balay nz = Ii[i+1] - Ii[i]; 3227b7940d39SSatish Balay ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr); 3228a1661176SMatthew Knepley } 3229a1661176SMatthew Knepley 3230a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3231a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3232a1661176SMatthew Knepley 3233a1661176SMatthew Knepley if (!v) { 3234a1661176SMatthew Knepley ierr = PetscFree(values);CHKERRQ(ierr); 3235a1661176SMatthew Knepley } 3236a1661176SMatthew Knepley PetscFunctionReturn(0); 3237a1661176SMatthew Knepley } 3238a1661176SMatthew Knepley EXTERN_C_END 3239a1661176SMatthew Knepley 32407c4f633dSBarry Smith #include "../src/mat/impls/dense/seq/dense.h" 3241be7314b0SBarry Smith #include "private/petscaxpy.h" 3242170fe5c8SBarry Smith 3243170fe5c8SBarry Smith #undef __FUNCT__ 3244170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ" 3245170fe5c8SBarry Smith /* 3246170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 3247170fe5c8SBarry Smith 3248170fe5c8SBarry Smith n p p 3249170fe5c8SBarry Smith ( ) ( ) ( ) 3250170fe5c8SBarry Smith m ( A ) * n ( B ) = m ( C ) 3251170fe5c8SBarry Smith ( ) ( ) ( ) 3252170fe5c8SBarry Smith 3253170fe5c8SBarry Smith */ 3254170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 3255170fe5c8SBarry Smith { 3256170fe5c8SBarry Smith PetscErrorCode ierr; 3257170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 3258170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 3259170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 32601de00fd4SBarry Smith PetscInt i,n,m,q,p; 3261170fe5c8SBarry Smith const PetscInt *ii,*idx; 3262170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 3263170fe5c8SBarry Smith PetscScalar *c,*c_q; 3264170fe5c8SBarry Smith 3265170fe5c8SBarry Smith PetscFunctionBegin; 3266d0f46423SBarry Smith m = A->rmap->n; 3267d0f46423SBarry Smith n = A->cmap->n; 3268d0f46423SBarry Smith p = B->cmap->n; 3269170fe5c8SBarry Smith a = sub_a->v; 3270170fe5c8SBarry Smith b = sub_b->a; 3271170fe5c8SBarry Smith c = sub_c->v; 3272170fe5c8SBarry Smith ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr); 3273170fe5c8SBarry Smith 3274170fe5c8SBarry Smith ii = sub_b->i; 3275170fe5c8SBarry Smith idx = sub_b->j; 3276170fe5c8SBarry Smith for (i=0; i<n; i++) { 3277170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 3278170fe5c8SBarry Smith while (q-->0) { 3279170fe5c8SBarry Smith c_q = c + m*(*idx); 3280170fe5c8SBarry Smith a_q = a + m*i; 3281be7314b0SBarry Smith PetscAXPY(c_q,*b,a_q,m); 3282170fe5c8SBarry Smith idx++; 3283170fe5c8SBarry Smith b++; 3284170fe5c8SBarry Smith } 3285170fe5c8SBarry Smith } 3286170fe5c8SBarry Smith PetscFunctionReturn(0); 3287170fe5c8SBarry Smith } 3288170fe5c8SBarry Smith 3289170fe5c8SBarry Smith #undef __FUNCT__ 3290170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ" 3291170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C) 3292170fe5c8SBarry Smith { 3293170fe5c8SBarry Smith PetscErrorCode ierr; 3294d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 3295170fe5c8SBarry Smith Mat Cmat; 3296170fe5c8SBarry Smith 3297170fe5c8SBarry Smith PetscFunctionBegin; 3298e32f2f54SBarry Smith if (A->cmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"A->cmap->n %d != B->rmap->n %d\n",A->cmap->n,B->rmap->n); 329939804f7cSBarry Smith ierr = MatCreate(((PetscObject)A)->comm,&Cmat);CHKERRQ(ierr); 3300170fe5c8SBarry Smith ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr); 3301170fe5c8SBarry Smith ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr); 3302170fe5c8SBarry Smith ierr = MatSeqDenseSetPreallocation(Cmat,PETSC_NULL);CHKERRQ(ierr); 3303170fe5c8SBarry Smith Cmat->assembled = PETSC_TRUE; 3304170fe5c8SBarry Smith *C = Cmat; 3305170fe5c8SBarry Smith PetscFunctionReturn(0); 3306170fe5c8SBarry Smith } 3307170fe5c8SBarry Smith 3308170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 3309170fe5c8SBarry Smith #undef __FUNCT__ 3310170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ" 3311170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 3312170fe5c8SBarry Smith { 3313170fe5c8SBarry Smith PetscErrorCode ierr; 3314170fe5c8SBarry Smith 3315170fe5c8SBarry Smith PetscFunctionBegin; 3316170fe5c8SBarry Smith if (scall == MAT_INITIAL_MATRIX){ 3317170fe5c8SBarry Smith ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr); 3318170fe5c8SBarry Smith } 3319170fe5c8SBarry Smith ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr); 3320170fe5c8SBarry Smith PetscFunctionReturn(0); 3321170fe5c8SBarry Smith } 3322170fe5c8SBarry Smith 3323170fe5c8SBarry Smith 33240bad9183SKris Buschelman /*MC 3325fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 33260bad9183SKris Buschelman based on compressed sparse row format. 33270bad9183SKris Buschelman 33280bad9183SKris Buschelman Options Database Keys: 33290bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 33300bad9183SKris Buschelman 33310bad9183SKris Buschelman Level: beginner 33320bad9183SKris Buschelman 3333f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 33340bad9183SKris Buschelman M*/ 33350bad9183SKris Buschelman 3336a6175056SHong Zhang EXTERN_C_BEGIN 3337b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX) 3338b5e56a35SBarry Smith extern PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*); 3339b5e56a35SBarry Smith #endif 334065460251SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SCALAR_SINGLE) && !defined(PETSC_USE_SCALAR_MAT_SINGLE) 3341af1023dbSSatish Balay extern PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat *); 3342af1023dbSSatish Balay #endif 33437087cfbeSBarry Smith extern PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 33447087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*); 33457087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*); 33467087cfbeSBarry Smith extern PetscErrorCode MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool *); 3347611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS) 33487087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*); 3349611f576cSBarry Smith #endif 3350611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU) 33517087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*); 3352611f576cSBarry Smith #endif 3353f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST) 3354f3c0ef26SHong Zhang extern PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*); 3355f3c0ef26SHong Zhang #endif 3356611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES) 33577087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_spooles(Mat,MatFactorType,Mat*); 3358611f576cSBarry Smith #endif 3359eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK) 33607087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*); 3361eb3b5408SSatish Balay #endif 3362586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD) 33637087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*); 3364586621ddSJed Brown #endif 3365719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL) 33667087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*); 3367719d5645SBarry Smith #endif 3368b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 33697087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*); 33707087cfbeSBarry Smith extern PetscErrorCode MatlabEnginePut_SeqAIJ(PetscObject,void*); 33717087cfbeSBarry Smith extern PetscErrorCode MatlabEngineGet_SeqAIJ(PetscObject,void*); 3372b3866ffcSBarry Smith #endif 337317667f90SBarry Smith EXTERN_C_END 337417667f90SBarry Smith 3375b24902e0SBarry Smith 337617667f90SBarry Smith EXTERN_C_BEGIN 33774a2ae208SSatish Balay #undef __FUNCT__ 33784a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ" 33797087cfbeSBarry Smith PetscErrorCode MatCreate_SeqAIJ(Mat B) 3380273d9f13SBarry Smith { 3381273d9f13SBarry Smith Mat_SeqAIJ *b; 3382dfbe8321SBarry Smith PetscErrorCode ierr; 338338baddfdSBarry Smith PetscMPIInt size; 3384273d9f13SBarry Smith 3385273d9f13SBarry Smith PetscFunctionBegin; 33867adad957SLisandro Dalcin ierr = MPI_Comm_size(((PetscObject)B)->comm,&size);CHKERRQ(ierr); 3387e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 3388273d9f13SBarry Smith 338938f2d2fdSLisandro Dalcin ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr); 3390b0a32e0cSBarry Smith B->data = (void*)b; 3391549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 3392416022c9SBarry Smith b->row = 0; 3393416022c9SBarry Smith b->col = 0; 339482bf6240SBarry Smith b->icol = 0; 3395b810aeb4SBarry Smith b->reallocs = 0; 339636db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 3397f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 3398416022c9SBarry Smith b->nonew = 0; 3399416022c9SBarry Smith b->diag = 0; 3400416022c9SBarry Smith b->solve_work = 0; 34012a1b7f2aSHong Zhang B->spptr = 0; 3402be6bf707SBarry Smith b->saved_values = 0; 3403d7f994e1SBarry Smith b->idiag = 0; 340471f1c65dSBarry Smith b->mdiag = 0; 340571f1c65dSBarry Smith b->ssor_work = 0; 340671f1c65dSBarry Smith b->omega = 1.0; 340771f1c65dSBarry Smith b->fshift = 0.0; 340871f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 3409a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 3410a30b2313SHong Zhang b->xtoy = 0; 3411a30b2313SHong Zhang b->XtoY = 0; 341288e51ccdSHong Zhang B->same_nonzero = PETSC_FALSE; 341317ab2063SBarry Smith 341435d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 3415b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3416700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_matlab_C","MatGetFactor_seqaij_matlab",MatGetFactor_seqaij_matlab);CHKERRQ(ierr); 3417b3866ffcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatlabEnginePut_SeqAIJ",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 3418b3866ffcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatlabEngineGet_SeqAIJ",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 3419b3866ffcSBarry Smith #endif 3420b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX) 3421700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_pastix_C","MatGetFactor_seqaij_pastix",MatGetFactor_seqaij_pastix);CHKERRQ(ierr); 3422b5e56a35SBarry Smith #endif 342365460251SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SCALAR_SINGLE) && !defined(PETSC_USE_SCALAR_MAT_SINGLE) 3424700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_essl_C","MatGetFactor_seqaij_essl",MatGetFactor_seqaij_essl);CHKERRQ(ierr); 3425719d5645SBarry Smith #endif 3426611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU) 3427700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_C","MatGetFactor_seqaij_superlu",MatGetFactor_seqaij_superlu);CHKERRQ(ierr); 3428611f576cSBarry Smith #endif 3429f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST) 3430700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_dist_C","MatGetFactor_seqaij_superlu_dist",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr); 3431f3c0ef26SHong Zhang #endif 3432611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES) 3433700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_spooles_C","MatGetFactor_seqaij_spooles",MatGetFactor_seqaij_spooles);CHKERRQ(ierr); 3434611f576cSBarry Smith #endif 3435611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS) 3436700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_mumps_C","MatGetFactor_aij_mumps",MatGetFactor_aij_mumps);CHKERRQ(ierr); 3437611f576cSBarry Smith #endif 3438eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK) 3439700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_umfpack_C","MatGetFactor_seqaij_umfpack",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr); 3440eb3b5408SSatish Balay #endif 3441586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD) 3442700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_cholmod_C","MatGetFactor_seqaij_cholmod",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr); 3443586621ddSJed Brown #endif 3444719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL) 3445700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_lusol_C","MatGetFactor_seqaij_lusol",MatGetFactor_seqaij_lusol);CHKERRQ(ierr); 3446719d5645SBarry Smith #endif 3447700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_petsc_C","MatGetFactor_seqaij_petsc",MatGetFactor_seqaij_petsc);CHKERRQ(ierr); 3448700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactorAvailable_petsc_C","MatGetFactorAvailable_seqaij_petsc",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr); 3449700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_bas_C","MatGetFactor_seqaij_bas",MatGetFactor_seqaij_bas);CHKERRQ(ierr); 3450700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C","MatSeqAIJSetColumnIndices_SeqAIJ",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 3451700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C","MatStoreValues_SeqAIJ",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 3452700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C","MatRetrieveValues_SeqAIJ",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 3453700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C","MatConvert_SeqAIJ_SeqSBAIJ",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 3454700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C","MatConvert_SeqAIJ_SeqBAIJ",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 3455700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijperm_C","MatConvert_SeqAIJ_SeqAIJPERM",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 3456700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C","MatConvert_SeqAIJ_SeqAIJCRL",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 3457700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C","MatIsTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 3458700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsHermitianTranspose_C","MatIsHermitianTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 3459700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C","MatSeqAIJSetPreallocation_SeqAIJ",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 3460700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C","MatSeqAIJSetPreallocationCSR_SeqAIJ",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 3461700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C","MatReorderForNonzeroDiagonal_SeqAIJ",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 3462700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMult_seqdense_seqaij_C","MatMatMult_SeqDense_SeqAIJ",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr); 3463700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C","MatMatMultSymbolic_SeqDense_SeqAIJ",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr); 3464700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C","MatMatMultNumeric_SeqDense_SeqAIJ",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr); 34654108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 346617667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 34673a40ed3dSBarry Smith PetscFunctionReturn(0); 346817ab2063SBarry Smith } 3469273d9f13SBarry Smith EXTERN_C_END 347017ab2063SBarry Smith 34714a2ae208SSatish Balay #undef __FUNCT__ 3472b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ" 3473b24902e0SBarry Smith /* 3474b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 3475b24902e0SBarry Smith */ 3476ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 347717ab2063SBarry Smith { 3478416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 34796849ba73SBarry Smith PetscErrorCode ierr; 3480d0f46423SBarry Smith PetscInt i,m = A->rmap->n; 348117ab2063SBarry Smith 34823a40ed3dSBarry Smith PetscFunctionBegin; 3483273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 3484273d9f13SBarry Smith 3485d5f3da31SBarry Smith C->factortype = A->factortype; 3486416022c9SBarry Smith c->row = 0; 3487416022c9SBarry Smith c->col = 0; 348882bf6240SBarry Smith c->icol = 0; 34896ad4291fSHong Zhang c->reallocs = 0; 349017ab2063SBarry Smith 34916ad4291fSHong Zhang C->assembled = PETSC_TRUE; 349217ab2063SBarry Smith 349326283091SBarry Smith ierr = PetscLayoutSetBlockSize(C->rmap,1);CHKERRQ(ierr); 349426283091SBarry Smith ierr = PetscLayoutSetBlockSize(C->cmap,1);CHKERRQ(ierr); 349526283091SBarry Smith ierr = PetscLayoutSetUp(C->rmap);CHKERRQ(ierr); 349626283091SBarry Smith ierr = PetscLayoutSetUp(C->cmap);CHKERRQ(ierr); 3497eec197d1SBarry Smith 349833b91e9fSSatish Balay ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr); 34999518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 350017ab2063SBarry Smith for (i=0; i<m; i++) { 3501416022c9SBarry Smith c->imax[i] = a->imax[i]; 3502416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 350317ab2063SBarry Smith } 350417ab2063SBarry Smith 350517ab2063SBarry Smith /* allocate the matrix space */ 3506f77e22a1SHong Zhang if (mallocmatspace){ 3507a96a251dSBarry Smith ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr); 35089518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 3509f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 351097f1f81fSBarry Smith ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 351117ab2063SBarry Smith if (m > 0) { 351297f1f81fSBarry Smith ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr); 3513be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 3514bfeeae90SHong Zhang ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 3515be6bf707SBarry Smith } else { 3516bfeeae90SHong Zhang ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 351717ab2063SBarry Smith } 351808480c60SBarry Smith } 3519f77e22a1SHong Zhang } 352017ab2063SBarry Smith 35216ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 3522416022c9SBarry Smith c->roworiented = a->roworiented; 3523416022c9SBarry Smith c->nonew = a->nonew; 3524416022c9SBarry Smith if (a->diag) { 352597f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr); 352652e6d16bSBarry Smith ierr = PetscLogObjectMemory(C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 352717ab2063SBarry Smith for (i=0; i<m; i++) { 3528416022c9SBarry Smith c->diag[i] = a->diag[i]; 352917ab2063SBarry Smith } 35303a40ed3dSBarry Smith } else c->diag = 0; 35316ad4291fSHong Zhang c->solve_work = 0; 35326ad4291fSHong Zhang c->saved_values = 0; 35336ad4291fSHong Zhang c->idiag = 0; 353471f1c65dSBarry Smith c->ssor_work = 0; 3535a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 3536e6b907acSBarry Smith c->free_a = PETSC_TRUE; 3537e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 35386ad4291fSHong Zhang c->xtoy = 0; 35396ad4291fSHong Zhang c->XtoY = 0; 35406ad4291fSHong Zhang 3541416022c9SBarry Smith c->nz = a->nz; 35428ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 3543273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 3544754ec7b1SSatish Balay 35456ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 35466ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 3547cd6b891eSBarry Smith c->compressedrow.check = a->compressedrow.check; 3548cd6b891eSBarry Smith if (a->compressedrow.use){ 35496ad4291fSHong Zhang i = a->compressedrow.nrows; 35500e83c824SBarry Smith ierr = PetscMalloc2(i+1,PetscInt,&c->compressedrow.i,i,PetscInt,&c->compressedrow.rindex);CHKERRQ(ierr); 35516ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr); 35526ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr); 355327ea64f8SHong Zhang } else { 355427ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 355527ea64f8SHong Zhang c->compressedrow.i = PETSC_NULL; 355627ea64f8SHong Zhang c->compressedrow.rindex = PETSC_NULL; 35576ad4291fSHong Zhang } 355888e51ccdSHong Zhang C->same_nonzero = A->same_nonzero; 35594108e4d5SBarry Smith ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 35604846f1f5SKris Buschelman 35617adad957SLisandro Dalcin ierr = PetscFListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 35623a40ed3dSBarry Smith PetscFunctionReturn(0); 356317ab2063SBarry Smith } 356417ab2063SBarry Smith 35654a2ae208SSatish Balay #undef __FUNCT__ 3566b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ" 3567b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 3568b24902e0SBarry Smith { 3569b24902e0SBarry Smith PetscErrorCode ierr; 3570b24902e0SBarry Smith 3571b24902e0SBarry Smith PetscFunctionBegin; 3572b24902e0SBarry Smith ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr); 35734b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 3574b24902e0SBarry Smith ierr = MatSetType(*B,MATSEQAIJ);CHKERRQ(ierr); 3575f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 3576b24902e0SBarry Smith PetscFunctionReturn(0); 3577b24902e0SBarry Smith } 3578b24902e0SBarry Smith 3579b24902e0SBarry Smith #undef __FUNCT__ 35804a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ" 3581112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 3582fbdbba38SShri Abhyankar { 3583fbdbba38SShri Abhyankar Mat_SeqAIJ *a; 3584fbdbba38SShri Abhyankar PetscErrorCode ierr; 3585fbdbba38SShri Abhyankar PetscInt i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols; 3586fbdbba38SShri Abhyankar int fd; 3587fbdbba38SShri Abhyankar PetscMPIInt size; 3588fbdbba38SShri Abhyankar MPI_Comm comm; 3589fbdbba38SShri Abhyankar 3590fbdbba38SShri Abhyankar PetscFunctionBegin; 3591fbdbba38SShri Abhyankar ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 3592fbdbba38SShri Abhyankar ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 3593fbdbba38SShri Abhyankar if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor"); 3594fbdbba38SShri Abhyankar ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 3595fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 3596fbdbba38SShri Abhyankar if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 3597fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 3598fbdbba38SShri Abhyankar 3599fbdbba38SShri Abhyankar if (nz < 0) { 3600fbdbba38SShri Abhyankar SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 3601fbdbba38SShri Abhyankar } 3602fbdbba38SShri Abhyankar 3603fbdbba38SShri Abhyankar /* read in row lengths */ 3604fbdbba38SShri Abhyankar ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr); 3605fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 3606fbdbba38SShri Abhyankar 3607fbdbba38SShri Abhyankar /* check if sum of rowlengths is same as nz */ 3608fbdbba38SShri Abhyankar for (i=0,sum=0; i< M; i++) sum +=rowlengths[i]; 3609fbdbba38SShri Abhyankar if (sum != nz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Inconsistant matrix data in file. no-nonzeros = %d, sum-row-lengths = %d\n",nz,sum); 3610fbdbba38SShri Abhyankar 3611fbdbba38SShri Abhyankar /* set global size if not set already*/ 3612f501eaabSShri Abhyankar if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) { 3613fbdbba38SShri Abhyankar ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 3614aabbc4fbSShri Abhyankar } else { 3615fbdbba38SShri Abhyankar /* if sizes and type are already set, check if the vector global sizes are correct */ 3616fbdbba38SShri Abhyankar ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr); 3617f501eaabSShri Abhyankar if (M != rows || N != cols) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different length (%d, %d) than the input matrix (%d, %d)",M,N,rows,cols); 3618aabbc4fbSShri Abhyankar } 3619fbdbba38SShri Abhyankar ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr); 3620fbdbba38SShri Abhyankar a = (Mat_SeqAIJ*)newMat->data; 3621fbdbba38SShri Abhyankar 3622fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 3623fbdbba38SShri Abhyankar 3624fbdbba38SShri Abhyankar /* read in nonzero values */ 3625fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 3626fbdbba38SShri Abhyankar 3627fbdbba38SShri Abhyankar /* set matrix "i" values */ 3628fbdbba38SShri Abhyankar a->i[0] = 0; 3629fbdbba38SShri Abhyankar for (i=1; i<= M; i++) { 3630fbdbba38SShri Abhyankar a->i[i] = a->i[i-1] + rowlengths[i-1]; 3631fbdbba38SShri Abhyankar a->ilen[i-1] = rowlengths[i-1]; 3632fbdbba38SShri Abhyankar } 3633fbdbba38SShri Abhyankar ierr = PetscFree(rowlengths);CHKERRQ(ierr); 3634fbdbba38SShri Abhyankar 3635fbdbba38SShri Abhyankar ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3636fbdbba38SShri Abhyankar ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3637fbdbba38SShri Abhyankar PetscFunctionReturn(0); 3638fbdbba38SShri Abhyankar } 3639fbdbba38SShri Abhyankar 3640fbdbba38SShri Abhyankar #undef __FUNCT__ 3641b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ" 3642ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 36437264ac53SSatish Balay { 36447264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data; 3645dfbe8321SBarry Smith PetscErrorCode ierr; 3646eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 3647eeffb40dSHong Zhang PetscInt k; 3648eeffb40dSHong Zhang #endif 36497264ac53SSatish Balay 36503a40ed3dSBarry Smith PetscFunctionBegin; 3651bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 3652d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 3653ca44d042SBarry Smith *flg = PETSC_FALSE; 3654ca44d042SBarry Smith PetscFunctionReturn(0); 3655bcd2baecSBarry Smith } 36567264ac53SSatish Balay 36577264ac53SSatish Balay /* if the a->i are the same */ 3658d0f46423SBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr); 3659abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 36607264ac53SSatish Balay 36617264ac53SSatish Balay /* if a->j are the same */ 366297f1f81fSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr); 3663abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 3664bcd2baecSBarry Smith 3665bcd2baecSBarry Smith /* if a->a are the same */ 3666eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 3667eeffb40dSHong Zhang for (k=0; k<a->nz; k++){ 3668eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])){ 3669eeffb40dSHong Zhang *flg = PETSC_FALSE; 36703a40ed3dSBarry Smith PetscFunctionReturn(0); 3671eeffb40dSHong Zhang } 3672eeffb40dSHong Zhang } 3673eeffb40dSHong Zhang #else 3674eeffb40dSHong Zhang ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 3675eeffb40dSHong Zhang #endif 3676eeffb40dSHong Zhang PetscFunctionReturn(0); 36777264ac53SSatish Balay } 367836db0b34SBarry Smith 36794a2ae208SSatish Balay #undef __FUNCT__ 36804a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays" 368105869f15SSatish Balay /*@ 368236db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 368336db0b34SBarry Smith provided by the user. 368436db0b34SBarry Smith 3685c75a6043SHong Zhang Collective on MPI_Comm 368636db0b34SBarry Smith 368736db0b34SBarry Smith Input Parameters: 368836db0b34SBarry Smith + comm - must be an MPI communicator of size 1 368936db0b34SBarry Smith . m - number of rows 369036db0b34SBarry Smith . n - number of columns 369136db0b34SBarry Smith . i - row indices 369236db0b34SBarry Smith . j - column indices 369336db0b34SBarry Smith - a - matrix values 369436db0b34SBarry Smith 369536db0b34SBarry Smith Output Parameter: 369636db0b34SBarry Smith . mat - the matrix 369736db0b34SBarry Smith 369836db0b34SBarry Smith Level: intermediate 369936db0b34SBarry Smith 370036db0b34SBarry Smith Notes: 37010551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 370236db0b34SBarry Smith once the matrix is destroyed 370336db0b34SBarry Smith 370436db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 370536db0b34SBarry Smith 3706bfeeae90SHong Zhang The i and j indices are 0 based 370736db0b34SBarry Smith 3708a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 3709a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 3710a4552177SSatish Balay as shown: 3711a4552177SSatish Balay 3712a4552177SSatish Balay 1 0 0 3713a4552177SSatish Balay 2 0 3 3714a4552177SSatish Balay 4 5 6 3715a4552177SSatish Balay 3716a4552177SSatish Balay i = {0,1,3,6} [size = nrow+1 = 3+1] 37179985e31cSBarry Smith j = {0,0,2,0,1,2} [size = nz = 6]; values must be sorted for each row 3718a4552177SSatish Balay v = {1,2,3,4,5,6} [size = nz = 6] 3719a4552177SSatish Balay 37209985e31cSBarry Smith 37212fb0ec9aSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 372236db0b34SBarry Smith 372336db0b34SBarry Smith @*/ 37247087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat) 372536db0b34SBarry Smith { 3726dfbe8321SBarry Smith PetscErrorCode ierr; 3727cbcfb4deSHong Zhang PetscInt ii; 372836db0b34SBarry Smith Mat_SeqAIJ *aij; 3729cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG) 3730cbcfb4deSHong Zhang PetscInt jj; 3731cbcfb4deSHong Zhang #endif 373236db0b34SBarry Smith 373336db0b34SBarry Smith PetscFunctionBegin; 3734a96a251dSBarry Smith if (i[0]) { 3735e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 373636db0b34SBarry Smith } 3737f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 3738f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 3739ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 3740ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 3741ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 3742ab93d7beSBarry Smith ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr); 3743ab93d7beSBarry Smith 374436db0b34SBarry Smith aij->i = i; 374536db0b34SBarry Smith aij->j = j; 374636db0b34SBarry Smith aij->a = a; 374736db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 374836db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 3749e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 3750e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 375136db0b34SBarry Smith 375236db0b34SBarry Smith for (ii=0; ii<m; ii++) { 375336db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 37542515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 3755e32f2f54SBarry Smith if (i[ii+1] - i[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row length in i (row indices) row = %d length = %d",ii,i[ii+1] - i[ii]); 37569985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 3757e32f2f54SBarry Smith if (j[jj] < j[jj-1]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column entry number %D (actual colum %D) in row %D is not sorted",jj-i[ii],j[jj],ii); 3758e32f2f54SBarry Smith if (j[jj] == j[jj]-1) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column entry number %D (actual colum %D) in row %D is identical to previous entry",jj-i[ii],j[jj],ii); 37599985e31cSBarry Smith } 376036db0b34SBarry Smith #endif 376136db0b34SBarry Smith } 37622515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 376336db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 3764e32f2f54SBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]); 3765e32f2f54SBarry Smith if (j[ii] > n - 1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column index to large at location = %d index = %d",ii,j[ii]); 376636db0b34SBarry Smith } 376736db0b34SBarry Smith #endif 376836db0b34SBarry Smith 3769b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3770b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 377136db0b34SBarry Smith PetscFunctionReturn(0); 377236db0b34SBarry Smith } 377336db0b34SBarry Smith 3774cc8ba8e1SBarry Smith #undef __FUNCT__ 3775ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ" 3776dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring) 3777cc8ba8e1SBarry Smith { 3778dfbe8321SBarry Smith PetscErrorCode ierr; 3779cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 378036db0b34SBarry Smith 3781cc8ba8e1SBarry Smith PetscFunctionBegin; 37828ee2e534SBarry Smith if (coloring->ctype == IS_COLORING_GLOBAL) { 3783cc8ba8e1SBarry Smith ierr = ISColoringReference(coloring);CHKERRQ(ierr); 3784cc8ba8e1SBarry Smith a->coloring = coloring; 378512c595b3SBarry Smith } else if (coloring->ctype == IS_COLORING_GHOSTED) { 378697f1f81fSBarry Smith PetscInt i,*larray; 378712c595b3SBarry Smith ISColoring ocoloring; 378808b6dcc0SBarry Smith ISColoringValue *colors; 378912c595b3SBarry Smith 379012c595b3SBarry Smith /* set coloring for diagonal portion */ 37910e83c824SBarry Smith ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr); 3792d0f46423SBarry Smith for (i=0; i<A->cmap->n; i++) { 379312c595b3SBarry Smith larray[i] = i; 379412c595b3SBarry Smith } 3795784ac674SJed Brown ierr = ISGlobalToLocalMappingApply(A->cmapping,IS_GTOLM_MASK,A->cmap->n,larray,PETSC_NULL,larray);CHKERRQ(ierr); 37960e83c824SBarry Smith ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); 3797d0f46423SBarry Smith for (i=0; i<A->cmap->n; i++) { 379812c595b3SBarry Smith colors[i] = coloring->colors[larray[i]]; 379912c595b3SBarry Smith } 380012c595b3SBarry Smith ierr = PetscFree(larray);CHKERRQ(ierr); 3801d0f46423SBarry Smith ierr = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr); 380212c595b3SBarry Smith a->coloring = ocoloring; 380312c595b3SBarry Smith } 3804cc8ba8e1SBarry Smith PetscFunctionReturn(0); 3805cc8ba8e1SBarry Smith } 3806cc8ba8e1SBarry Smith 3807dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC) 3808ee4f033dSBarry Smith EXTERN_C_BEGIN 380929c1e371SBarry Smith #include "adic/ad_utils.h" 3810ee4f033dSBarry Smith EXTERN_C_END 3811cc8ba8e1SBarry Smith 3812cc8ba8e1SBarry Smith #undef __FUNCT__ 3813ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ" 3814dfbe8321SBarry Smith PetscErrorCode MatSetValuesAdic_SeqAIJ(Mat A,void *advalues) 3815cc8ba8e1SBarry Smith { 3816cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3817d0f46423SBarry Smith PetscInt m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j,nlen; 38184440f671SBarry Smith PetscScalar *v = a->a,*values = ((PetscScalar*)advalues)+1; 381908b6dcc0SBarry Smith ISColoringValue *color; 3820cc8ba8e1SBarry Smith 3821cc8ba8e1SBarry Smith PetscFunctionBegin; 3822e32f2f54SBarry Smith if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix"); 38234440f671SBarry Smith nlen = PetscADGetDerivTypeSize()/sizeof(PetscScalar); 3824cc8ba8e1SBarry Smith color = a->coloring->colors; 3825cc8ba8e1SBarry Smith /* loop over rows */ 3826cc8ba8e1SBarry Smith for (i=0; i<m; i++) { 3827cc8ba8e1SBarry Smith nz = ii[i+1] - ii[i]; 3828cc8ba8e1SBarry Smith /* loop over columns putting computed value into matrix */ 3829cc8ba8e1SBarry Smith for (j=0; j<nz; j++) { 3830cc8ba8e1SBarry Smith *v++ = values[color[*jj++]]; 3831cc8ba8e1SBarry Smith } 38324440f671SBarry Smith values += nlen; /* jump to next row of derivatives */ 3833ee4f033dSBarry Smith } 3834ee4f033dSBarry Smith PetscFunctionReturn(0); 3835ee4f033dSBarry Smith } 3836ee4f033dSBarry Smith #endif 3837ee4f033dSBarry Smith 3838ee4f033dSBarry Smith #undef __FUNCT__ 3839ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ" 384097f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues) 3841ee4f033dSBarry Smith { 3842ee4f033dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3843d0f46423SBarry Smith PetscInt m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j; 384454f21887SBarry Smith MatScalar *v = a->a; 384554f21887SBarry Smith PetscScalar *values = (PetscScalar *)advalues; 384608b6dcc0SBarry Smith ISColoringValue *color; 3847ee4f033dSBarry Smith 3848ee4f033dSBarry Smith PetscFunctionBegin; 3849e32f2f54SBarry Smith if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix"); 3850ee4f033dSBarry Smith color = a->coloring->colors; 3851ee4f033dSBarry Smith /* loop over rows */ 3852ee4f033dSBarry Smith for (i=0; i<m; i++) { 3853ee4f033dSBarry Smith nz = ii[i+1] - ii[i]; 3854ee4f033dSBarry Smith /* loop over columns putting computed value into matrix */ 3855ee4f033dSBarry Smith for (j=0; j<nz; j++) { 3856ee4f033dSBarry Smith *v++ = values[color[*jj++]]; 3857ee4f033dSBarry Smith } 3858ee4f033dSBarry Smith values += nl; /* jump to next row of derivatives */ 3859cc8ba8e1SBarry Smith } 3860cc8ba8e1SBarry Smith PetscFunctionReturn(0); 3861cc8ba8e1SBarry Smith } 386236db0b34SBarry Smith 386381824310SBarry Smith /* 386481824310SBarry Smith Special version for direct calls from Fortran 386581824310SBarry Smith */ 38667087cfbeSBarry Smith #include "private/fortranimpl.h" 386781824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 386881824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 386981824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 387081824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 387181824310SBarry Smith #endif 387281824310SBarry Smith 387381824310SBarry Smith /* Change these macros so can be used in void function */ 387481824310SBarry Smith #undef CHKERRQ 38757adad957SLisandro Dalcin #define CHKERRQ(ierr) CHKERRABORT(((PetscObject)A)->comm,ierr) 387681824310SBarry Smith #undef SETERRQ2 3877e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 387881824310SBarry Smith 387981824310SBarry Smith EXTERN_C_BEGIN 388081824310SBarry Smith #undef __FUNCT__ 388181824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_" 38821f6cc5b2SSatish Balay void PETSC_STDCALL matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr) 388381824310SBarry Smith { 388481824310SBarry Smith Mat A = *AA; 388581824310SBarry Smith PetscInt m = *mm, n = *nn; 388681824310SBarry Smith InsertMode is = *isis; 388781824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 388881824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 388981824310SBarry Smith PetscInt *imax,*ai,*ailen; 389081824310SBarry Smith PetscErrorCode ierr; 389181824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 389254f21887SBarry Smith MatScalar *ap,value,*aa; 3893ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 3894ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 389581824310SBarry Smith 389681824310SBarry Smith PetscFunctionBegin; 3897d9e2c085SLisandro Dalcin ierr = MatPreallocated(A);CHKERRQ(ierr); 389881824310SBarry Smith imax = a->imax; 389981824310SBarry Smith ai = a->i; 390081824310SBarry Smith ailen = a->ilen; 390181824310SBarry Smith aj = a->j; 390281824310SBarry Smith aa = a->a; 390381824310SBarry Smith 390481824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 390581824310SBarry Smith row = im[k]; 390681824310SBarry Smith if (row < 0) continue; 390781824310SBarry Smith #if defined(PETSC_USE_DEBUG) 3908d0f46423SBarry Smith if (row >= A->rmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 390981824310SBarry Smith #endif 391081824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 391181824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 391281824310SBarry Smith low = 0; 391381824310SBarry Smith high = nrow; 391481824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 391581824310SBarry Smith if (in[l] < 0) continue; 391681824310SBarry Smith #if defined(PETSC_USE_DEBUG) 3917d0f46423SBarry Smith if (in[l] >= A->cmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 391881824310SBarry Smith #endif 391981824310SBarry Smith col = in[l]; 392081824310SBarry Smith if (roworiented) { 392181824310SBarry Smith value = v[l + k*n]; 392281824310SBarry Smith } else { 392381824310SBarry Smith value = v[k + l*m]; 392481824310SBarry Smith } 392581824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 392681824310SBarry Smith 392781824310SBarry Smith if (col <= lastcol) low = 0; else high = nrow; 392881824310SBarry Smith lastcol = col; 392981824310SBarry Smith while (high-low > 5) { 393081824310SBarry Smith t = (low+high)/2; 393181824310SBarry Smith if (rp[t] > col) high = t; 393281824310SBarry Smith else low = t; 393381824310SBarry Smith } 393481824310SBarry Smith for (i=low; i<high; i++) { 393581824310SBarry Smith if (rp[i] > col) break; 393681824310SBarry Smith if (rp[i] == col) { 393781824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 393881824310SBarry Smith else ap[i] = value; 393981824310SBarry Smith goto noinsert; 394081824310SBarry Smith } 394181824310SBarry Smith } 394281824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 394381824310SBarry Smith if (nonew == 1) goto noinsert; 39447adad957SLisandro Dalcin if (nonew == -1) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 3945fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 394681824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 394781824310SBarry Smith /* shift up all the later entries in this row */ 394881824310SBarry Smith for (ii=N; ii>=i; ii--) { 394981824310SBarry Smith rp[ii+1] = rp[ii]; 395081824310SBarry Smith ap[ii+1] = ap[ii]; 395181824310SBarry Smith } 395281824310SBarry Smith rp[i] = col; 395381824310SBarry Smith ap[i] = value; 395481824310SBarry Smith noinsert:; 395581824310SBarry Smith low = i + 1; 395681824310SBarry Smith } 395781824310SBarry Smith ailen[row] = nrow; 395881824310SBarry Smith } 395981824310SBarry Smith A->same_nonzero = PETSC_FALSE; 396081824310SBarry Smith PetscFunctionReturnVoid(); 396181824310SBarry Smith } 396281824310SBarry Smith EXTERN_C_END 3963*62298a1eSBarry Smith 3964*62298a1eSBarry Smith #undef __FUNCT__ 3965*62298a1eSBarry Smith #define __FUNCT__ "MatSeqAIJFindZeroRows" 3966*62298a1eSBarry Smith /*@C 3967*62298a1eSBarry Smith MatSeqAIJFindZeroRows - Locate all rows that are not completely zero in the matrix 3968*62298a1eSBarry Smith 3969*62298a1eSBarry Smith Input Parameter: 3970*62298a1eSBarry Smith . A - the matrix 3971*62298a1eSBarry Smith 3972*62298a1eSBarry Smith Output Parameter: 3973*62298a1eSBarry Smith . keptrows - the rows that are not completely zero 3974*62298a1eSBarry Smith 3975*62298a1eSBarry Smith @*/ 3976*62298a1eSBarry Smith PetscErrorCode MatSeqAIJFindZeroRows(Mat A,IS *keptrows) 3977*62298a1eSBarry Smith { 3978*62298a1eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3979*62298a1eSBarry Smith const MatScalar *aa; 3980*62298a1eSBarry Smith PetscInt m=A->rmap->n,cnt = 0; 3981*62298a1eSBarry Smith const PetscInt *ii; 3982*62298a1eSBarry Smith PetscInt n,i,j,*rows; 3983*62298a1eSBarry Smith PetscErrorCode ierr; 3984*62298a1eSBarry Smith 3985*62298a1eSBarry Smith PetscFunctionBegin; 3986*62298a1eSBarry Smith *keptrows = 0; 3987*62298a1eSBarry Smith ii = a->i; 3988*62298a1eSBarry Smith for (i=0; i<m; i++) { 3989*62298a1eSBarry Smith n = ii[i+1] - ii[i]; 3990*62298a1eSBarry Smith if (!n) { 3991*62298a1eSBarry Smith cnt++; 3992*62298a1eSBarry Smith goto ok1; 3993*62298a1eSBarry Smith } 3994*62298a1eSBarry Smith aa = a->a + ii[i]; 3995*62298a1eSBarry Smith for (j=0; j<n; j++) { 3996*62298a1eSBarry Smith if (aa[j] != 0.0) goto ok1; 3997*62298a1eSBarry Smith } 3998*62298a1eSBarry Smith cnt++; 3999*62298a1eSBarry Smith ok1:; 4000*62298a1eSBarry Smith } 4001*62298a1eSBarry Smith if (!cnt) PetscFunctionReturn(0); 4002*62298a1eSBarry Smith ierr = PetscMalloc((A->rmap->n-cnt)*sizeof(PetscInt),&rows);CHKERRQ(ierr); 4003*62298a1eSBarry Smith cnt = 0; 4004*62298a1eSBarry Smith for (i=0; i<m; i++) { 4005*62298a1eSBarry Smith n = ii[i+1] - ii[i]; 4006*62298a1eSBarry Smith if (!n) continue; 4007*62298a1eSBarry Smith aa = a->a + ii[i]; 4008*62298a1eSBarry Smith for (j=0; j<n; j++) { 4009*62298a1eSBarry Smith if (aa[j] != 0.0) { 4010*62298a1eSBarry Smith rows[cnt++] = i; 4011*62298a1eSBarry Smith break; 4012*62298a1eSBarry Smith } 4013*62298a1eSBarry Smith } 4014*62298a1eSBarry Smith } 4015*62298a1eSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr); 4016*62298a1eSBarry Smith PetscFunctionReturn(0); 4017*62298a1eSBarry Smith } 4018