1be1d678aSKris Buschelman #define PETSCMAT_DLL 2b3cc6726SBarry Smith 3d5d45c9bSBarry Smith /* 43369ce9aSBarry Smith Defines the basic matrix operations for the AIJ (compressed row) 5d5d45c9bSBarry Smith matrix storage format. 6d5d45c9bSBarry Smith */ 73369ce9aSBarry Smith 89e070d67SMatthew Knepley #include "src/mat/impls/aij/seq/aij.h" /*I "petscmat.h" I*/ 9f5eb4b81SSatish Balay #include "src/inline/spops.h" 108d195f9aSBarry Smith #include "src/inline/dot.h" 110a835dfdSSatish Balay #include "petscbt.h" 1217ab2063SBarry Smith 134a2ae208SSatish Balay #undef __FUNCT__ 1479299369SBarry Smith #define __FUNCT__ "MatDiagonalSet_SeqAIJ" 1579299369SBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is) 1679299369SBarry Smith { 1779299369SBarry Smith PetscErrorCode ierr; 1879299369SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) Y->data; 19899cda47SBarry Smith PetscInt i,*diag, m = Y->rmap.n; 2079299369SBarry Smith PetscScalar *v,*aa = aij->a; 2109f38230SBarry Smith PetscTruth missing; 2279299369SBarry Smith 2379299369SBarry Smith PetscFunctionBegin; 2409f38230SBarry Smith if (Y->assembled) { 2509f38230SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,PETSC_NULL);CHKERRQ(ierr); 2609f38230SBarry Smith if (!missing) { 2779299369SBarry Smith diag = aij->diag; 2879299369SBarry Smith ierr = VecGetArray(D,&v);CHKERRQ(ierr); 2979299369SBarry Smith if (is == INSERT_VALUES) { 3079299369SBarry Smith for (i=0; i<m; i++) { 3179299369SBarry Smith aa[diag[i]] = v[i]; 3279299369SBarry Smith } 3379299369SBarry Smith } else { 3479299369SBarry Smith for (i=0; i<m; i++) { 3579299369SBarry Smith aa[diag[i]] += v[i]; 3679299369SBarry Smith } 3779299369SBarry Smith } 3879299369SBarry Smith ierr = VecRestoreArray(D,&v);CHKERRQ(ierr); 3979299369SBarry Smith PetscFunctionReturn(0); 4079299369SBarry Smith } 4109f38230SBarry Smith } 4209f38230SBarry Smith ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr); 4309f38230SBarry Smith PetscFunctionReturn(0); 4409f38230SBarry Smith } 4579299369SBarry Smith 4679299369SBarry Smith #undef __FUNCT__ 474a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ" 488f7157efSSatish Balay PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *m,PetscInt *ia[],PetscInt *ja[],PetscTruth *done) 4917ab2063SBarry Smith { 50416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 51dfbe8321SBarry Smith PetscErrorCode ierr; 5297f1f81fSBarry Smith PetscInt i,ishift; 5317ab2063SBarry Smith 543a40ed3dSBarry Smith PetscFunctionBegin; 55899cda47SBarry Smith *m = A->rmap.n; 563a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 57bfeeae90SHong Zhang ishift = 0; 5853e63a63SBarry Smith if (symmetric && !A->structurally_symmetric) { 59899cda47SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(A->rmap.n,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr); 60bfeeae90SHong Zhang } else if (oshift == 1) { 61899cda47SBarry Smith PetscInt nz = a->i[A->rmap.n]; 623b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 63899cda47SBarry Smith ierr = PetscMalloc((A->rmap.n+1)*sizeof(PetscInt),ia);CHKERRQ(ierr); 6497f1f81fSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscInt),ja);CHKERRQ(ierr); 653b2fbd54SBarry Smith for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1; 66899cda47SBarry Smith for (i=0; i<A->rmap.n+1; i++) (*ia)[i] = a->i[i] + 1; 676945ee14SBarry Smith } else { 686945ee14SBarry Smith *ia = a->i; *ja = a->j; 69a2ce50c7SBarry Smith } 703a40ed3dSBarry Smith PetscFunctionReturn(0); 71a2744918SBarry Smith } 72a2744918SBarry Smith 734a2ae208SSatish Balay #undef __FUNCT__ 744a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ" 758f7157efSSatish Balay PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscTruth *done) 766945ee14SBarry Smith { 77dfbe8321SBarry Smith PetscErrorCode ierr; 786945ee14SBarry Smith 793a40ed3dSBarry Smith PetscFunctionBegin; 803a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 81bfeeae90SHong Zhang if ((symmetric && !A->structurally_symmetric) || oshift == 1) { 82606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 83606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 84bcd2baecSBarry Smith } 853a40ed3dSBarry Smith PetscFunctionReturn(0); 8617ab2063SBarry Smith } 8717ab2063SBarry Smith 884a2ae208SSatish Balay #undef __FUNCT__ 894a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ" 908f7157efSSatish Balay PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *nn,PetscInt *ia[],PetscInt *ja[],PetscTruth *done) 913b2fbd54SBarry Smith { 923b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 93dfbe8321SBarry Smith PetscErrorCode ierr; 94899cda47SBarry Smith PetscInt i,*collengths,*cia,*cja,n = A->cmap.n,m = A->rmap.n; 9597f1f81fSBarry Smith PetscInt nz = a->i[m],row,*jj,mr,col; 963b2fbd54SBarry Smith 973a40ed3dSBarry Smith PetscFunctionBegin; 98899cda47SBarry Smith *nn = n; 993a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 1003b2fbd54SBarry Smith if (symmetric) { 101899cda47SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(A->rmap.n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr); 1023b2fbd54SBarry Smith } else { 10397f1f81fSBarry Smith ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr); 10497f1f81fSBarry Smith ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 10597f1f81fSBarry Smith ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr); 10697f1f81fSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr); 1073b2fbd54SBarry Smith jj = a->j; 1083b2fbd54SBarry Smith for (i=0; i<nz; i++) { 109bfeeae90SHong Zhang collengths[jj[i]]++; 1103b2fbd54SBarry Smith } 1113b2fbd54SBarry Smith cia[0] = oshift; 1123b2fbd54SBarry Smith for (i=0; i<n; i++) { 1133b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 1143b2fbd54SBarry Smith } 11597f1f81fSBarry Smith ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 1163b2fbd54SBarry Smith jj = a->j; 117a93ec695SBarry Smith for (row=0; row<m; row++) { 118a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 119a93ec695SBarry Smith for (i=0; i<mr; i++) { 120bfeeae90SHong Zhang col = *jj++; 1213b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 1223b2fbd54SBarry Smith } 1233b2fbd54SBarry Smith } 124606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 1253b2fbd54SBarry Smith *ia = cia; *ja = cja; 1263b2fbd54SBarry Smith } 1273a40ed3dSBarry Smith PetscFunctionReturn(0); 1283b2fbd54SBarry Smith } 1293b2fbd54SBarry Smith 1304a2ae208SSatish Balay #undef __FUNCT__ 1314a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ" 1328f7157efSSatish Balay PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscTruth *done) 1333b2fbd54SBarry Smith { 134dfbe8321SBarry Smith PetscErrorCode ierr; 135606d414cSSatish Balay 1363a40ed3dSBarry Smith PetscFunctionBegin; 1373a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 1383b2fbd54SBarry Smith 139606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 140606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 1413b2fbd54SBarry Smith 1423a40ed3dSBarry Smith PetscFunctionReturn(0); 1433b2fbd54SBarry Smith } 1443b2fbd54SBarry Smith 14587d4246cSBarry Smith #undef __FUNCT__ 14687d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ" 14787d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[]) 14887d4246cSBarry Smith { 14987d4246cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 15087d4246cSBarry Smith PetscInt *ai = a->i; 15187d4246cSBarry Smith PetscErrorCode ierr; 15287d4246cSBarry Smith 15387d4246cSBarry Smith PetscFunctionBegin; 15487d4246cSBarry Smith ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr); 15587d4246cSBarry Smith PetscFunctionReturn(0); 15687d4246cSBarry Smith } 15787d4246cSBarry Smith 158227d817aSBarry Smith #define CHUNKSIZE 15 15917ab2063SBarry Smith 1604a2ae208SSatish Balay #undef __FUNCT__ 1614a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ" 16297f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 16317ab2063SBarry Smith { 164416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 165e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 16697f1f81fSBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 1676849ba73SBarry Smith PetscErrorCode ierr; 168e2ee6c50SBarry Smith PetscInt *aj = a->j,nonew = a->nonew,lastcol = -1; 16987828ca2SBarry Smith PetscScalar *ap,value,*aa = a->a; 170edb03aefSBarry Smith PetscTruth ignorezeroentries = a->ignorezeroentries; 171273d9f13SBarry Smith PetscTruth roworiented = a->roworiented; 17217ab2063SBarry Smith 1733a40ed3dSBarry Smith PetscFunctionBegin; 17417ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 175416022c9SBarry Smith row = im[k]; 1765ef9f2a5SBarry Smith if (row < 0) continue; 1772515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 178899cda47SBarry Smith if (row >= A->rmap.n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap.n-1); 1793b2fbd54SBarry Smith #endif 180bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 18117ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 182416022c9SBarry Smith low = 0; 183c71e6ed7SBarry Smith high = nrow; 18417ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 1855ef9f2a5SBarry Smith if (in[l] < 0) continue; 1862515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 187899cda47SBarry Smith if (in[l] >= A->cmap.n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->cmap.n-1); 1883b2fbd54SBarry Smith #endif 189bfeeae90SHong Zhang col = in[l]; 1904b0e389bSBarry Smith if (roworiented) { 1915ef9f2a5SBarry Smith value = v[l + k*n]; 192bef8e0ddSBarry Smith } else { 1934b0e389bSBarry Smith value = v[k + l*m]; 1944b0e389bSBarry Smith } 195abc0a331SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 19636db0b34SBarry Smith 1977cd84e04SBarry Smith if (col <= lastcol) low = 0; else high = nrow; 198e2ee6c50SBarry Smith lastcol = col; 199416022c9SBarry Smith while (high-low > 5) { 200416022c9SBarry Smith t = (low+high)/2; 201416022c9SBarry Smith if (rp[t] > col) high = t; 202416022c9SBarry Smith else low = t; 20317ab2063SBarry Smith } 204416022c9SBarry Smith for (i=low; i<high; i++) { 20517ab2063SBarry Smith if (rp[i] > col) break; 20617ab2063SBarry Smith if (rp[i] == col) { 207416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 20817ab2063SBarry Smith else ap[i] = value; 20917ab2063SBarry Smith goto noinsert; 21017ab2063SBarry Smith } 21117ab2063SBarry Smith } 212abc0a331SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 213c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 214cc72174dSBarry Smith if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 215421e10b8SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap.n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 216c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 217416022c9SBarry Smith /* shift up all the later entries in this row */ 218416022c9SBarry Smith for (ii=N; ii>=i; ii--) { 21917ab2063SBarry Smith rp[ii+1] = rp[ii]; 22017ab2063SBarry Smith ap[ii+1] = ap[ii]; 22117ab2063SBarry Smith } 22217ab2063SBarry Smith rp[i] = col; 22317ab2063SBarry Smith ap[i] = value; 22417ab2063SBarry Smith noinsert:; 225416022c9SBarry Smith low = i + 1; 22617ab2063SBarry Smith } 22717ab2063SBarry Smith ailen[row] = nrow; 22817ab2063SBarry Smith } 22988e51ccdSHong Zhang A->same_nonzero = PETSC_FALSE; 2303a40ed3dSBarry Smith PetscFunctionReturn(0); 23117ab2063SBarry Smith } 23217ab2063SBarry Smith 23381824310SBarry Smith 2344a2ae208SSatish Balay #undef __FUNCT__ 2354a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ" 23697f1f81fSBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 2377eb43aa7SLois Curfman McInnes { 2387eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 23997f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 24097f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 24197e567efSBarry Smith PetscScalar *ap,*aa = a->a; 2427eb43aa7SLois Curfman McInnes 2433a40ed3dSBarry Smith PetscFunctionBegin; 2447eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 2457eb43aa7SLois Curfman McInnes row = im[k]; 24697e567efSBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 247899cda47SBarry Smith if (row >= A->rmap.n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap.n-1); 248bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 2497eb43aa7SLois Curfman McInnes nrow = ailen[row]; 2507eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 25197e567efSBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 252899cda47SBarry Smith if (in[l] >= A->cmap.n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->cmap.n-1); 253bfeeae90SHong Zhang col = in[l] ; 2547eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 2557eb43aa7SLois Curfman McInnes while (high-low > 5) { 2567eb43aa7SLois Curfman McInnes t = (low+high)/2; 2577eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 2587eb43aa7SLois Curfman McInnes else low = t; 2597eb43aa7SLois Curfman McInnes } 2607eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 2617eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 2627eb43aa7SLois Curfman McInnes if (rp[i] == col) { 263b49de8d1SLois Curfman McInnes *v++ = ap[i]; 2647eb43aa7SLois Curfman McInnes goto finished; 2657eb43aa7SLois Curfman McInnes } 2667eb43aa7SLois Curfman McInnes } 26797e567efSBarry Smith *v++ = 0.0; 2687eb43aa7SLois Curfman McInnes finished:; 2697eb43aa7SLois Curfman McInnes } 2707eb43aa7SLois Curfman McInnes } 2713a40ed3dSBarry Smith PetscFunctionReturn(0); 2727eb43aa7SLois Curfman McInnes } 2737eb43aa7SLois Curfman McInnes 27417ab2063SBarry Smith 2754a2ae208SSatish Balay #undef __FUNCT__ 2764a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary" 277dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer) 27817ab2063SBarry Smith { 279416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2806849ba73SBarry Smith PetscErrorCode ierr; 2816f69ff64SBarry Smith PetscInt i,*col_lens; 2826f69ff64SBarry Smith int fd; 28317ab2063SBarry Smith 2843a40ed3dSBarry Smith PetscFunctionBegin; 285b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 286899cda47SBarry Smith ierr = PetscMalloc((4+A->rmap.n)*sizeof(PetscInt),&col_lens);CHKERRQ(ierr); 287552e946dSBarry Smith col_lens[0] = MAT_FILE_COOKIE; 288899cda47SBarry Smith col_lens[1] = A->rmap.n; 289899cda47SBarry Smith col_lens[2] = A->cmap.n; 290416022c9SBarry Smith col_lens[3] = a->nz; 291416022c9SBarry Smith 292416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 293899cda47SBarry Smith for (i=0; i<A->rmap.n; i++) { 294416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 29517ab2063SBarry Smith } 296899cda47SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap.n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 297606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 298416022c9SBarry Smith 299416022c9SBarry Smith /* store column indices (zero start index) */ 3006f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 301416022c9SBarry Smith 302416022c9SBarry Smith /* store nonzero values */ 3036f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 3043a40ed3dSBarry Smith PetscFunctionReturn(0); 30517ab2063SBarry Smith } 306416022c9SBarry Smith 307dfbe8321SBarry Smith EXTERN PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 308cd155464SBarry Smith 3094a2ae208SSatish Balay #undef __FUNCT__ 3104a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII" 311dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 312416022c9SBarry Smith { 313416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 314dfbe8321SBarry Smith PetscErrorCode ierr; 315899cda47SBarry Smith PetscInt i,j,m = A->rmap.n,shift=0; 316e060cb09SBarry Smith const char *name; 317f3ef73ceSBarry Smith PetscViewerFormat format; 31817ab2063SBarry Smith 3193a40ed3dSBarry Smith PetscFunctionBegin; 320435da068SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 321b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 32271c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 32397f1f81fSBarry Smith PetscInt nofinalvalue = 0; 324899cda47SBarry Smith if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap.n-!shift)) { 325d00d2cf4SBarry Smith nofinalvalue = 1; 326d00d2cf4SBarry Smith } 327b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 328899cda47SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap.n);CHKERRQ(ierr); 32977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 33077431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 331b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 33217ab2063SBarry Smith 33317ab2063SBarry Smith for (i=0; i<m; i++) { 334416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 335aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 33677431f27SBarry 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); 33717ab2063SBarry Smith #else 33877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr); 33917ab2063SBarry Smith #endif 34017ab2063SBarry Smith } 34117ab2063SBarry Smith } 342d00d2cf4SBarry Smith if (nofinalvalue) { 343899cda47SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap.n,0.0);CHKERRQ(ierr); 344d00d2cf4SBarry Smith } 345fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 346b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 34768369a75SKris Buschelman } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) { 348cd155464SBarry Smith PetscFunctionReturn(0); 349fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 350b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 35144cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 35277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 35344cd7ae7SLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 354aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 35536db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 356a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 35736db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 358a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 35936db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 360a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 3616831982aSBarry Smith } 36244cd7ae7SLois Curfman McInnes #else 363a83599f4SBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);} 36444cd7ae7SLois Curfman McInnes #endif 36544cd7ae7SLois Curfman McInnes } 366b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 36744cd7ae7SLois Curfman McInnes } 368b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 369fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 37097f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 371b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 37297f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&sptr);CHKERRQ(ierr); 373496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 374496be53dSLois Curfman McInnes sptr[i] = nzd+1; 375496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 376496be53dSLois Curfman McInnes if (a->j[j] >= i) { 377aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 37836db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 379496be53dSLois Curfman McInnes #else 380496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 381496be53dSLois Curfman McInnes #endif 382496be53dSLois Curfman McInnes } 383496be53dSLois Curfman McInnes } 384496be53dSLois Curfman McInnes } 3852e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 38677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 3872e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 38877431f27SBarry 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);} 38977431f27SBarry 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);} 39077431f27SBarry 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);} 39177431f27SBarry Smith else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);} 39277431f27SBarry Smith else if (i<m) {ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);} 39377431f27SBarry Smith else {ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);} 394496be53dSLois Curfman McInnes } 395b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 396606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 397496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 398496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 39977431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 400496be53dSLois Curfman McInnes } 401b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 402496be53dSLois Curfman McInnes } 403b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 404496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 405496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 406496be53dSLois Curfman McInnes if (a->j[j] >= i) { 407aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 40836db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 409b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 4106831982aSBarry Smith } 411496be53dSLois Curfman McInnes #else 412b0a32e0cSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);} 413496be53dSLois Curfman McInnes #endif 414496be53dSLois Curfman McInnes } 415496be53dSLois Curfman McInnes } 416b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 417496be53dSLois Curfman McInnes } 418b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 419fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 42097f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 42187828ca2SBarry Smith PetscScalar value; 42202594712SBarry Smith 423b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 42402594712SBarry Smith for (i=0; i<m; i++) { 42502594712SBarry Smith jcnt = 0; 426899cda47SBarry Smith for (j=0; j<A->cmap.n; j++) { 427e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 42802594712SBarry Smith value = a->a[cnt++]; 429e24b481bSBarry Smith jcnt++; 43002594712SBarry Smith } else { 43102594712SBarry Smith value = 0.0; 43202594712SBarry Smith } 433aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 434b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr); 43502594712SBarry Smith #else 436b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr); 43702594712SBarry Smith #endif 43802594712SBarry Smith } 439b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 44002594712SBarry Smith } 441b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 4423a40ed3dSBarry Smith } else { 443b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 44417ab2063SBarry Smith for (i=0; i<m; i++) { 44577431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 446416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 447aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 44836db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 449a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 45036db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 451a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 4523a40ed3dSBarry Smith } else { 453a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 45417ab2063SBarry Smith } 45517ab2063SBarry Smith #else 456a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 45717ab2063SBarry Smith #endif 45817ab2063SBarry Smith } 459b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 46017ab2063SBarry Smith } 461b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 46217ab2063SBarry Smith } 463b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 4643a40ed3dSBarry Smith PetscFunctionReturn(0); 465416022c9SBarry Smith } 466416022c9SBarry Smith 4674a2ae208SSatish Balay #undef __FUNCT__ 4684a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom" 469dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 470416022c9SBarry Smith { 471480ef9eaSBarry Smith Mat A = (Mat) Aa; 472416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 473dfbe8321SBarry Smith PetscErrorCode ierr; 474899cda47SBarry Smith PetscInt i,j,m = A->rmap.n,color; 47536db0b34SBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0; 476b0a32e0cSBarry Smith PetscViewer viewer; 477f3ef73ceSBarry Smith PetscViewerFormat format; 478cddf8d76SBarry Smith 4793a40ed3dSBarry Smith PetscFunctionBegin; 480480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 481b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 48219bcc07fSBarry Smith 483b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 484416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 4850513a670SBarry Smith 486fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 4870513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 488b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 489416022c9SBarry Smith for (i=0; i<m; i++) { 490cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 491bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 492bfeeae90SHong Zhang x_l = a->j[j] ; x_r = x_l + 1.0; 493aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 49436db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 495cddf8d76SBarry Smith #else 496cddf8d76SBarry Smith if (a->a[j] >= 0.) continue; 497cddf8d76SBarry Smith #endif 498b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 499cddf8d76SBarry Smith } 500cddf8d76SBarry Smith } 501b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 502cddf8d76SBarry Smith for (i=0; i<m; i++) { 503cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 504bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 505bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 506cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 507b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 508cddf8d76SBarry Smith } 509cddf8d76SBarry Smith } 510b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 511cddf8d76SBarry Smith for (i=0; i<m; i++) { 512cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 513bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 514bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 515aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 51636db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 517cddf8d76SBarry Smith #else 518cddf8d76SBarry Smith if (a->a[j] <= 0.) continue; 519cddf8d76SBarry Smith #endif 520b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 521416022c9SBarry Smith } 522416022c9SBarry Smith } 5230513a670SBarry Smith } else { 5240513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 5250513a670SBarry Smith /* first determine max of all nonzero values */ 52697f1f81fSBarry Smith PetscInt nz = a->nz,count; 527b0a32e0cSBarry Smith PetscDraw popup; 52836db0b34SBarry Smith PetscReal scale; 5290513a670SBarry Smith 5300513a670SBarry Smith for (i=0; i<nz; i++) { 5310513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 5320513a670SBarry Smith } 533b0a32e0cSBarry Smith scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv; 534b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 535b0a32e0cSBarry Smith if (popup) {ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);} 5360513a670SBarry Smith count = 0; 5370513a670SBarry Smith for (i=0; i<m; i++) { 5380513a670SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 539bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 540bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 54197f1f81fSBarry Smith color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count])); 542b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 5430513a670SBarry Smith count++; 5440513a670SBarry Smith } 5450513a670SBarry Smith } 5460513a670SBarry Smith } 547480ef9eaSBarry Smith PetscFunctionReturn(0); 548480ef9eaSBarry Smith } 549cddf8d76SBarry Smith 5504a2ae208SSatish Balay #undef __FUNCT__ 5514a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw" 552dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 553480ef9eaSBarry Smith { 554dfbe8321SBarry Smith PetscErrorCode ierr; 555b0a32e0cSBarry Smith PetscDraw draw; 55636db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 557480ef9eaSBarry Smith PetscTruth isnull; 558480ef9eaSBarry Smith 559480ef9eaSBarry Smith PetscFunctionBegin; 560b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 561b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 562480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 563480ef9eaSBarry Smith 564480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 565899cda47SBarry Smith xr = A->cmap.n; yr = A->rmap.n; h = yr/10.0; w = xr/10.0; 566480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 567b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 568b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 569480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 5703a40ed3dSBarry Smith PetscFunctionReturn(0); 571416022c9SBarry Smith } 572416022c9SBarry Smith 5734a2ae208SSatish Balay #undef __FUNCT__ 5744a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ" 575dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 576416022c9SBarry Smith { 577dfbe8321SBarry Smith PetscErrorCode ierr; 5786805f65bSBarry Smith PetscTruth iascii,isbinary,isdraw; 579416022c9SBarry Smith 5803a40ed3dSBarry Smith PetscFunctionBegin; 58132077d6dSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 582fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr); 583fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr); 584c45a1595SBarry Smith if (iascii) { 5853a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 5860f5bd95cSBarry Smith } else if (isbinary) { 5873a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 5880f5bd95cSBarry Smith } else if (isdraw) { 5893a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 5905cd90555SBarry Smith } else { 591958c9bccSBarry Smith SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name); 59217ab2063SBarry Smith } 5934846f1f5SKris Buschelman ierr = MatView_Inode(A,viewer);CHKERRQ(ierr); 5943a40ed3dSBarry Smith PetscFunctionReturn(0); 59517ab2063SBarry Smith } 59619bcc07fSBarry Smith 5974a2ae208SSatish Balay #undef __FUNCT__ 5984a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ" 599dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 60017ab2063SBarry Smith { 601416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 6026849ba73SBarry Smith PetscErrorCode ierr; 60397f1f81fSBarry Smith PetscInt fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 604899cda47SBarry Smith PetscInt m = A->rmap.n,*ip,N,*ailen = a->ilen,rmax = 0; 60587828ca2SBarry Smith PetscScalar *aa = a->a,*ap; 6063447b6efSHong Zhang PetscReal ratio=0.6; 60717ab2063SBarry Smith 6083a40ed3dSBarry Smith PetscFunctionBegin; 6093a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 61017ab2063SBarry Smith 61143ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 61217ab2063SBarry Smith for (i=1; i<m; i++) { 613416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 61417ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 61594a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 61617ab2063SBarry Smith if (fshift) { 617bfeeae90SHong Zhang ip = aj + ai[i] ; 618bfeeae90SHong Zhang ap = aa + ai[i] ; 61917ab2063SBarry Smith N = ailen[i]; 62017ab2063SBarry Smith for (j=0; j<N; j++) { 62117ab2063SBarry Smith ip[j-fshift] = ip[j]; 62217ab2063SBarry Smith ap[j-fshift] = ap[j]; 62317ab2063SBarry Smith } 62417ab2063SBarry Smith } 62517ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 62617ab2063SBarry Smith } 62717ab2063SBarry Smith if (m) { 62817ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 62917ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 63017ab2063SBarry Smith } 63117ab2063SBarry Smith /* reset ilen and imax for each row */ 63217ab2063SBarry Smith for (i=0; i<m; i++) { 63317ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 63417ab2063SBarry Smith } 635bfeeae90SHong Zhang a->nz = ai[m]; 63617ab2063SBarry Smith 63709f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 638899cda47SBarry 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); 639ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 640ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 641a0e1a203SBarry Smith 642dd5f02e7SSatish Balay a->reallocs = 0; 6434e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift; 64436db0b34SBarry Smith a->rmax = rmax; 6454e220ebcSLois Curfman McInnes 646cb5d8e9eSHong Zhang /* check for zero rows. If found a large number of zero rows, use CompressedRow functions */ 647317fbc4cSHong Zhang ierr = Mat_CheckCompressedRow(A,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 64888e51ccdSHong Zhang A->same_nonzero = PETSC_TRUE; 64971c2f376SKris Buschelman 6504846f1f5SKris Buschelman ierr = MatAssemblyEnd_Inode(A,mode);CHKERRQ(ierr); 6513a40ed3dSBarry Smith PetscFunctionReturn(0); 65217ab2063SBarry Smith } 65317ab2063SBarry Smith 6544a2ae208SSatish Balay #undef __FUNCT__ 65599cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ" 65699cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 65799cafbc1SBarry Smith { 65899cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 65999cafbc1SBarry Smith PetscInt i,nz = a->nz; 66099cafbc1SBarry Smith PetscScalar *aa = a->a; 66199cafbc1SBarry Smith 66299cafbc1SBarry Smith PetscFunctionBegin; 66399cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 66499cafbc1SBarry Smith PetscFunctionReturn(0); 66599cafbc1SBarry Smith } 66699cafbc1SBarry Smith 66799cafbc1SBarry Smith #undef __FUNCT__ 66899cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ" 66999cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 67099cafbc1SBarry Smith { 67199cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 67299cafbc1SBarry Smith PetscInt i,nz = a->nz; 67399cafbc1SBarry Smith PetscScalar *aa = a->a; 67499cafbc1SBarry Smith 67599cafbc1SBarry Smith PetscFunctionBegin; 67699cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 67799cafbc1SBarry Smith PetscFunctionReturn(0); 67899cafbc1SBarry Smith } 67999cafbc1SBarry Smith 68099cafbc1SBarry Smith #undef __FUNCT__ 6814a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ" 682dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 68317ab2063SBarry Smith { 684416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 685dfbe8321SBarry Smith PetscErrorCode ierr; 6863a40ed3dSBarry Smith 6873a40ed3dSBarry Smith PetscFunctionBegin; 688899cda47SBarry Smith ierr = PetscMemzero(a->a,(a->i[A->rmap.n])*sizeof(PetscScalar));CHKERRQ(ierr); 6893a40ed3dSBarry Smith PetscFunctionReturn(0); 69017ab2063SBarry Smith } 691416022c9SBarry Smith 6924a2ae208SSatish Balay #undef __FUNCT__ 6934a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ" 694dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 69517ab2063SBarry Smith { 696416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 697dfbe8321SBarry Smith PetscErrorCode ierr; 698d5d45c9bSBarry Smith 6993a40ed3dSBarry Smith PetscFunctionBegin; 700aa482453SBarry Smith #if defined(PETSC_USE_LOG) 701899cda47SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap.n,A->cmap.n,a->nz); 70217ab2063SBarry Smith #endif 703e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 704c38d4ed2SBarry Smith if (a->row) { 705c38d4ed2SBarry Smith ierr = ISDestroy(a->row);CHKERRQ(ierr); 706c38d4ed2SBarry Smith } 707c38d4ed2SBarry Smith if (a->col) { 708c38d4ed2SBarry Smith ierr = ISDestroy(a->col);CHKERRQ(ierr); 709c38d4ed2SBarry Smith } 71005b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 71105b42c5fSBarry Smith ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr); 71205b42c5fSBarry Smith ierr = PetscFree(a->idiag);CHKERRQ(ierr); 71305b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 71482bf6240SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 71505b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 716cc8ba8e1SBarry Smith if (a->coloring) {ierr = ISColoringDestroy(a->coloring);CHKERRQ(ierr);} 71705b42c5fSBarry Smith ierr = PetscFree(a->xtoy);CHKERRQ(ierr); 718407f6b05SHong Zhang if (a->XtoY) {ierr = MatDestroy(a->XtoY);CHKERRQ(ierr);} 719d487561eSHong Zhang if (a->compressedrow.use){ierr = PetscFree(a->compressedrow.i);} 720a30b2313SHong Zhang 7214846f1f5SKris Buschelman ierr = MatDestroy_Inode(A);CHKERRQ(ierr); 7224846f1f5SKris Buschelman 723606d414cSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 724901853e0SKris Buschelman 725dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 726901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetColumnIndices_C","",PETSC_NULL);CHKERRQ(ierr); 727901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatStoreValues_C","",PETSC_NULL);CHKERRQ(ierr); 728901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatRetrieveValues_C","",PETSC_NULL);CHKERRQ(ierr); 729901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqsbaij_C","",PETSC_NULL);CHKERRQ(ierr); 730901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqbaij_C","",PETSC_NULL);CHKERRQ(ierr); 731ba03775dSHong Zhang ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqcsrperm_C","",PETSC_NULL);CHKERRQ(ierr); 732901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatIsTranspose_C","",PETSC_NULL);CHKERRQ(ierr); 733901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocation_C","",PETSC_NULL);CHKERRQ(ierr); 734a1661176SMatthew Knepley ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C","",PETSC_NULL);CHKERRQ(ierr); 735901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatReorderForNonzeroDiagonal_C","",PETSC_NULL);CHKERRQ(ierr); 7363a40ed3dSBarry Smith PetscFunctionReturn(0); 73717ab2063SBarry Smith } 73817ab2063SBarry Smith 7394a2ae208SSatish Balay #undef __FUNCT__ 7404a2ae208SSatish Balay #define __FUNCT__ "MatCompress_SeqAIJ" 741dfbe8321SBarry Smith PetscErrorCode MatCompress_SeqAIJ(Mat A) 74217ab2063SBarry Smith { 7433a40ed3dSBarry Smith PetscFunctionBegin; 7443a40ed3dSBarry Smith PetscFunctionReturn(0); 74517ab2063SBarry Smith } 74617ab2063SBarry Smith 7474a2ae208SSatish Balay #undef __FUNCT__ 7484a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ" 749*4e0d8c25SBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscTruth flg) 75017ab2063SBarry Smith { 751416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 7524846f1f5SKris Buschelman PetscErrorCode ierr; 7533a40ed3dSBarry Smith 7543a40ed3dSBarry Smith PetscFunctionBegin; 755a65d3064SKris Buschelman switch (op) { 756a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 757*4e0d8c25SBarry Smith a->roworiented = flg; 758a65d3064SKris Buschelman break; 759a65d3064SKris Buschelman case MAT_KEEP_ZEROED_ROWS: 760*4e0d8c25SBarry Smith a->keepzeroedrows = flg; 761a65d3064SKris Buschelman break; 762a65d3064SKris Buschelman case MAT_COLUMNS_SORTED: 763*4e0d8c25SBarry Smith a->sorted = flg; 764a65d3064SKris Buschelman break; 765a65d3064SKris Buschelman case MAT_NO_NEW_NONZERO_LOCATIONS: 766*4e0d8c25SBarry Smith a->nonew = (flg ? 1 : 0); 767a65d3064SKris Buschelman break; 768a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 769*4e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 770a65d3064SKris Buschelman break; 771a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 772*4e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 773a65d3064SKris Buschelman break; 774a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 775*4e0d8c25SBarry Smith a->ignorezeroentries = flg; 7760df259c2SBarry Smith break; 777d487561eSHong Zhang case MAT_USE_COMPRESSEDROW: 778*4e0d8c25SBarry Smith a->compressedrow.use = flg; 779d487561eSHong Zhang break; 780a65d3064SKris Buschelman case MAT_ROWS_SORTED: 781*4e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 782a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 783a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 784290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 785a65d3064SKris Buschelman break; 786a65d3064SKris Buschelman default: 78771c2f376SKris Buschelman break; 788a65d3064SKris Buschelman } 789*4e0d8c25SBarry Smith ierr = MatSetOption_Inode(A,op,flg);CHKERRQ(ierr); 7903a40ed3dSBarry Smith PetscFunctionReturn(0); 79117ab2063SBarry Smith } 79217ab2063SBarry Smith 7934a2ae208SSatish Balay #undef __FUNCT__ 7944a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ" 795dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 79617ab2063SBarry Smith { 797416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 7986849ba73SBarry Smith PetscErrorCode ierr; 79997f1f81fSBarry Smith PetscInt i,j,n; 80087828ca2SBarry Smith PetscScalar *x,zero = 0.0; 80117ab2063SBarry Smith 8023a40ed3dSBarry Smith PetscFunctionBegin; 8032dcb1b2aSMatthew Knepley ierr = VecSet(v,zero);CHKERRQ(ierr); 8041ebc52fbSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 80536db0b34SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 806899cda47SBarry Smith if (n != A->rmap.n) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 807899cda47SBarry Smith for (i=0; i<A->rmap.n; i++) { 808bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 809bfeeae90SHong Zhang if (a->j[j] == i) { 810416022c9SBarry Smith x[i] = a->a[j]; 81117ab2063SBarry Smith break; 81217ab2063SBarry Smith } 81317ab2063SBarry Smith } 81417ab2063SBarry Smith } 8151ebc52fbSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 8163a40ed3dSBarry Smith PetscFunctionReturn(0); 81717ab2063SBarry Smith } 81817ab2063SBarry Smith 8194a2ae208SSatish Balay #undef __FUNCT__ 8204a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ" 821dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 82217ab2063SBarry Smith { 823416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 8245c897100SBarry Smith PetscScalar *x,*y; 825dfbe8321SBarry Smith PetscErrorCode ierr; 826899cda47SBarry Smith PetscInt m = A->rmap.n; 8275c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 8285c897100SBarry Smith PetscScalar *v,alpha; 8297b2bb3b9SHong Zhang PetscInt n,i,*idx,*ii,*ridx=PETSC_NULL; 8303447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 8314eb6d288SHong Zhang PetscTruth usecprow = cprow.use; 8325c897100SBarry Smith #endif 83317ab2063SBarry Smith 8343a40ed3dSBarry Smith PetscFunctionBegin; 8352e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 8361ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 8371ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 8385c897100SBarry Smith 8395c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 840bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 8415c897100SBarry Smith #else 8423447b6efSHong Zhang if (usecprow){ 8433447b6efSHong Zhang m = cprow.nrows; 8443447b6efSHong Zhang ii = cprow.i; 8457b2bb3b9SHong Zhang ridx = cprow.rindex; 8463447b6efSHong Zhang } else { 8473447b6efSHong Zhang ii = a->i; 8483447b6efSHong Zhang } 84917ab2063SBarry Smith for (i=0; i<m; i++) { 8503447b6efSHong Zhang idx = a->j + ii[i] ; 8513447b6efSHong Zhang v = a->a + ii[i] ; 8523447b6efSHong Zhang n = ii[i+1] - ii[i]; 8533447b6efSHong Zhang if (usecprow){ 8547b2bb3b9SHong Zhang alpha = x[ridx[i]]; 8553447b6efSHong Zhang } else { 85617ab2063SBarry Smith alpha = x[i]; 8573447b6efSHong Zhang } 85817ab2063SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 85917ab2063SBarry Smith } 8605c897100SBarry Smith #endif 861efee365bSSatish Balay ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr); 8621ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 8631ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 8643a40ed3dSBarry Smith PetscFunctionReturn(0); 86517ab2063SBarry Smith } 86617ab2063SBarry Smith 8674a2ae208SSatish Balay #undef __FUNCT__ 8685c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ" 869dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 8705c897100SBarry Smith { 8718d5b0100SBarry Smith PetscScalar zero = 0.0; 872dfbe8321SBarry Smith PetscErrorCode ierr; 8735c897100SBarry Smith 8745c897100SBarry Smith PetscFunctionBegin; 8752dcb1b2aSMatthew Knepley ierr = VecSet(yy,zero);CHKERRQ(ierr); 8765c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 8775c897100SBarry Smith PetscFunctionReturn(0); 8785c897100SBarry Smith } 8795c897100SBarry Smith 8805c897100SBarry Smith 8815c897100SBarry Smith #undef __FUNCT__ 8824a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ" 883dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 88417ab2063SBarry Smith { 885416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 88697952fefSHong Zhang PetscScalar *x,*y,*aa; 887dfbe8321SBarry Smith PetscErrorCode ierr; 888899cda47SBarry Smith PetscInt m=A->rmap.n,*aj,*ii; 889a46b3154SVictor Eijkhout PetscInt n,i,j,nonzerorow=0,*ridx=PETSC_NULL; 890362ced78SSatish Balay PetscScalar sum; 89197952fefSHong Zhang PetscTruth usecprow=a->compressedrow.use; 892f2e71c43SSatish Balay #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 893f2e71c43SSatish Balay PetscInt jrow; 894e36a17ebSSatish Balay #endif 89517ab2063SBarry Smith 896b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 89797952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 898fee21e36SBarry Smith #endif 899fee21e36SBarry Smith 9003a40ed3dSBarry Smith PetscFunctionBegin; 9011ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 9021ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 90397952fefSHong Zhang aj = a->j; 90497952fefSHong Zhang aa = a->a; 905416022c9SBarry Smith ii = a->i; 9064eb6d288SHong Zhang if (usecprow){ /* use compressed row format */ 90797952fefSHong Zhang m = a->compressedrow.nrows; 90897952fefSHong Zhang ii = a->compressedrow.i; 90997952fefSHong Zhang ridx = a->compressedrow.rindex; 91097952fefSHong Zhang for (i=0; i<m; i++){ 91197952fefSHong Zhang n = ii[i+1] - ii[i]; 91297952fefSHong Zhang aj = a->j + ii[i]; 91397952fefSHong Zhang aa = a->a + ii[i]; 91497952fefSHong Zhang sum = 0.0; 915a46b3154SVictor Eijkhout nonzerorow += (n>0); 91697952fefSHong Zhang for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; 91797952fefSHong Zhang y[*ridx++] = sum; 91897952fefSHong Zhang } 91997952fefSHong Zhang } else { /* do not use compressed row format */ 920b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 921b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 922b05257ddSBarry Smith #else 92317ab2063SBarry Smith for (i=0; i<m; i++) { 9249ea0dfa2SSatish Balay jrow = ii[i]; 9259ea0dfa2SSatish Balay n = ii[i+1] - jrow; 92617ab2063SBarry Smith sum = 0.0; 927a46b3154SVictor Eijkhout nonzerorow += (n>0); 9289ea0dfa2SSatish Balay for (j=0; j<n; j++) { 92997952fefSHong Zhang sum += aa[jrow]*x[aj[jrow]]; jrow++; 9309ea0dfa2SSatish Balay } 93117ab2063SBarry Smith y[i] = sum; 93217ab2063SBarry Smith } 9338d195f9aSBarry Smith #endif 934b05257ddSBarry Smith } 935a46b3154SVictor Eijkhout ierr = PetscLogFlops(2*a->nz - nonzerorow);CHKERRQ(ierr); 9361ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 9371ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 9383a40ed3dSBarry Smith PetscFunctionReturn(0); 93917ab2063SBarry Smith } 94017ab2063SBarry Smith 9414a2ae208SSatish Balay #undef __FUNCT__ 9424a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ" 943dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 94417ab2063SBarry Smith { 945416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 94697952fefSHong Zhang PetscScalar *x,*y,*z,*aa; 947dfbe8321SBarry Smith PetscErrorCode ierr; 948899cda47SBarry Smith PetscInt m = A->rmap.n,*aj,*ii; 949aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 95097952fefSHong Zhang PetscInt n,i,jrow,j,*ridx=PETSC_NULL; 951362ced78SSatish Balay PetscScalar sum; 95297952fefSHong Zhang PetscTruth usecprow=a->compressedrow.use; 953e36a17ebSSatish Balay #endif 9549ea0dfa2SSatish Balay 9553a40ed3dSBarry Smith PetscFunctionBegin; 9561ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 9571ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 9582e8a6d31SBarry Smith if (zz != yy) { 9591ebc52fbSHong Zhang ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 9602e8a6d31SBarry Smith } else { 9612e8a6d31SBarry Smith z = y; 9622e8a6d31SBarry Smith } 963bfeeae90SHong Zhang 96497952fefSHong Zhang aj = a->j; 96597952fefSHong Zhang aa = a->a; 966cddf8d76SBarry Smith ii = a->i; 967aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 96897952fefSHong Zhang fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 96902ab625aSSatish Balay #else 9704eb6d288SHong Zhang if (usecprow){ /* use compressed row format */ 9714eb6d288SHong Zhang if (zz != yy){ 9724eb6d288SHong Zhang ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 9734eb6d288SHong Zhang } 97497952fefSHong Zhang m = a->compressedrow.nrows; 97597952fefSHong Zhang ii = a->compressedrow.i; 97697952fefSHong Zhang ridx = a->compressedrow.rindex; 97797952fefSHong Zhang for (i=0; i<m; i++){ 97897952fefSHong Zhang n = ii[i+1] - ii[i]; 97997952fefSHong Zhang aj = a->j + ii[i]; 98097952fefSHong Zhang aa = a->a + ii[i]; 98197952fefSHong Zhang sum = y[*ridx]; 98297952fefSHong Zhang for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; 98397952fefSHong Zhang z[*ridx++] = sum; 98497952fefSHong Zhang } 98597952fefSHong Zhang } else { /* do not use compressed row format */ 98617ab2063SBarry Smith for (i=0; i<m; i++) { 9879ea0dfa2SSatish Balay jrow = ii[i]; 9889ea0dfa2SSatish Balay n = ii[i+1] - jrow; 98917ab2063SBarry Smith sum = y[i]; 9909ea0dfa2SSatish Balay for (j=0; j<n; j++) { 99197952fefSHong Zhang sum += aa[jrow]*x[aj[jrow]]; jrow++; 9929ea0dfa2SSatish Balay } 99317ab2063SBarry Smith z[i] = sum; 99417ab2063SBarry Smith } 99597952fefSHong Zhang } 99602ab625aSSatish Balay #endif 997efee365bSSatish Balay ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr); 9981ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 9991ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 10002e8a6d31SBarry Smith if (zz != yy) { 10011ebc52fbSHong Zhang ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 10022e8a6d31SBarry Smith } 10033a40ed3dSBarry Smith PetscFunctionReturn(0); 100417ab2063SBarry Smith } 100517ab2063SBarry Smith 100617ab2063SBarry Smith /* 100717ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 100817ab2063SBarry Smith */ 10094a2ae208SSatish Balay #undef __FUNCT__ 10104a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ" 1011dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 101217ab2063SBarry Smith { 1013416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 10146849ba73SBarry Smith PetscErrorCode ierr; 101509f38230SBarry Smith PetscInt i,j,m = A->rmap.n; 101617ab2063SBarry Smith 10173a40ed3dSBarry Smith PetscFunctionBegin; 101809f38230SBarry Smith if (!a->diag) { 101909f38230SBarry Smith ierr = PetscMalloc(m*sizeof(PetscInt),&a->diag);CHKERRQ(ierr); 10209518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(A, m*sizeof(PetscInt));CHKERRQ(ierr); 102109f38230SBarry Smith } 1022899cda47SBarry Smith for (i=0; i<A->rmap.n; i++) { 102309f38230SBarry Smith a->diag[i] = a->i[i+1]; 1024bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1025bfeeae90SHong Zhang if (a->j[j] == i) { 102609f38230SBarry Smith a->diag[i] = j; 102717ab2063SBarry Smith break; 102817ab2063SBarry Smith } 102917ab2063SBarry Smith } 103017ab2063SBarry Smith } 10313a40ed3dSBarry Smith PetscFunctionReturn(0); 103217ab2063SBarry Smith } 103317ab2063SBarry Smith 1034be5855fcSBarry Smith /* 1035be5855fcSBarry Smith Checks for missing diagonals 1036be5855fcSBarry Smith */ 10374a2ae208SSatish Balay #undef __FUNCT__ 10384a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ" 103909f38230SBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscTruth *missing,PetscInt *d) 1040be5855fcSBarry Smith { 1041be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 104297f1f81fSBarry Smith PetscInt *diag,*jj = a->j,i; 1043be5855fcSBarry Smith 1044be5855fcSBarry Smith PetscFunctionBegin; 104509f38230SBarry Smith *missing = PETSC_FALSE; 104609f38230SBarry Smith if (A->rmap.n > 0 && !jj) { 104709f38230SBarry Smith *missing = PETSC_TRUE; 104809f38230SBarry Smith if (d) *d = 0; 104909f38230SBarry Smith PetscInfo(A,"Matrix has no entries therefor is missing diagonal"); 105009f38230SBarry Smith } else { 1051f1e2ffcdSBarry Smith diag = a->diag; 1052899cda47SBarry Smith for (i=0; i<A->rmap.n; i++) { 1053bfeeae90SHong Zhang if (jj[diag[i]] != i) { 105409f38230SBarry Smith *missing = PETSC_TRUE; 105509f38230SBarry Smith if (d) *d = i; 105609f38230SBarry Smith PetscInfo1(A,"Matrix is missing diagonal number %D",i); 105709f38230SBarry Smith } 1058be5855fcSBarry Smith } 1059be5855fcSBarry Smith } 1060be5855fcSBarry Smith PetscFunctionReturn(0); 1061be5855fcSBarry Smith } 1062be5855fcSBarry Smith 10634a2ae208SSatish Balay #undef __FUNCT__ 10644a2ae208SSatish Balay #define __FUNCT__ "MatRelax_SeqAIJ" 106597f1f81fSBarry Smith PetscErrorCode MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 106617ab2063SBarry Smith { 1067416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1068beeb8507SBarry Smith PetscScalar *x,d,*xs,sum,*t,scale,*idiag=0,*mdiag; 1069beeb8507SBarry Smith const PetscScalar *v = a->a, *b, *bs,*xb, *ts; 1070dfbe8321SBarry Smith PetscErrorCode ierr; 1071899cda47SBarry Smith PetscInt n = A->cmap.n,m = A->rmap.n,i; 107297f1f81fSBarry Smith const PetscInt *idx,*diag; 107317ab2063SBarry Smith 10743a40ed3dSBarry Smith PetscFunctionBegin; 1075b965ef7fSBarry Smith its = its*lits; 107677431f27SBarry Smith if (its <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D and local its %D both positive",its,lits); 107791723122SBarry Smith 1078ed480e8bSBarry Smith diag = a->diag; 1079ed480e8bSBarry Smith if (!a->idiag) { 1080ed480e8bSBarry Smith ierr = PetscMalloc(3*m*sizeof(PetscScalar),&a->idiag);CHKERRQ(ierr); 10819518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr); 1082ed480e8bSBarry Smith a->ssor = a->idiag + m; 1083ed480e8bSBarry Smith mdiag = a->ssor + m; 1084ed480e8bSBarry Smith v = a->a; 1085ed480e8bSBarry Smith 1086ed480e8bSBarry Smith /* this is wrong when fshift omega changes each iteration */ 1087958c9bccSBarry Smith if (omega == 1.0 && !fshift) { 1088ed480e8bSBarry Smith for (i=0; i<m; i++) { 1089ed480e8bSBarry Smith mdiag[i] = v[diag[i]]; 109029c1d7e0SHong Zhang if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 1091ed480e8bSBarry Smith a->idiag[i] = 1.0/v[diag[i]]; 1092ed480e8bSBarry Smith } 1093efee365bSSatish Balay ierr = PetscLogFlops(m);CHKERRQ(ierr); 1094ed480e8bSBarry Smith } else { 1095ed480e8bSBarry Smith for (i=0; i<m; i++) { 1096ed480e8bSBarry Smith mdiag[i] = v[diag[i]]; 1097beeb8507SBarry Smith a->idiag[i] = omega/(fshift + v[diag[i]]); 1098ed480e8bSBarry Smith } 1099efee365bSSatish Balay ierr = PetscLogFlops(2*m);CHKERRQ(ierr); 1100beeb8507SBarry Smith } 1101ed480e8bSBarry Smith } 1102ed480e8bSBarry Smith t = a->ssor; 1103ed480e8bSBarry Smith idiag = a->idiag; 1104ed480e8bSBarry Smith mdiag = a->idiag + 2*m; 1105ed480e8bSBarry Smith 11061ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 1107fb2e594dSBarry Smith if (xx != bb) { 11081ebc52fbSHong Zhang ierr = VecGetArray(bb,(PetscScalar**)&b);CHKERRQ(ierr); 1109fb2e594dSBarry Smith } else { 1110fb2e594dSBarry Smith b = x; 1111fb2e594dSBarry Smith } 1112fb2e594dSBarry Smith 1113ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 1114ed480e8bSBarry Smith xs = x; 111517ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 111617ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1117ed480e8bSBarry Smith bs = b; 111817ab2063SBarry Smith for (i=0; i<m; i++) { 1119ed480e8bSBarry Smith d = fshift + a->a[diag[i]]; 1120416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1121ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1122ed480e8bSBarry Smith v = a->a + diag[i] + 1; 112317ab2063SBarry Smith sum = b[i]*d/omega; 112417ab2063SBarry Smith SPARSEDENSEDOT(sum,bs,v,idx,n); 112517ab2063SBarry Smith x[i] = sum; 112617ab2063SBarry Smith } 11271ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 11281ebc52fbSHong Zhang if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);} 1129efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 11303a40ed3dSBarry Smith PetscFunctionReturn(0); 113117ab2063SBarry Smith } 1132c783ea89SBarry Smith 1133ed480e8bSBarry Smith 1134fc3d8934SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1135fc3d8934SBarry Smith U is upper triangular, E is diagonal; This routine applies 1136fc3d8934SBarry Smith 1137fc3d8934SBarry Smith (L + E)^{-1} A (U + E)^{-1} 1138fc3d8934SBarry Smith 1139fc3d8934SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 1140fc3d8934SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 114148af12d7SBarry Smith is the relaxation factor. 1142fc3d8934SBarry Smith */ 1143fc3d8934SBarry Smith 114448af12d7SBarry Smith if (flag == SOR_APPLY_LOWER) { 114529bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 11463a40ed3dSBarry Smith } else if (flag & SOR_EISENSTAT) { 114717ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 114817ab2063SBarry Smith U is upper triangular, E is diagonal; This routine applies 114917ab2063SBarry Smith 115017ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 115117ab2063SBarry Smith 115217ab2063SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 115317ab2063SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 115417ab2063SBarry Smith is the relaxation factor. 115517ab2063SBarry Smith */ 115617ab2063SBarry Smith scale = (2.0/omega) - 1.0; 115717ab2063SBarry Smith 115817ab2063SBarry Smith /* x = (E + U)^{-1} b */ 115917ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1160416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1161ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1162ed480e8bSBarry Smith v = a->a + diag[i] + 1; 116317ab2063SBarry Smith sum = b[i]; 116417ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1165ed480e8bSBarry Smith x[i] = sum*idiag[i]; 116617ab2063SBarry Smith } 116717ab2063SBarry Smith 116817ab2063SBarry Smith /* t = b - (2*E - D)x */ 1169416022c9SBarry Smith v = a->a; 1170ed480e8bSBarry Smith for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; } 117117ab2063SBarry Smith 117217ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1173ed480e8bSBarry Smith ts = t; 1174416022c9SBarry Smith diag = a->diag; 117517ab2063SBarry Smith for (i=0; i<m; i++) { 1176416022c9SBarry Smith n = diag[i] - a->i[i]; 1177ed480e8bSBarry Smith idx = a->j + a->i[i]; 1178ed480e8bSBarry Smith v = a->a + a->i[i]; 117917ab2063SBarry Smith sum = t[i]; 118017ab2063SBarry Smith SPARSEDENSEMDOT(sum,ts,v,idx,n); 1181ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1182733d66baSBarry Smith /* x = x + t */ 1183733d66baSBarry Smith x[i] += t[i]; 118417ab2063SBarry Smith } 118517ab2063SBarry Smith 1186efee365bSSatish Balay ierr = PetscLogFlops(6*m-1 + 2*a->nz);CHKERRQ(ierr); 11871ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 11881ebc52fbSHong Zhang if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);} 11893a40ed3dSBarry Smith PetscFunctionReturn(0); 119017ab2063SBarry Smith } 119117ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 119217ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 119377d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 119497f1f81fSBarry Smith fortranrelaxaijforwardzero_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,idiag,a->a,(void*)b); 119577d8c4bbSBarry Smith #else 119617ab2063SBarry Smith for (i=0; i<m; i++) { 1197416022c9SBarry Smith n = diag[i] - a->i[i]; 1198ed480e8bSBarry Smith idx = a->j + a->i[i]; 1199ed480e8bSBarry Smith v = a->a + a->i[i]; 120017ab2063SBarry Smith sum = b[i]; 120117ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1202ed480e8bSBarry Smith x[i] = sum*idiag[i]; 120317ab2063SBarry Smith } 120477d8c4bbSBarry Smith #endif 120517ab2063SBarry Smith xb = x; 1206efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 12073a40ed3dSBarry Smith } else xb = b; 120817ab2063SBarry Smith if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) && 120917ab2063SBarry Smith (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) { 121017ab2063SBarry Smith for (i=0; i<m; i++) { 1211ed480e8bSBarry Smith x[i] *= mdiag[i]; 121217ab2063SBarry Smith } 1213efee365bSSatish Balay ierr = PetscLogFlops(m);CHKERRQ(ierr); 121417ab2063SBarry Smith } 121517ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 121677d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 121797f1f81fSBarry Smith fortranrelaxaijbackwardzero_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,idiag,a->a,(void*)xb); 121877d8c4bbSBarry Smith #else 121917ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1220416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1221ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1222ed480e8bSBarry Smith v = a->a + diag[i] + 1; 122317ab2063SBarry Smith sum = xb[i]; 122417ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1225ed480e8bSBarry Smith x[i] = sum*idiag[i]; 122617ab2063SBarry Smith } 122777d8c4bbSBarry Smith #endif 1228efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 122917ab2063SBarry Smith } 123017ab2063SBarry Smith its--; 123117ab2063SBarry Smith } 123217ab2063SBarry Smith while (its--) { 123317ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 123477d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 123597f1f81fSBarry Smith fortranrelaxaijforward_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,a->a,(void*)b); 123677d8c4bbSBarry Smith #else 123717ab2063SBarry Smith for (i=0; i<m; i++) { 1238416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1239ed480e8bSBarry Smith idx = a->j + a->i[i]; 1240ed480e8bSBarry Smith v = a->a + a->i[i]; 124117ab2063SBarry Smith sum = b[i]; 124217ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1243ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 124417ab2063SBarry Smith } 124577d8c4bbSBarry Smith #endif 1246efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 124717ab2063SBarry Smith } 124817ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 124977d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 125097f1f81fSBarry Smith fortranrelaxaijbackward_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,a->a,(void*)b); 125177d8c4bbSBarry Smith #else 125217ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1253416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1254ed480e8bSBarry Smith idx = a->j + a->i[i]; 1255ed480e8bSBarry Smith v = a->a + a->i[i]; 125617ab2063SBarry Smith sum = b[i]; 125717ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1258ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 125917ab2063SBarry Smith } 126077d8c4bbSBarry Smith #endif 1261efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 126217ab2063SBarry Smith } 126317ab2063SBarry Smith } 12641ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 12651ebc52fbSHong Zhang if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);} 12663a40ed3dSBarry Smith PetscFunctionReturn(0); 126717ab2063SBarry Smith } 126817ab2063SBarry Smith 12694a2ae208SSatish Balay #undef __FUNCT__ 12704a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ" 1271dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 127217ab2063SBarry Smith { 1273416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 12744e220ebcSLois Curfman McInnes 12753a40ed3dSBarry Smith PetscFunctionBegin; 1276899cda47SBarry Smith info->rows_global = (double)A->rmap.n; 1277899cda47SBarry Smith info->columns_global = (double)A->cmap.n; 1278899cda47SBarry Smith info->rows_local = (double)A->rmap.n; 1279899cda47SBarry Smith info->columns_local = (double)A->cmap.n; 12804e220ebcSLois Curfman McInnes info->block_size = 1.0; 12814e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 12824e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 12834e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 12844e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 12854e220ebcSLois Curfman McInnes info->mallocs = (double)a->reallocs; 12864e220ebcSLois Curfman McInnes info->memory = A->mem; 12874e220ebcSLois Curfman McInnes if (A->factor) { 12884e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 12894e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 12904e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 12914e220ebcSLois Curfman McInnes } else { 12924e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 12934e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 12944e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 12954e220ebcSLois Curfman McInnes } 12963a40ed3dSBarry Smith PetscFunctionReturn(0); 129717ab2063SBarry Smith } 129817ab2063SBarry Smith 12994a2ae208SSatish Balay #undef __FUNCT__ 13004a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ" 1301f4df32b1SMatthew Knepley PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag) 130217ab2063SBarry Smith { 1303416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 130409f38230SBarry Smith PetscInt i,m = A->rmap.n - 1,d; 13056849ba73SBarry Smith PetscErrorCode ierr; 130609f38230SBarry Smith PetscTruth missing; 130717ab2063SBarry Smith 13083a40ed3dSBarry Smith PetscFunctionBegin; 1309f1e2ffcdSBarry Smith if (a->keepzeroedrows) { 1310f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 131177431f27SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1312bfeeae90SHong Zhang ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 1313f1e2ffcdSBarry Smith } 1314f4df32b1SMatthew Knepley if (diag != 0.0) { 131509f38230SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 131609f38230SBarry Smith if (missing) SETERRQ1(PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 1317f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1318f4df32b1SMatthew Knepley a->a[a->diag[rows[i]]] = diag; 1319f1e2ffcdSBarry Smith } 1320f1e2ffcdSBarry Smith } 132188e51ccdSHong Zhang A->same_nonzero = PETSC_TRUE; 1322f1e2ffcdSBarry Smith } else { 1323f4df32b1SMatthew Knepley if (diag != 0.0) { 132417ab2063SBarry Smith for (i=0; i<N; i++) { 132577431f27SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 13267ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1327416022c9SBarry Smith a->ilen[rows[i]] = 1; 1328f4df32b1SMatthew Knepley a->a[a->i[rows[i]]] = diag; 1329bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 13307ae801bdSBarry Smith } else { /* in case row was completely empty */ 1331f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 133217ab2063SBarry Smith } 133317ab2063SBarry Smith } 13343a40ed3dSBarry Smith } else { 133517ab2063SBarry Smith for (i=0; i<N; i++) { 133677431f27SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1337416022c9SBarry Smith a->ilen[rows[i]] = 0; 133817ab2063SBarry Smith } 133917ab2063SBarry Smith } 134088e51ccdSHong Zhang A->same_nonzero = PETSC_FALSE; 1341f1e2ffcdSBarry Smith } 134243a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13433a40ed3dSBarry Smith PetscFunctionReturn(0); 134417ab2063SBarry Smith } 134517ab2063SBarry Smith 13464a2ae208SSatish Balay #undef __FUNCT__ 13474a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ" 134897f1f81fSBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 134917ab2063SBarry Smith { 1350416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 135197f1f81fSBarry Smith PetscInt *itmp; 135217ab2063SBarry Smith 13533a40ed3dSBarry Smith PetscFunctionBegin; 1354899cda47SBarry Smith if (row < 0 || row >= A->rmap.n) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 135517ab2063SBarry Smith 1356416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1357bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 135817ab2063SBarry Smith if (idx) { 1359bfeeae90SHong Zhang itmp = a->j + a->i[row]; 1360bfeeae90SHong Zhang if (*nz) { 13614e093b46SBarry Smith *idx = itmp; 136217ab2063SBarry Smith } 136317ab2063SBarry Smith else *idx = 0; 136417ab2063SBarry Smith } 13653a40ed3dSBarry Smith PetscFunctionReturn(0); 136617ab2063SBarry Smith } 136717ab2063SBarry Smith 1368bfeeae90SHong Zhang /* remove this function? */ 13694a2ae208SSatish Balay #undef __FUNCT__ 13704a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ" 137197f1f81fSBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 137217ab2063SBarry Smith { 13733a40ed3dSBarry Smith PetscFunctionBegin; 13743a40ed3dSBarry Smith PetscFunctionReturn(0); 137517ab2063SBarry Smith } 137617ab2063SBarry Smith 13774a2ae208SSatish Balay #undef __FUNCT__ 13784a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ" 1379dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 138017ab2063SBarry Smith { 1381416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 138287828ca2SBarry Smith PetscScalar *v = a->a; 138336db0b34SBarry Smith PetscReal sum = 0.0; 13846849ba73SBarry Smith PetscErrorCode ierr; 138597f1f81fSBarry Smith PetscInt i,j; 138617ab2063SBarry Smith 13873a40ed3dSBarry Smith PetscFunctionBegin; 138817ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1389416022c9SBarry Smith for (i=0; i<a->nz; i++) { 1390aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 139136db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 139217ab2063SBarry Smith #else 139317ab2063SBarry Smith sum += (*v)*(*v); v++; 139417ab2063SBarry Smith #endif 139517ab2063SBarry Smith } 1396064f8208SBarry Smith *nrm = sqrt(sum); 13973a40ed3dSBarry Smith } else if (type == NORM_1) { 139836db0b34SBarry Smith PetscReal *tmp; 139997f1f81fSBarry Smith PetscInt *jj = a->j; 1400899cda47SBarry Smith ierr = PetscMalloc((A->cmap.n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr); 1401899cda47SBarry Smith ierr = PetscMemzero(tmp,A->cmap.n*sizeof(PetscReal));CHKERRQ(ierr); 1402064f8208SBarry Smith *nrm = 0.0; 1403416022c9SBarry Smith for (j=0; j<a->nz; j++) { 1404bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 140517ab2063SBarry Smith } 1406899cda47SBarry Smith for (j=0; j<A->cmap.n; j++) { 1407064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 140817ab2063SBarry Smith } 1409606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 14103a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1411064f8208SBarry Smith *nrm = 0.0; 1412899cda47SBarry Smith for (j=0; j<A->rmap.n; j++) { 1413bfeeae90SHong Zhang v = a->a + a->i[j]; 141417ab2063SBarry Smith sum = 0.0; 1415416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 1416cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 141717ab2063SBarry Smith } 1418064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 141917ab2063SBarry Smith } 14203a40ed3dSBarry Smith } else { 142129bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"No support for two norm"); 142217ab2063SBarry Smith } 14233a40ed3dSBarry Smith PetscFunctionReturn(0); 142417ab2063SBarry Smith } 142517ab2063SBarry Smith 14264a2ae208SSatish Balay #undef __FUNCT__ 14274a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ" 1428dfbe8321SBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,Mat *B) 142917ab2063SBarry Smith { 1430416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1431416022c9SBarry Smith Mat C; 14326849ba73SBarry Smith PetscErrorCode ierr; 1433899cda47SBarry Smith PetscInt i,*aj = a->j,*ai = a->i,m = A->rmap.n,len,*col; 143487828ca2SBarry Smith PetscScalar *array = a->a; 143517ab2063SBarry Smith 14363a40ed3dSBarry Smith PetscFunctionBegin; 1437899cda47SBarry Smith if (!B && m != A->cmap.n) SETERRQ(PETSC_ERR_ARG_SIZ,"Square matrix only for in-place"); 1438899cda47SBarry Smith ierr = PetscMalloc((1+A->cmap.n)*sizeof(PetscInt),&col);CHKERRQ(ierr); 1439899cda47SBarry Smith ierr = PetscMemzero(col,(1+A->cmap.n)*sizeof(PetscInt));CHKERRQ(ierr); 1440bfeeae90SHong Zhang 1441bfeeae90SHong Zhang for (i=0; i<ai[m]; i++) col[aj[i]] += 1; 1442f69a0ea3SMatthew Knepley ierr = MatCreate(A->comm,&C);CHKERRQ(ierr); 1443899cda47SBarry Smith ierr = MatSetSizes(C,A->cmap.n,m,A->cmap.n,m);CHKERRQ(ierr); 1444f204ca49SKris Buschelman ierr = MatSetType(C,A->type_name);CHKERRQ(ierr); 1445ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr); 1446606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 144717ab2063SBarry Smith for (i=0; i<m; i++) { 144817ab2063SBarry Smith len = ai[i+1]-ai[i]; 144987d4246cSBarry Smith ierr = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 1450b9b97703SBarry Smith array += len; 1451b9b97703SBarry Smith aj += len; 145217ab2063SBarry Smith } 145317ab2063SBarry Smith 14546d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14556d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 145617ab2063SBarry Smith 1457f1e2ffcdSBarry Smith if (B) { 1458416022c9SBarry Smith *B = C; 145917ab2063SBarry Smith } else { 1460273d9f13SBarry Smith ierr = MatHeaderCopy(A,C);CHKERRQ(ierr); 146117ab2063SBarry Smith } 14623a40ed3dSBarry Smith PetscFunctionReturn(0); 146317ab2063SBarry Smith } 146417ab2063SBarry Smith 1465cd0d46ebSvictorle EXTERN_C_BEGIN 1466cd0d46ebSvictorle #undef __FUNCT__ 14675fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ" 1468be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscTruth *f) 1469cd0d46ebSvictorle { 1470cd0d46ebSvictorle Mat_SeqAIJ *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data; 147197f1f81fSBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; PetscScalar *va,*vb; 14726849ba73SBarry Smith PetscErrorCode ierr; 147397f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 1474cd0d46ebSvictorle 1475cd0d46ebSvictorle PetscFunctionBegin; 1476cd0d46ebSvictorle bij = (Mat_SeqAIJ *) B->data; 1477cd0d46ebSvictorle 1478cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 1479cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 14805485867bSBarry Smith if (ma!=nb || na!=mb){ 14815485867bSBarry Smith *f = PETSC_FALSE; 14825485867bSBarry Smith PetscFunctionReturn(0); 14835485867bSBarry Smith } 1484cd0d46ebSvictorle aii = aij->i; bii = bij->i; 1485cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 1486cd0d46ebSvictorle va = aij->a; vb = bij->a; 148797f1f81fSBarry Smith ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr); 148897f1f81fSBarry Smith ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr); 1489cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 1490cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 1491cd0d46ebSvictorle 1492cd0d46ebSvictorle *f = PETSC_TRUE; 1493cd0d46ebSvictorle for (i=0; i<ma; i++) { 1494cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 149597f1f81fSBarry Smith PetscInt idc,idr; 14965485867bSBarry Smith PetscScalar vc,vr; 1497cd0d46ebSvictorle /* column/row index/value */ 14985485867bSBarry Smith idc = adx[aptr[i]]; 14995485867bSBarry Smith idr = bdx[bptr[idc]]; 15005485867bSBarry Smith vc = va[aptr[i]]; 15015485867bSBarry Smith vr = vb[bptr[idc]]; 15025485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 15035485867bSBarry Smith *f = PETSC_FALSE; 15045485867bSBarry Smith goto done; 1505cd0d46ebSvictorle } else { 15065485867bSBarry Smith aptr[i]++; 15075485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 1508cd0d46ebSvictorle } 1509cd0d46ebSvictorle } 1510cd0d46ebSvictorle } 1511cd0d46ebSvictorle done: 1512cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 15133aeef889SHong Zhang if (B) { 15143aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 15153aeef889SHong Zhang } 1516cd0d46ebSvictorle PetscFunctionReturn(0); 1517cd0d46ebSvictorle } 1518cd0d46ebSvictorle EXTERN_C_END 1519cd0d46ebSvictorle 15201cbb95d3SBarry Smith EXTERN_C_BEGIN 15211cbb95d3SBarry Smith #undef __FUNCT__ 15221cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ" 15231cbb95d3SBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscTruth *f) 15241cbb95d3SBarry Smith { 15251cbb95d3SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data; 15261cbb95d3SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; PetscScalar *va,*vb; 15271cbb95d3SBarry Smith PetscErrorCode ierr; 15281cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 15291cbb95d3SBarry Smith 15301cbb95d3SBarry Smith PetscFunctionBegin; 15311cbb95d3SBarry Smith bij = (Mat_SeqAIJ *) B->data; 15321cbb95d3SBarry Smith 15331cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 15341cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 15351cbb95d3SBarry Smith if (ma!=nb || na!=mb){ 15361cbb95d3SBarry Smith *f = PETSC_FALSE; 15371cbb95d3SBarry Smith PetscFunctionReturn(0); 15381cbb95d3SBarry Smith } 15391cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 15401cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 15411cbb95d3SBarry Smith va = aij->a; vb = bij->a; 15421cbb95d3SBarry Smith ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr); 15431cbb95d3SBarry Smith ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr); 15441cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 15451cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 15461cbb95d3SBarry Smith 15471cbb95d3SBarry Smith *f = PETSC_TRUE; 15481cbb95d3SBarry Smith for (i=0; i<ma; i++) { 15491cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 15501cbb95d3SBarry Smith PetscInt idc,idr; 15511cbb95d3SBarry Smith PetscScalar vc,vr; 15521cbb95d3SBarry Smith /* column/row index/value */ 15531cbb95d3SBarry Smith idc = adx[aptr[i]]; 15541cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 15551cbb95d3SBarry Smith vc = va[aptr[i]]; 15561cbb95d3SBarry Smith vr = vb[bptr[idc]]; 15571cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 15581cbb95d3SBarry Smith *f = PETSC_FALSE; 15591cbb95d3SBarry Smith goto done; 15601cbb95d3SBarry Smith } else { 15611cbb95d3SBarry Smith aptr[i]++; 15621cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 15631cbb95d3SBarry Smith } 15641cbb95d3SBarry Smith } 15651cbb95d3SBarry Smith } 15661cbb95d3SBarry Smith done: 15671cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 15681cbb95d3SBarry Smith if (B) { 15691cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 15701cbb95d3SBarry Smith } 15711cbb95d3SBarry Smith PetscFunctionReturn(0); 15721cbb95d3SBarry Smith } 15731cbb95d3SBarry Smith EXTERN_C_END 15741cbb95d3SBarry Smith 15759e29f15eSvictorle #undef __FUNCT__ 15769e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ" 1577dfbe8321SBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscTruth *f) 15789e29f15eSvictorle { 1579dfbe8321SBarry Smith PetscErrorCode ierr; 15809e29f15eSvictorle PetscFunctionBegin; 15815485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 15829e29f15eSvictorle PetscFunctionReturn(0); 15839e29f15eSvictorle } 15849e29f15eSvictorle 15854a2ae208SSatish Balay #undef __FUNCT__ 15861cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ" 15871cbb95d3SBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscTruth *f) 15881cbb95d3SBarry Smith { 15891cbb95d3SBarry Smith PetscErrorCode ierr; 15901cbb95d3SBarry Smith PetscFunctionBegin; 15911cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 15921cbb95d3SBarry Smith PetscFunctionReturn(0); 15931cbb95d3SBarry Smith } 15941cbb95d3SBarry Smith 15951cbb95d3SBarry Smith #undef __FUNCT__ 15964a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ" 1597dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 159817ab2063SBarry Smith { 1599416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 160087828ca2SBarry Smith PetscScalar *l,*r,x,*v; 1601dfbe8321SBarry Smith PetscErrorCode ierr; 1602899cda47SBarry Smith PetscInt i,j,m = A->rmap.n,n = A->cmap.n,M,nz = a->nz,*jj; 160317ab2063SBarry Smith 16043a40ed3dSBarry Smith PetscFunctionBegin; 160517ab2063SBarry Smith if (ll) { 16063ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 16073ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 1608e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 1609899cda47SBarry Smith if (m != A->rmap.n) SETERRQ(PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 16101ebc52fbSHong Zhang ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 1611416022c9SBarry Smith v = a->a; 161217ab2063SBarry Smith for (i=0; i<m; i++) { 161317ab2063SBarry Smith x = l[i]; 1614416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 161517ab2063SBarry Smith for (j=0; j<M; j++) { (*v++) *= x;} 161617ab2063SBarry Smith } 16171ebc52fbSHong Zhang ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 1618efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 161917ab2063SBarry Smith } 162017ab2063SBarry Smith if (rr) { 1621e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 1622899cda47SBarry Smith if (n != A->cmap.n) SETERRQ(PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 16231ebc52fbSHong Zhang ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 1624416022c9SBarry Smith v = a->a; jj = a->j; 162517ab2063SBarry Smith for (i=0; i<nz; i++) { 1626bfeeae90SHong Zhang (*v++) *= r[*jj++]; 162717ab2063SBarry Smith } 16281ebc52fbSHong Zhang ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 1629efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 163017ab2063SBarry Smith } 16313a40ed3dSBarry Smith PetscFunctionReturn(0); 163217ab2063SBarry Smith } 163317ab2063SBarry Smith 16344a2ae208SSatish Balay #undef __FUNCT__ 16354a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ" 163697f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 163717ab2063SBarry Smith { 1638db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 16396849ba73SBarry Smith PetscErrorCode ierr; 1640899cda47SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap.n,*lens; 164197f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 164297f1f81fSBarry Smith PetscInt *irow,*icol,nrows,ncols; 164397f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 164487828ca2SBarry Smith PetscScalar *a_new,*mat_a; 1645416022c9SBarry Smith Mat C; 1646fee21e36SBarry Smith PetscTruth stride; 164717ab2063SBarry Smith 16483a40ed3dSBarry Smith PetscFunctionBegin; 1649d64ed03dSBarry Smith ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr); 165029bbc08cSBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted"); 1651d64ed03dSBarry Smith ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr); 165229bbc08cSBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted"); 165399141d43SSatish Balay 165417ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 1655b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 1656b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 165717ab2063SBarry Smith 1658fee21e36SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 1659fee21e36SBarry Smith ierr = ISStride(iscol,&stride);CHKERRQ(ierr); 1660fee21e36SBarry Smith if (stride && step == 1) { 166102834360SBarry Smith /* special case of contiguous rows */ 166297f1f81fSBarry Smith ierr = PetscMalloc((2*nrows+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 166331ebf83bSSatish Balay starts = lens + nrows; 166402834360SBarry Smith /* loop over new rows determining lens and starting points */ 166502834360SBarry Smith for (i=0; i<nrows; i++) { 1666bfeeae90SHong Zhang kstart = ai[irow[i]]; 1667a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 166802834360SBarry Smith for (k=kstart; k<kend; k++) { 1669bfeeae90SHong Zhang if (aj[k] >= first) { 167002834360SBarry Smith starts[i] = k; 167102834360SBarry Smith break; 167202834360SBarry Smith } 167302834360SBarry Smith } 1674a2744918SBarry Smith sum = 0; 167502834360SBarry Smith while (k < kend) { 1676bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 1677a2744918SBarry Smith sum++; 167802834360SBarry Smith } 1679a2744918SBarry Smith lens[i] = sum; 168002834360SBarry Smith } 168102834360SBarry Smith /* create submatrix */ 1682cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 168397f1f81fSBarry Smith PetscInt n_cols,n_rows; 168408480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 168529bbc08cSBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 1686d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 168708480c60SBarry Smith C = *B; 16883a40ed3dSBarry Smith } else { 1689f69a0ea3SMatthew Knepley ierr = MatCreate(A->comm,&C);CHKERRQ(ierr); 1690f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 1691e2d9671bSKris Buschelman ierr = MatSetType(C,A->type_name);CHKERRQ(ierr); 1692ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 169308480c60SBarry Smith } 1694db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 1695db02288aSLois Curfman McInnes 169602834360SBarry Smith /* loop over rows inserting into submatrix */ 1697db02288aSLois Curfman McInnes a_new = c->a; 1698db02288aSLois Curfman McInnes j_new = c->j; 1699db02288aSLois Curfman McInnes i_new = c->i; 1700bfeeae90SHong Zhang 170102834360SBarry Smith for (i=0; i<nrows; i++) { 1702a2744918SBarry Smith ii = starts[i]; 1703a2744918SBarry Smith lensi = lens[i]; 1704a2744918SBarry Smith for (k=0; k<lensi; k++) { 1705a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 170602834360SBarry Smith } 170787828ca2SBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr); 1708a2744918SBarry Smith a_new += lensi; 1709a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 1710a2744918SBarry Smith c->ilen[i] = lensi; 171102834360SBarry Smith } 1712606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 17133a40ed3dSBarry Smith } else { 171402834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 171597f1f81fSBarry Smith ierr = PetscMalloc((1+oldcols)*sizeof(PetscInt),&smap);CHKERRQ(ierr); 1716bfeeae90SHong Zhang 171797f1f81fSBarry Smith ierr = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 171897f1f81fSBarry Smith ierr = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr); 171917ab2063SBarry Smith for (i=0; i<ncols; i++) smap[icol[i]] = i+1; 172002834360SBarry Smith /* determine lens of each row */ 172102834360SBarry Smith for (i=0; i<nrows; i++) { 1722bfeeae90SHong Zhang kstart = ai[irow[i]]; 172302834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 172402834360SBarry Smith lens[i] = 0; 172502834360SBarry Smith for (k=kstart; k<kend; k++) { 1726bfeeae90SHong Zhang if (smap[aj[k]]) { 172702834360SBarry Smith lens[i]++; 172802834360SBarry Smith } 172902834360SBarry Smith } 173002834360SBarry Smith } 173117ab2063SBarry Smith /* Create and fill new matrix */ 1732a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 17330f5bd95cSBarry Smith PetscTruth equal; 17340f5bd95cSBarry Smith 173599141d43SSatish Balay c = (Mat_SeqAIJ *)((*B)->data); 1736899cda47SBarry Smith if ((*B)->rmap.n != nrows || (*B)->cmap.n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 1737899cda47SBarry Smith ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap.n*sizeof(PetscInt),&equal);CHKERRQ(ierr); 17380f5bd95cSBarry Smith if (!equal) { 173929bbc08cSBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 174099141d43SSatish Balay } 1741899cda47SBarry Smith ierr = PetscMemzero(c->ilen,(*B)->rmap.n*sizeof(PetscInt));CHKERRQ(ierr); 174208480c60SBarry Smith C = *B; 17433a40ed3dSBarry Smith } else { 1744f69a0ea3SMatthew Knepley ierr = MatCreate(A->comm,&C);CHKERRQ(ierr); 1745f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 1746e2d9671bSKris Buschelman ierr = MatSetType(C,A->type_name);CHKERRQ(ierr); 1747ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 174808480c60SBarry Smith } 174999141d43SSatish Balay c = (Mat_SeqAIJ *)(C->data); 175017ab2063SBarry Smith for (i=0; i<nrows; i++) { 175199141d43SSatish Balay row = irow[i]; 1752bfeeae90SHong Zhang kstart = ai[row]; 175399141d43SSatish Balay kend = kstart + a->ilen[row]; 1754bfeeae90SHong Zhang mat_i = c->i[i]; 175599141d43SSatish Balay mat_j = c->j + mat_i; 175699141d43SSatish Balay mat_a = c->a + mat_i; 175799141d43SSatish Balay mat_ilen = c->ilen + i; 175817ab2063SBarry Smith for (k=kstart; k<kend; k++) { 1759bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 1760ed480e8bSBarry Smith *mat_j++ = tcol - 1; 176199141d43SSatish Balay *mat_a++ = a->a[k]; 176299141d43SSatish Balay (*mat_ilen)++; 176399141d43SSatish Balay 176417ab2063SBarry Smith } 176517ab2063SBarry Smith } 176617ab2063SBarry Smith } 176702834360SBarry Smith /* Free work space */ 176802834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 1769606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 1770606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 177102834360SBarry Smith } 17726d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17736d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 177417ab2063SBarry Smith 177517ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 1776416022c9SBarry Smith *B = C; 17773a40ed3dSBarry Smith PetscFunctionReturn(0); 177817ab2063SBarry Smith } 177917ab2063SBarry Smith 1780a871dcd8SBarry Smith /* 1781a871dcd8SBarry Smith */ 17824a2ae208SSatish Balay #undef __FUNCT__ 17834a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ" 1784dfbe8321SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatFactorInfo *info) 1785a871dcd8SBarry Smith { 178663b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 1787dfbe8321SBarry Smith PetscErrorCode ierr; 178863b91edcSBarry Smith Mat outA; 1789b8a78c4aSBarry Smith PetscTruth row_identity,col_identity; 179063b91edcSBarry Smith 17913a40ed3dSBarry Smith PetscFunctionBegin; 1792d3d32019SBarry Smith if (info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 1793b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 1794b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 1795a871dcd8SBarry Smith 179663b91edcSBarry Smith outA = inA; 179763b91edcSBarry Smith inA->factor = FACTOR_LU; 1798c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1799c3122656SLisandro Dalcin if (a->row) { ierr = ISDestroy(a->row); CHKERRQ(ierr);} 1800c3122656SLisandro Dalcin a->row = row; 1801c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 1802c3122656SLisandro Dalcin if (a->col) { ierr = ISDestroy(a->col); CHKERRQ(ierr);} 1803c3122656SLisandro Dalcin a->col = col; 180463b91edcSBarry Smith 180536db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 1806b9b97703SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */ 18074c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 180852e6d16bSBarry Smith ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr); 1809f0ec6fceSSatish Balay 181094a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 1811899cda47SBarry Smith ierr = PetscMalloc((inA->rmap.n+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr); 18129518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(inA, (inA->rmap.n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 181394a9d846SBarry Smith } 181463b91edcSBarry Smith 1815f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 1816137fb511SHong Zhang if (row_identity && col_identity) { 1817af281ebdSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ(inA,info,&outA);CHKERRQ(ierr); 1818137fb511SHong Zhang } else { 1819137fb511SHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(inA,info,&outA);CHKERRQ(ierr); 1820137fb511SHong Zhang } 18213a40ed3dSBarry Smith PetscFunctionReturn(0); 1822a871dcd8SBarry Smith } 1823a871dcd8SBarry Smith 1824d9eff348SSatish Balay #include "petscblaslapack.h" 18254a2ae208SSatish Balay #undef __FUNCT__ 18264a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ" 1827f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 1828f0b747eeSBarry Smith { 1829f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 18304ce68768SBarry Smith PetscBLASInt bnz = (PetscBLASInt)a->nz,one = 1; 1831f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 1832efee365bSSatish Balay PetscErrorCode ierr; 1833efee365bSSatish Balay 18343a40ed3dSBarry Smith 18353a40ed3dSBarry Smith PetscFunctionBegin; 1836f4df32b1SMatthew Knepley BLASscal_(&bnz,&oalpha,a->a,&one); 1837efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 18383a40ed3dSBarry Smith PetscFunctionReturn(0); 1839f0b747eeSBarry Smith } 1840f0b747eeSBarry Smith 18414a2ae208SSatish Balay #undef __FUNCT__ 18424a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ" 184397f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 1844cddf8d76SBarry Smith { 1845dfbe8321SBarry Smith PetscErrorCode ierr; 184697f1f81fSBarry Smith PetscInt i; 1847cddf8d76SBarry Smith 18483a40ed3dSBarry Smith PetscFunctionBegin; 1849cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 1850b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr); 1851cddf8d76SBarry Smith } 1852cddf8d76SBarry Smith 1853cddf8d76SBarry Smith for (i=0; i<n; i++) { 18546a6a5d1dSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 1855cddf8d76SBarry Smith } 18563a40ed3dSBarry Smith PetscFunctionReturn(0); 1857cddf8d76SBarry Smith } 1858cddf8d76SBarry Smith 18594a2ae208SSatish Balay #undef __FUNCT__ 18604a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ" 186197f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 18624dcbc457SBarry Smith { 1863e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18646849ba73SBarry Smith PetscErrorCode ierr; 186597f1f81fSBarry Smith PetscInt row,i,j,k,l,m,n,*idx,*nidx,isz,val; 186697f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 1867f1af5d2fSBarry Smith PetscBT table; 1868bbd702dbSSatish Balay 18693a40ed3dSBarry Smith PetscFunctionBegin; 1870899cda47SBarry Smith m = A->rmap.n; 1871e4d965acSSatish Balay ai = a->i; 1872bfeeae90SHong Zhang aj = a->j; 18738a047759SSatish Balay 1874a45adfd6SMatthew Knepley if (ov < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 187506763907SSatish Balay 187697f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr); 18776831982aSBarry Smith ierr = PetscBTCreate(m,table);CHKERRQ(ierr); 187806763907SSatish Balay 1879e4d965acSSatish Balay for (i=0; i<is_max; i++) { 1880b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 1881e4d965acSSatish Balay isz = 0; 18826831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 1883e4d965acSSatish Balay 1884e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 18854dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 1886b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 1887e4d965acSSatish Balay 1888dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 1889e4d965acSSatish Balay for (j=0; j<n ; ++j){ 1890f1af5d2fSBarry Smith if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];} 18914dcbc457SBarry Smith } 189206763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 189306763907SSatish Balay ierr = ISDestroy(is[i]);CHKERRQ(ierr); 1894e4d965acSSatish Balay 189504a348a9SBarry Smith k = 0; 189604a348a9SBarry Smith for (j=0; j<ov; j++){ /* for each overlap */ 189704a348a9SBarry Smith n = isz; 189806763907SSatish Balay for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */ 1899e4d965acSSatish Balay row = nidx[k]; 1900e4d965acSSatish Balay start = ai[row]; 1901e4d965acSSatish Balay end = ai[row+1]; 190204a348a9SBarry Smith for (l = start; l<end ; l++){ 1903efb16452SHong Zhang val = aj[l] ; 1904f1af5d2fSBarry Smith if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;} 1905e4d965acSSatish Balay } 1906e4d965acSSatish Balay } 1907e4d965acSSatish Balay } 1908029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr); 1909e4d965acSSatish Balay } 19106831982aSBarry Smith ierr = PetscBTDestroy(table);CHKERRQ(ierr); 1911606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 19123a40ed3dSBarry Smith PetscFunctionReturn(0); 19134dcbc457SBarry Smith } 191417ab2063SBarry Smith 19150513a670SBarry Smith /* -------------------------------------------------------------- */ 19164a2ae208SSatish Balay #undef __FUNCT__ 19174a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ" 1918dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 19190513a670SBarry Smith { 19200513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 19216849ba73SBarry Smith PetscErrorCode ierr; 1922899cda47SBarry Smith PetscInt i,nz,m = A->rmap.n,n = A->cmap.n,*col; 192397f1f81fSBarry Smith PetscInt *row,*cnew,j,*lens; 192456cd22aeSBarry Smith IS icolp,irowp; 192597f1f81fSBarry Smith PetscInt *cwork; 192632ec9ce4SBarry Smith PetscScalar *vwork; 19270513a670SBarry Smith 19283a40ed3dSBarry Smith PetscFunctionBegin; 19294c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 193056cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 19314c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 193256cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 19330513a670SBarry Smith 19340513a670SBarry Smith /* determine lengths of permuted rows */ 193597f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 19360513a670SBarry Smith for (i=0; i<m; i++) { 19370513a670SBarry Smith lens[row[i]] = a->i[i+1] - a->i[i]; 19380513a670SBarry Smith } 1939f69a0ea3SMatthew Knepley ierr = MatCreate(A->comm,B);CHKERRQ(ierr); 1940f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 1941f204ca49SKris Buschelman ierr = MatSetType(*B,A->type_name);CHKERRQ(ierr); 1942ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 1943606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 19440513a670SBarry Smith 194597f1f81fSBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr); 19460513a670SBarry Smith for (i=0; i<m; i++) { 194732ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 19480513a670SBarry Smith for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];} 1949cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 195032ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 19510513a670SBarry Smith } 1952606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 19533c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 19540513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 19550513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 195656cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 195756cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 195856cd22aeSBarry Smith ierr = ISDestroy(irowp);CHKERRQ(ierr); 195956cd22aeSBarry Smith ierr = ISDestroy(icolp);CHKERRQ(ierr); 19603a40ed3dSBarry Smith PetscFunctionReturn(0); 19610513a670SBarry Smith } 19620513a670SBarry Smith 19634a2ae208SSatish Balay #undef __FUNCT__ 19644a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ" 1965dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 1966cb5b572fSBarry Smith { 1967dfbe8321SBarry Smith PetscErrorCode ierr; 1968cb5b572fSBarry Smith 1969cb5b572fSBarry Smith PetscFunctionBegin; 197033f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 197133f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 1972be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1973be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 1974be6bf707SBarry Smith 1975899cda47SBarry Smith if (a->i[A->rmap.n] != b->i[B->rmap.n]) { 1976634064b4SBarry Smith SETERRQ(PETSC_ERR_ARG_INCOMP,"Number of nonzeros in two matrices are different"); 1977cb5b572fSBarry Smith } 1978899cda47SBarry Smith ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap.n])*sizeof(PetscScalar));CHKERRQ(ierr); 1979cb5b572fSBarry Smith } else { 1980cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1981cb5b572fSBarry Smith } 1982cb5b572fSBarry Smith PetscFunctionReturn(0); 1983cb5b572fSBarry Smith } 1984cb5b572fSBarry Smith 19854a2ae208SSatish Balay #undef __FUNCT__ 19864a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ" 1987dfbe8321SBarry Smith PetscErrorCode MatSetUpPreallocation_SeqAIJ(Mat A) 1988273d9f13SBarry Smith { 1989dfbe8321SBarry Smith PetscErrorCode ierr; 1990273d9f13SBarry Smith 1991273d9f13SBarry Smith PetscFunctionBegin; 1992ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 1993273d9f13SBarry Smith PetscFunctionReturn(0); 1994273d9f13SBarry Smith } 1995273d9f13SBarry Smith 19964a2ae208SSatish Balay #undef __FUNCT__ 19974a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ" 1998dfbe8321SBarry Smith PetscErrorCode MatGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 19996c0721eeSBarry Smith { 20006c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 20016c0721eeSBarry Smith PetscFunctionBegin; 20026c0721eeSBarry Smith *array = a->a; 20036c0721eeSBarry Smith PetscFunctionReturn(0); 20046c0721eeSBarry Smith } 20056c0721eeSBarry Smith 20064a2ae208SSatish Balay #undef __FUNCT__ 20074a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ" 2008dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 20096c0721eeSBarry Smith { 20106c0721eeSBarry Smith PetscFunctionBegin; 20116c0721eeSBarry Smith PetscFunctionReturn(0); 20126c0721eeSBarry Smith } 2013273d9f13SBarry Smith 2014ee4f033dSBarry Smith #undef __FUNCT__ 2015ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ" 2016dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 2017ee4f033dSBarry Smith { 20186849ba73SBarry Smith PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f; 20196849ba73SBarry Smith PetscErrorCode ierr; 202097f1f81fSBarry Smith PetscInt k,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2; 2021efb30889SBarry Smith PetscScalar dx,*y,*xx,*w3_array; 202287828ca2SBarry Smith PetscScalar *vscale_array; 2023ee4f033dSBarry Smith PetscReal epsilon = coloring->error_rel,umin = coloring->umin; 2024ee4f033dSBarry Smith Vec w1,w2,w3; 2025ee4f033dSBarry Smith void *fctx = coloring->fctx; 2026ee4f033dSBarry Smith PetscTruth flg; 2027ee4f033dSBarry Smith 2028ee4f033dSBarry Smith PetscFunctionBegin; 2029ee4f033dSBarry Smith if (!coloring->w1) { 2030ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr); 203152e6d16bSBarry Smith ierr = PetscLogObjectParent(coloring,coloring->w1);CHKERRQ(ierr); 2032ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr); 203352e6d16bSBarry Smith ierr = PetscLogObjectParent(coloring,coloring->w2);CHKERRQ(ierr); 2034ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr); 203552e6d16bSBarry Smith ierr = PetscLogObjectParent(coloring,coloring->w3);CHKERRQ(ierr); 2036ee4f033dSBarry Smith } 2037ee4f033dSBarry Smith w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3; 2038ee4f033dSBarry Smith 2039ee4f033dSBarry Smith ierr = MatSetUnfactored(J);CHKERRQ(ierr); 2040e82a3eeeSBarry Smith ierr = PetscOptionsHasName(coloring->prefix,"-mat_fd_coloring_dont_rezero",&flg);CHKERRQ(ierr); 2041ee4f033dSBarry Smith if (flg) { 2042ae15b995SBarry Smith ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr); 2043ee4f033dSBarry Smith } else { 20440b9b6f31SBarry Smith PetscTruth assembled; 20450b9b6f31SBarry Smith ierr = MatAssembled(J,&assembled);CHKERRQ(ierr); 20460b9b6f31SBarry Smith if (assembled) { 2047ee4f033dSBarry Smith ierr = MatZeroEntries(J);CHKERRQ(ierr); 2048ee4f033dSBarry Smith } 20490b9b6f31SBarry Smith } 2050ee4f033dSBarry Smith 2051ee4f033dSBarry Smith ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr); 2052ee4f033dSBarry Smith ierr = VecGetSize(x1,&N);CHKERRQ(ierr); 2053ee4f033dSBarry Smith 2054ee4f033dSBarry Smith /* 2055ee4f033dSBarry Smith This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets 2056ee4f033dSBarry Smith coloring->F for the coarser grids from the finest 2057ee4f033dSBarry Smith */ 2058ee4f033dSBarry Smith if (coloring->F) { 2059ee4f033dSBarry Smith ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr); 2060ee4f033dSBarry Smith ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr); 2061ee4f033dSBarry Smith if (m1 != m2) { 2062ee4f033dSBarry Smith coloring->F = 0; 2063ee4f033dSBarry Smith } 2064ee4f033dSBarry Smith } 2065ee4f033dSBarry Smith 2066ee4f033dSBarry Smith if (coloring->F) { 2067ee4f033dSBarry Smith w1 = coloring->F; 2068ee4f033dSBarry Smith coloring->F = 0; 2069ee4f033dSBarry Smith } else { 207066f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2071ee4f033dSBarry Smith ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr); 207266f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2073ee4f033dSBarry Smith } 2074ee4f033dSBarry Smith 2075ee4f033dSBarry Smith /* 2076ee4f033dSBarry Smith Compute all the scale factors and share with other processors 2077ee4f033dSBarry Smith */ 20781ebc52fbSHong Zhang ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start; 20791ebc52fbSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start; 2080ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 2081ee4f033dSBarry Smith /* 2082ee4f033dSBarry Smith Loop over each column associated with color adding the 2083ee4f033dSBarry Smith perturbation to the vector w3. 2084ee4f033dSBarry Smith */ 2085ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 2086ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 2087ee4f033dSBarry Smith dx = xx[col]; 2088ee4f033dSBarry Smith if (dx == 0.0) dx = 1.0; 2089ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 2090ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 2091ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 2092ee4f033dSBarry Smith #else 2093ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2094ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2095ee4f033dSBarry Smith #endif 2096ee4f033dSBarry Smith dx *= epsilon; 2097ee4f033dSBarry Smith vscale_array[col] = 1.0/dx; 2098ee4f033dSBarry Smith } 2099ee4f033dSBarry Smith } 21001ebc52fbSHong Zhang vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2101ee4f033dSBarry Smith ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2102ee4f033dSBarry Smith ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2103ee4f033dSBarry Smith 2104ee4f033dSBarry Smith /* ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD); 2105ee4f033dSBarry Smith ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/ 2106ee4f033dSBarry Smith 2107ee4f033dSBarry Smith if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow; 2108ee4f033dSBarry Smith else vscaleforrow = coloring->columnsforrow; 2109ee4f033dSBarry Smith 21101ebc52fbSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2111ee4f033dSBarry Smith /* 2112ee4f033dSBarry Smith Loop over each color 2113ee4f033dSBarry Smith */ 2114ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 211549b058dcSBarry Smith coloring->currentcolor = k; 2116ee4f033dSBarry Smith ierr = VecCopy(x1,w3);CHKERRQ(ierr); 21171ebc52fbSHong Zhang ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start; 2118ee4f033dSBarry Smith /* 2119ee4f033dSBarry Smith Loop over each column associated with color adding the 2120ee4f033dSBarry Smith perturbation to the vector w3. 2121ee4f033dSBarry Smith */ 2122ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 2123ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 2124ee4f033dSBarry Smith dx = xx[col]; 21255b8514ebSBarry Smith if (dx == 0.0) dx = 1.0; 2126ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 2127ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 2128ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 2129ee4f033dSBarry Smith #else 2130ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2131ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2132ee4f033dSBarry Smith #endif 2133ee4f033dSBarry Smith dx *= epsilon; 2134634064b4SBarry Smith if (!PetscAbsScalar(dx)) SETERRQ(PETSC_ERR_PLIB,"Computed 0 differencing parameter"); 2135ee4f033dSBarry Smith w3_array[col] += dx; 2136ee4f033dSBarry Smith } 21371ebc52fbSHong Zhang w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr); 2138ee4f033dSBarry Smith 2139ee4f033dSBarry Smith /* 2140ee4f033dSBarry Smith Evaluate function at x1 + dx (here dx is a vector of perturbations) 2141ee4f033dSBarry Smith */ 2142ee4f033dSBarry Smith 214366f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2144ee4f033dSBarry Smith ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr); 214566f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2146efb30889SBarry Smith ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr); 2147ee4f033dSBarry Smith 2148ee4f033dSBarry Smith /* 2149ee4f033dSBarry Smith Loop over rows of vector, putting results into Jacobian matrix 2150ee4f033dSBarry Smith */ 21511ebc52fbSHong Zhang ierr = VecGetArray(w2,&y);CHKERRQ(ierr); 2152ee4f033dSBarry Smith for (l=0; l<coloring->nrows[k]; l++) { 2153ee4f033dSBarry Smith row = coloring->rows[k][l]; 2154ee4f033dSBarry Smith col = coloring->columnsforrow[k][l]; 2155ee4f033dSBarry Smith y[row] *= vscale_array[vscaleforrow[k][l]]; 2156ee4f033dSBarry Smith srow = row + start; 2157ee4f033dSBarry Smith ierr = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr); 2158ee4f033dSBarry Smith } 21591ebc52fbSHong Zhang ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr); 2160ee4f033dSBarry Smith } 216149b058dcSBarry Smith coloring->currentcolor = k; 21621ebc52fbSHong Zhang ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 21631ebc52fbSHong Zhang xx = xx + start; ierr = VecRestoreArray(x1,&xx);CHKERRQ(ierr); 2164ee4f033dSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2165ee4f033dSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2166ee4f033dSBarry Smith PetscFunctionReturn(0); 2167ee4f033dSBarry Smith } 2168ee4f033dSBarry Smith 2169ac90fabeSBarry Smith #include "petscblaslapack.h" 2170ac90fabeSBarry Smith #undef __FUNCT__ 2171ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ" 2172f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 2173ac90fabeSBarry Smith { 2174dfbe8321SBarry Smith PetscErrorCode ierr; 217597f1f81fSBarry Smith PetscInt i; 2176ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data; 21774ce68768SBarry Smith PetscBLASInt one=1,bnz = (PetscBLASInt)x->nz; 2178ac90fabeSBarry Smith 2179ac90fabeSBarry Smith PetscFunctionBegin; 2180ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 2181f4df32b1SMatthew Knepley PetscScalar alpha = a; 2182f4df32b1SMatthew Knepley BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one); 2183c537a176SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 2184a30b2313SHong Zhang if (y->xtoy && y->XtoY != X) { 2185a30b2313SHong Zhang ierr = PetscFree(y->xtoy);CHKERRQ(ierr); 2186a30b2313SHong Zhang ierr = MatDestroy(y->XtoY);CHKERRQ(ierr); 2187a30b2313SHong Zhang } 2188a30b2313SHong Zhang if (!y->xtoy) { /* get xtoy */ 2189899cda47SBarry Smith ierr = MatAXPYGetxtoy_Private(X->rmap.n,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr); 2190a30b2313SHong Zhang y->XtoY = X; 2191407f6b05SHong Zhang ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 2192c537a176SHong Zhang } 2193f4df32b1SMatthew Knepley for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]); 2194ae15b995SBarry Smith ierr = PetscInfo3(0,"ratio of nnz(X)/nnz(Y): %d/%d = %G\n",x->nz,y->nz,(PetscReal)(x->nz)/y->nz);CHKERRQ(ierr); 2195ac90fabeSBarry Smith } else { 2196f4df32b1SMatthew Knepley ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 2197ac90fabeSBarry Smith } 2198ac90fabeSBarry Smith PetscFunctionReturn(0); 2199ac90fabeSBarry Smith } 2200ac90fabeSBarry Smith 2201521d7252SBarry Smith #undef __FUNCT__ 2202521d7252SBarry Smith #define __FUNCT__ "MatSetBlockSize_SeqAIJ" 2203521d7252SBarry Smith PetscErrorCode MatSetBlockSize_SeqAIJ(Mat A,PetscInt bs) 2204521d7252SBarry Smith { 2205521d7252SBarry Smith PetscFunctionBegin; 2206521d7252SBarry Smith PetscFunctionReturn(0); 2207521d7252SBarry Smith } 2208521d7252SBarry Smith 2209354c94deSBarry Smith #undef __FUNCT__ 2210354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ" 2211354c94deSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatConjugate_SeqAIJ(Mat mat) 2212354c94deSBarry Smith { 2213354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 2214354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2215354c94deSBarry Smith PetscInt i,nz; 2216354c94deSBarry Smith PetscScalar *a; 2217354c94deSBarry Smith 2218354c94deSBarry Smith PetscFunctionBegin; 2219354c94deSBarry Smith nz = aij->nz; 2220354c94deSBarry Smith a = aij->a; 2221354c94deSBarry Smith for (i=0; i<nz; i++) { 2222354c94deSBarry Smith a[i] = PetscConj(a[i]); 2223354c94deSBarry Smith } 2224354c94deSBarry Smith #else 2225354c94deSBarry Smith PetscFunctionBegin; 2226354c94deSBarry Smith #endif 2227354c94deSBarry Smith PetscFunctionReturn(0); 2228354c94deSBarry Smith } 2229354c94deSBarry Smith 2230e34fafa9SBarry Smith #undef __FUNCT__ 2231985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ" 2232985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2233e34fafa9SBarry Smith { 2234e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2235e34fafa9SBarry Smith PetscErrorCode ierr; 2236899cda47SBarry Smith PetscInt i,j,m = A->rmap.n,*ai,*aj,ncols,n; 2237e34fafa9SBarry Smith PetscReal atmp; 2238985db425SBarry Smith PetscScalar *x; 2239e34fafa9SBarry Smith MatScalar *aa; 2240e34fafa9SBarry Smith 2241e34fafa9SBarry Smith PetscFunctionBegin; 2242e34fafa9SBarry Smith if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2243e34fafa9SBarry Smith aa = a->a; 2244e34fafa9SBarry Smith ai = a->i; 2245e34fafa9SBarry Smith aj = a->j; 2246e34fafa9SBarry Smith 2247985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2248e34fafa9SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2249e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2250899cda47SBarry Smith if (n != A->rmap.n) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2251e34fafa9SBarry Smith for (i=0; i<m; i++) { 2252e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 2253985db425SBarry Smith x[i] = 0.0; if (idx) idx[i] = 0; 2254e34fafa9SBarry Smith for (j=0; j<ncols; j++){ 2255985db425SBarry Smith atmp = PetscAbsScalar(*aa); 2256985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2257985db425SBarry Smith aa++; aj++; 2258985db425SBarry Smith } 2259985db425SBarry Smith } 2260985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2261985db425SBarry Smith PetscFunctionReturn(0); 2262985db425SBarry Smith } 2263985db425SBarry Smith 2264985db425SBarry Smith #undef __FUNCT__ 2265985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ" 2266985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2267985db425SBarry Smith { 2268985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2269985db425SBarry Smith PetscErrorCode ierr; 2270985db425SBarry Smith PetscInt i,j,m = A->rmap.n,*ai,*aj,ncols,n; 2271985db425SBarry Smith PetscScalar *x; 2272985db425SBarry Smith MatScalar *aa; 2273985db425SBarry Smith 2274985db425SBarry Smith PetscFunctionBegin; 2275985db425SBarry Smith if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2276985db425SBarry Smith aa = a->a; 2277985db425SBarry Smith ai = a->i; 2278985db425SBarry Smith aj = a->j; 2279985db425SBarry Smith 2280985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2281985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2282985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2283985db425SBarry Smith if (n != A->rmap.n) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2284985db425SBarry Smith for (i=0; i<m; i++) { 2285985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 2286985db425SBarry Smith if (ncols == A->cmap.n) { /* row is dense */ 2287985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 2288985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 2289985db425SBarry Smith x[i] = 0.0; 2290985db425SBarry Smith if (idx) { 2291985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2292985db425SBarry Smith for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */ 2293985db425SBarry Smith if (aj[j] > j) { 2294985db425SBarry Smith idx[i] = j; 2295985db425SBarry Smith break; 2296985db425SBarry Smith } 2297985db425SBarry Smith } 2298985db425SBarry Smith } 2299985db425SBarry Smith } 2300985db425SBarry Smith for (j=0; j<ncols; j++){ 2301985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 2302985db425SBarry Smith aa++; aj++; 2303985db425SBarry Smith } 2304985db425SBarry Smith } 2305985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2306985db425SBarry Smith PetscFunctionReturn(0); 2307985db425SBarry Smith } 2308985db425SBarry Smith 2309985db425SBarry Smith #undef __FUNCT__ 2310985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ" 2311985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2312985db425SBarry Smith { 2313985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2314985db425SBarry Smith PetscErrorCode ierr; 2315985db425SBarry Smith PetscInt i,j,m = A->rmap.n,*ai,*aj,ncols,n; 2316985db425SBarry Smith PetscScalar *x; 2317985db425SBarry Smith MatScalar *aa; 2318985db425SBarry Smith 2319985db425SBarry Smith PetscFunctionBegin; 2320985db425SBarry Smith if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2321985db425SBarry Smith aa = a->a; 2322985db425SBarry Smith ai = a->i; 2323985db425SBarry Smith aj = a->j; 2324985db425SBarry Smith 2325985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2326985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2327985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2328985db425SBarry Smith if (n != A->rmap.n) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2329985db425SBarry Smith for (i=0; i<m; i++) { 2330985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 2331985db425SBarry Smith if (ncols == A->cmap.n) { /* row is dense */ 2332985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 2333985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 2334985db425SBarry Smith x[i] = 0.0; 2335985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 2336985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2337985db425SBarry Smith for (j=0;j<ncols;j++) { 2338985db425SBarry Smith if (aj[j] > j) { 2339985db425SBarry Smith idx[i] = j; 2340985db425SBarry Smith break; 2341985db425SBarry Smith } 2342985db425SBarry Smith } 2343985db425SBarry Smith } 2344985db425SBarry Smith } 2345985db425SBarry Smith for (j=0; j<ncols; j++){ 2346985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 2347985db425SBarry Smith aa++; aj++; 2348e34fafa9SBarry Smith } 2349e34fafa9SBarry Smith } 2350e34fafa9SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2351e34fafa9SBarry Smith PetscFunctionReturn(0); 2352e34fafa9SBarry Smith } 2353e34fafa9SBarry Smith 2354682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 23550a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ, 2356cb5b572fSBarry Smith MatGetRow_SeqAIJ, 2357cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 2358cb5b572fSBarry Smith MatMult_SeqAIJ, 235997304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 23607c922b88SBarry Smith MatMultTranspose_SeqAIJ, 23617c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 2362cb5b572fSBarry Smith MatSolve_SeqAIJ, 2363cb5b572fSBarry Smith MatSolveAdd_SeqAIJ, 23647c922b88SBarry Smith MatSolveTranspose_SeqAIJ, 236597304618SKris Buschelman /*10*/ MatSolveTransposeAdd_SeqAIJ, 2366cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 2367cb5b572fSBarry Smith 0, 236817ab2063SBarry Smith MatRelax_SeqAIJ, 236917ab2063SBarry Smith MatTranspose_SeqAIJ, 237097304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ, 2371cb5b572fSBarry Smith MatEqual_SeqAIJ, 2372cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 2373cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 2374cb5b572fSBarry Smith MatNorm_SeqAIJ, 237597304618SKris Buschelman /*20*/ 0, 2376cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 237717ab2063SBarry Smith MatCompress_SeqAIJ, 2378cb5b572fSBarry Smith MatSetOption_SeqAIJ, 2379cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 238097304618SKris Buschelman /*25*/ MatZeroRows_SeqAIJ, 2381cb5b572fSBarry Smith MatLUFactorSymbolic_SeqAIJ, 2382cb5b572fSBarry Smith MatLUFactorNumeric_SeqAIJ, 2383f76d2b81SHong Zhang MatCholeskyFactorSymbolic_SeqAIJ, 2384a6175056SHong Zhang MatCholeskyFactorNumeric_SeqAIJ, 238597304618SKris Buschelman /*30*/ MatSetUpPreallocation_SeqAIJ, 2386cb5b572fSBarry Smith MatILUFactorSymbolic_SeqAIJ, 2387861ba921SHong Zhang MatICCFactorSymbolic_SeqAIJ, 23886c0721eeSBarry Smith MatGetArray_SeqAIJ, 23896c0721eeSBarry Smith MatRestoreArray_SeqAIJ, 239097304618SKris Buschelman /*35*/ MatDuplicate_SeqAIJ, 2391cb5b572fSBarry Smith 0, 2392cb5b572fSBarry Smith 0, 2393cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 2394cb5b572fSBarry Smith 0, 239597304618SKris Buschelman /*40*/ MatAXPY_SeqAIJ, 2396cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 2397cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 2398cb5b572fSBarry Smith MatGetValues_SeqAIJ, 2399cb5b572fSBarry Smith MatCopy_SeqAIJ, 2400985db425SBarry Smith /*45*/ MatGetRowMax_SeqAIJ, 2401cb5b572fSBarry Smith MatScale_SeqAIJ, 2402cb5b572fSBarry Smith 0, 240379299369SBarry Smith MatDiagonalSet_SeqAIJ, 24046945ee14SBarry Smith MatILUDTFactor_SeqAIJ, 2405521d7252SBarry Smith /*50*/ MatSetBlockSize_SeqAIJ, 24063b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 24073b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 24083b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 2409a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 241097304618SKris Buschelman /*55*/ MatFDColoringCreate_SeqAIJ, 2411b9617806SBarry Smith 0, 24120513a670SBarry Smith 0, 2413cda55fadSBarry Smith MatPermute_SeqAIJ, 2414cda55fadSBarry Smith 0, 241597304618SKris Buschelman /*60*/ 0, 2416b9b97703SBarry Smith MatDestroy_SeqAIJ, 2417b9b97703SBarry Smith MatView_SeqAIJ, 2418357abbc8SBarry Smith 0, 2419ee4f033dSBarry Smith 0, 242097304618SKris Buschelman /*65*/ 0, 2421ee4f033dSBarry Smith 0, 2422ee4f033dSBarry Smith 0, 2423ee4f033dSBarry Smith 0, 2424ee4f033dSBarry Smith 0, 2425985db425SBarry Smith /*70*/ MatGetRowMaxAbs_SeqAIJ, 2426ee4f033dSBarry Smith 0, 2427ee4f033dSBarry Smith MatSetColoring_SeqAIJ, 2428dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC) 2429ee4f033dSBarry Smith MatSetValuesAdic_SeqAIJ, 2430dcf5cc72SBarry Smith #else 2431dcf5cc72SBarry Smith 0, 2432dcf5cc72SBarry Smith #endif 2433ee4f033dSBarry Smith MatSetValuesAdifor_SeqAIJ, 2434b8f8c88eSHong Zhang /*75*/ 0, 243597304618SKris Buschelman 0, 243697304618SKris Buschelman 0, 243797304618SKris Buschelman 0, 243897304618SKris Buschelman 0, 243997304618SKris Buschelman /*80*/ 0, 244097304618SKris Buschelman 0, 244197304618SKris Buschelman 0, 244297304618SKris Buschelman 0, 2443bc011b1eSHong Zhang MatLoad_SeqAIJ, 2444bc011b1eSHong Zhang /*85*/ MatIsSymmetric_SeqAIJ, 24451cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 24466284ec50SHong Zhang 0, 24476284ec50SHong Zhang 0, 2448bc011b1eSHong Zhang 0, 2449bc011b1eSHong Zhang /*90*/ MatMatMult_SeqAIJ_SeqAIJ, 245026be0446SHong Zhang MatMatMultSymbolic_SeqAIJ_SeqAIJ, 245126be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 2452d439da42SKris Buschelman MatPtAP_Basic, 24537ba1a0bfSKris Buschelman MatPtAPSymbolic_SeqAIJ, 24547ba1a0bfSKris Buschelman /*95*/ MatPtAPNumeric_SeqAIJ, 2455bc011b1eSHong Zhang MatMatMultTranspose_SeqAIJ_SeqAIJ, 2456bc011b1eSHong Zhang MatMatMultTransposeSymbolic_SeqAIJ_SeqAIJ, 2457bc011b1eSHong Zhang MatMatMultTransposeNumeric_SeqAIJ_SeqAIJ, 24587ba1a0bfSKris Buschelman MatPtAPSymbolic_SeqAIJ_SeqAIJ, 24597ba1a0bfSKris Buschelman /*100*/MatPtAPNumeric_SeqAIJ_SeqAIJ, 2460609c6c4dSKris Buschelman 0, 2461609c6c4dSKris Buschelman 0, 246287d4246cSBarry Smith MatConjugate_SeqAIJ, 246387d4246cSBarry Smith 0, 246499cafbc1SBarry Smith /*105*/MatSetValuesRow_SeqAIJ, 246599cafbc1SBarry Smith MatRealPart_SeqAIJ, 2466f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 2467f5edf698SHong Zhang 0, 24682bebee5dSHong Zhang 0, 2469985db425SBarry Smith /*110*/MatMatSolve_SeqAIJ, 2470985db425SBarry Smith 0, 2471985db425SBarry Smith MatGetRowMin_SeqAIJ 24729e29f15eSvictorle }; 247317ab2063SBarry Smith 2474fb2e594dSBarry Smith EXTERN_C_BEGIN 24754a2ae208SSatish Balay #undef __FUNCT__ 24764a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ" 2477be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 2478bef8e0ddSBarry Smith { 2479bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 248097f1f81fSBarry Smith PetscInt i,nz,n; 2481bef8e0ddSBarry Smith 2482bef8e0ddSBarry Smith PetscFunctionBegin; 2483bef8e0ddSBarry Smith 2484bef8e0ddSBarry Smith nz = aij->maxnz; 248511c9b30cSMatthew Knepley n = mat->rmap.n; 2486bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 2487bef8e0ddSBarry Smith aij->j[i] = indices[i]; 2488bef8e0ddSBarry Smith } 2489bef8e0ddSBarry Smith aij->nz = nz; 2490bef8e0ddSBarry Smith for (i=0; i<n; i++) { 2491bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 2492bef8e0ddSBarry Smith } 2493bef8e0ddSBarry Smith 2494bef8e0ddSBarry Smith PetscFunctionReturn(0); 2495bef8e0ddSBarry Smith } 2496fb2e594dSBarry Smith EXTERN_C_END 2497bef8e0ddSBarry Smith 24984a2ae208SSatish Balay #undef __FUNCT__ 24994a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices" 2500bef8e0ddSBarry Smith /*@ 2501bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 2502bef8e0ddSBarry Smith in the matrix. 2503bef8e0ddSBarry Smith 2504bef8e0ddSBarry Smith Input Parameters: 2505bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 2506bef8e0ddSBarry Smith - indices - the column indices 2507bef8e0ddSBarry Smith 250815091d37SBarry Smith Level: advanced 250915091d37SBarry Smith 2510bef8e0ddSBarry Smith Notes: 2511bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 2512bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 2513bef8e0ddSBarry Smith of the MatSetValues() operation. 2514bef8e0ddSBarry Smith 2515bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 2516d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 2517bef8e0ddSBarry Smith 2518bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 2519bef8e0ddSBarry Smith 2520b9617806SBarry Smith The indices should start with zero, not one. 2521b9617806SBarry Smith 2522bef8e0ddSBarry Smith @*/ 2523be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 2524bef8e0ddSBarry Smith { 252597f1f81fSBarry Smith PetscErrorCode ierr,(*f)(Mat,PetscInt *); 2526bef8e0ddSBarry Smith 2527bef8e0ddSBarry Smith PetscFunctionBegin; 25284482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 25294482741eSBarry Smith PetscValidPointer(indices,2); 2530c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr); 2531bef8e0ddSBarry Smith if (f) { 2532bef8e0ddSBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 2533bef8e0ddSBarry Smith } else { 2534634064b4SBarry Smith SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to set column indices"); 2535bef8e0ddSBarry Smith } 2536bef8e0ddSBarry Smith PetscFunctionReturn(0); 2537bef8e0ddSBarry Smith } 2538bef8e0ddSBarry Smith 2539be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 2540be6bf707SBarry Smith 2541fb2e594dSBarry Smith EXTERN_C_BEGIN 25424a2ae208SSatish Balay #undef __FUNCT__ 25434a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ" 2544be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatStoreValues_SeqAIJ(Mat mat) 2545be6bf707SBarry Smith { 2546be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 25476849ba73SBarry Smith PetscErrorCode ierr; 2548899cda47SBarry Smith size_t nz = aij->i[mat->rmap.n]; 2549be6bf707SBarry Smith 2550be6bf707SBarry Smith PetscFunctionBegin; 2551be6bf707SBarry Smith if (aij->nonew != 1) { 2552*4e0d8c25SBarry Smith SETERRQ(PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS,PETSC_TRUE);first"); 2553be6bf707SBarry Smith } 2554be6bf707SBarry Smith 2555be6bf707SBarry Smith /* allocate space for values if not already there */ 2556be6bf707SBarry Smith if (!aij->saved_values) { 255787828ca2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr); 25589518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 2559be6bf707SBarry Smith } 2560be6bf707SBarry Smith 2561be6bf707SBarry Smith /* copy values over */ 256287828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 2563be6bf707SBarry Smith PetscFunctionReturn(0); 2564be6bf707SBarry Smith } 2565fb2e594dSBarry Smith EXTERN_C_END 2566be6bf707SBarry Smith 25674a2ae208SSatish Balay #undef __FUNCT__ 2568b9617806SBarry Smith #define __FUNCT__ "MatStoreValues" 2569be6bf707SBarry Smith /*@ 2570be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 2571be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2572be6bf707SBarry Smith nonlinear portion. 2573be6bf707SBarry Smith 2574be6bf707SBarry Smith Collect on Mat 2575be6bf707SBarry Smith 2576be6bf707SBarry Smith Input Parameters: 25770e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 2578be6bf707SBarry Smith 257915091d37SBarry Smith Level: advanced 258015091d37SBarry Smith 2581be6bf707SBarry Smith Common Usage, with SNESSolve(): 2582be6bf707SBarry Smith $ Create Jacobian matrix 2583be6bf707SBarry Smith $ Set linear terms into matrix 2584be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 2585be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 2586be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 2587*4e0d8c25SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS,PETSC_TRUE); 2588be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2589be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 2590be6bf707SBarry Smith $ In your Jacobian routine 2591be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2592be6bf707SBarry Smith $ Set nonlinear terms in matrix 2593be6bf707SBarry Smith 2594be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 2595be6bf707SBarry Smith $ // build linear portion of Jacobian 2596*4e0d8c25SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS,PETSC_TRUE); 2597be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2598be6bf707SBarry Smith $ loop over nonlinear iterations 2599be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2600be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 2601be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 2602be6bf707SBarry Smith $ Solve linear system with Jacobian 2603be6bf707SBarry Smith $ endloop 2604be6bf707SBarry Smith 2605be6bf707SBarry Smith Notes: 2606be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 2607*4e0d8c25SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS,PETSC_TRUE); before 2608be6bf707SBarry Smith calling this routine. 2609be6bf707SBarry Smith 26100c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 26110c468ba9SBarry Smith and does not allocated additional space. 26120c468ba9SBarry Smith 2613be6bf707SBarry Smith .seealso: MatRetrieveValues() 2614be6bf707SBarry Smith 2615be6bf707SBarry Smith @*/ 2616be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatStoreValues(Mat mat) 2617be6bf707SBarry Smith { 2618dfbe8321SBarry Smith PetscErrorCode ierr,(*f)(Mat); 2619be6bf707SBarry Smith 2620be6bf707SBarry Smith PetscFunctionBegin; 26214482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 262229bbc08cSBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 262329bbc08cSBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2624be6bf707SBarry Smith 2625c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void (**)(void))&f);CHKERRQ(ierr); 2626be6bf707SBarry Smith if (f) { 2627be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2628be6bf707SBarry Smith } else { 2629634064b4SBarry Smith SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to store values"); 2630be6bf707SBarry Smith } 2631be6bf707SBarry Smith PetscFunctionReturn(0); 2632be6bf707SBarry Smith } 2633be6bf707SBarry Smith 2634fb2e594dSBarry Smith EXTERN_C_BEGIN 26354a2ae208SSatish Balay #undef __FUNCT__ 26364a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ" 2637be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatRetrieveValues_SeqAIJ(Mat mat) 2638be6bf707SBarry Smith { 2639be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 26406849ba73SBarry Smith PetscErrorCode ierr; 2641899cda47SBarry Smith PetscInt nz = aij->i[mat->rmap.n]; 2642be6bf707SBarry Smith 2643be6bf707SBarry Smith PetscFunctionBegin; 2644be6bf707SBarry Smith if (aij->nonew != 1) { 2645*4e0d8c25SBarry Smith SETERRQ(PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS,PETSC_TRUE);first"); 2646be6bf707SBarry Smith } 2647be6bf707SBarry Smith if (!aij->saved_values) { 2648634064b4SBarry Smith SETERRQ(PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 2649be6bf707SBarry Smith } 2650be6bf707SBarry Smith /* copy values over */ 265187828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 2652be6bf707SBarry Smith PetscFunctionReturn(0); 2653be6bf707SBarry Smith } 2654fb2e594dSBarry Smith EXTERN_C_END 2655be6bf707SBarry Smith 26564a2ae208SSatish Balay #undef __FUNCT__ 26574a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues" 2658be6bf707SBarry Smith /*@ 2659be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 2660be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2661be6bf707SBarry Smith nonlinear portion. 2662be6bf707SBarry Smith 2663be6bf707SBarry Smith Collect on Mat 2664be6bf707SBarry Smith 2665be6bf707SBarry Smith Input Parameters: 2666be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2667be6bf707SBarry Smith 266815091d37SBarry Smith Level: advanced 266915091d37SBarry Smith 2670be6bf707SBarry Smith .seealso: MatStoreValues() 2671be6bf707SBarry Smith 2672be6bf707SBarry Smith @*/ 2673be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatRetrieveValues(Mat mat) 2674be6bf707SBarry Smith { 2675dfbe8321SBarry Smith PetscErrorCode ierr,(*f)(Mat); 2676be6bf707SBarry Smith 2677be6bf707SBarry Smith PetscFunctionBegin; 26784482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 267929bbc08cSBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 268029bbc08cSBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2681be6bf707SBarry Smith 2682c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void (**)(void))&f);CHKERRQ(ierr); 2683be6bf707SBarry Smith if (f) { 2684be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2685be6bf707SBarry Smith } else { 2686634064b4SBarry Smith SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to retrieve values"); 2687be6bf707SBarry Smith } 2688be6bf707SBarry Smith PetscFunctionReturn(0); 2689be6bf707SBarry Smith } 2690be6bf707SBarry Smith 2691f83d6046SBarry Smith 2692be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 26934a2ae208SSatish Balay #undef __FUNCT__ 26944a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ" 269517ab2063SBarry Smith /*@C 2696682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 26970d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 26986e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 269951c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 27002bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 270117ab2063SBarry Smith 2702db81eaa0SLois Curfman McInnes Collective on MPI_Comm 2703db81eaa0SLois Curfman McInnes 270417ab2063SBarry Smith Input Parameters: 2705db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 270617ab2063SBarry Smith . m - number of rows 270717ab2063SBarry Smith . n - number of columns 270817ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 270951c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 27102bd5e0b2SLois Curfman McInnes (possibly different for each row) or PETSC_NULL 271117ab2063SBarry Smith 271217ab2063SBarry Smith Output Parameter: 2713416022c9SBarry Smith . A - the matrix 271417ab2063SBarry Smith 2715b259b22eSLois Curfman McInnes Notes: 271649a6f317SBarry Smith If nnz is given then nz is ignored 271749a6f317SBarry Smith 271817ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 271917ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 27200002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 272144cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 272217ab2063SBarry Smith 272317ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2724a40aa06bSLois Curfman McInnes Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 27253d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 27266da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 272717ab2063SBarry Smith 2728682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 27294fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 2730682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 27316c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 27326c7ebb05SLois Curfman McInnes 27336c7ebb05SLois Curfman McInnes Options Database Keys: 2734698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 2735698d4c6aSKris Buschelman . -mat_inode_limit <limit> - Sets inode limit (max limit=5) 2736db81eaa0SLois Curfman McInnes - -mat_aij_oneindex - Internally use indexing starting at 1 2737db81eaa0SLois Curfman McInnes rather than 0. Note that when calling MatSetValues(), 2738db81eaa0SLois Curfman McInnes the user still MUST index entries starting at 0! 273917ab2063SBarry Smith 2740027ccd11SLois Curfman McInnes Level: intermediate 2741027ccd11SLois Curfman McInnes 274236db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 274336db0b34SBarry Smith 274417ab2063SBarry Smith @*/ 2745be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 274617ab2063SBarry Smith { 2747dfbe8321SBarry Smith PetscErrorCode ierr; 27486945ee14SBarry Smith 27493a40ed3dSBarry Smith PetscFunctionBegin; 2750f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 2751f69a0ea3SMatthew Knepley ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 2752273d9f13SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 2753ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,(PetscInt*)nnz);CHKERRQ(ierr); 2754273d9f13SBarry Smith PetscFunctionReturn(0); 2755273d9f13SBarry Smith } 2756273d9f13SBarry Smith 27574a2ae208SSatish Balay #undef __FUNCT__ 27584a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation" 2759273d9f13SBarry Smith /*@C 2760273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 2761273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 2762273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 2763273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 2764273d9f13SBarry Smith 2765273d9f13SBarry Smith Collective on MPI_Comm 2766273d9f13SBarry Smith 2767273d9f13SBarry Smith Input Parameters: 276845bfc511SMatthew Knepley + B - The matrix 2769273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 2770273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 2771273d9f13SBarry Smith (possibly different for each row) or PETSC_NULL 2772273d9f13SBarry Smith 2773273d9f13SBarry Smith Notes: 277449a6f317SBarry Smith If nnz is given then nz is ignored 277549a6f317SBarry Smith 2776273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 2777273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 2778273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 2779273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 2780273d9f13SBarry Smith 2781273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2782273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 2783273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 2784273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 2785273d9f13SBarry Smith 2786a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 2787a96a251dSBarry Smith entries or columns indices 2788a96a251dSBarry Smith 2789273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 2790273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 2791273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 2792273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 2793273d9f13SBarry Smith 2794273d9f13SBarry Smith Options Database Keys: 2795698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 2796698d4c6aSKris Buschelman . -mat_inode_limit <limit> - Sets inode limit (max limit=5) 2797273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 2798273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 2799273d9f13SBarry Smith the user still MUST index entries starting at 0! 2800273d9f13SBarry Smith 2801273d9f13SBarry Smith Level: intermediate 2802273d9f13SBarry Smith 2803273d9f13SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 2804273d9f13SBarry Smith 2805273d9f13SBarry Smith @*/ 2806be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 2807273d9f13SBarry Smith { 280897f1f81fSBarry Smith PetscErrorCode ierr,(*f)(Mat,PetscInt,const PetscInt[]); 2809a23d5eceSKris Buschelman 2810a23d5eceSKris Buschelman PetscFunctionBegin; 2811a23d5eceSKris Buschelman ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",(void (**)(void))&f);CHKERRQ(ierr); 2812a23d5eceSKris Buschelman if (f) { 2813a23d5eceSKris Buschelman ierr = (*f)(B,nz,nnz);CHKERRQ(ierr); 2814a23d5eceSKris Buschelman } 2815a23d5eceSKris Buschelman PetscFunctionReturn(0); 2816a23d5eceSKris Buschelman } 2817a23d5eceSKris Buschelman 2818a23d5eceSKris Buschelman EXTERN_C_BEGIN 2819a23d5eceSKris Buschelman #undef __FUNCT__ 2820a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ" 2821be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,PetscInt *nnz) 2822a23d5eceSKris Buschelman { 2823273d9f13SBarry Smith Mat_SeqAIJ *b; 2824a43ee2ecSKris Buschelman PetscTruth skipallocation = PETSC_FALSE; 28256849ba73SBarry Smith PetscErrorCode ierr; 282697f1f81fSBarry Smith PetscInt i; 2827273d9f13SBarry Smith 2828273d9f13SBarry Smith PetscFunctionBegin; 2829d5d45c9bSBarry Smith 2830a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 2831c461c341SBarry Smith skipallocation = PETSC_TRUE; 2832c461c341SBarry Smith nz = 0; 2833c461c341SBarry Smith } 2834c461c341SBarry Smith 2835899cda47SBarry Smith B->rmap.bs = B->cmap.bs = 1; 28366148ca0dSBarry Smith ierr = PetscMapSetUp(&B->rmap);CHKERRQ(ierr); 28376148ca0dSBarry Smith ierr = PetscMapSetUp(&B->cmap);CHKERRQ(ierr); 2838899cda47SBarry Smith 2839435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 2840435da068SBarry Smith if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 2841b73539f3SBarry Smith if (nnz) { 2842899cda47SBarry Smith for (i=0; i<B->rmap.n; i++) { 284329bbc08cSBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 2844899cda47SBarry Smith if (nnz[i] > B->cmap.n) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than row length: local row %d value %d rowlength %d",i,nnz[i],B->cmap.n); 2845b73539f3SBarry Smith } 2846b73539f3SBarry Smith } 2847b73539f3SBarry Smith 2848273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 2849273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 2850273d9f13SBarry Smith 2851ab93d7beSBarry Smith if (!skipallocation) { 2852899cda47SBarry Smith ierr = PetscMalloc2(B->rmap.n,PetscInt,&b->imax,B->rmap.n,PetscInt,&b->ilen);CHKERRQ(ierr); 28539518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(B,2*B->rmap.n*sizeof(PetscInt));CHKERRQ(ierr); 2854273d9f13SBarry Smith if (!nnz) { 2855435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 2856273d9f13SBarry Smith else if (nz <= 0) nz = 1; 2857899cda47SBarry Smith for (i=0; i<B->rmap.n; i++) b->imax[i] = nz; 2858899cda47SBarry Smith nz = nz*B->rmap.n; 2859273d9f13SBarry Smith } else { 2860273d9f13SBarry Smith nz = 0; 2861899cda47SBarry Smith for (i=0; i<B->rmap.n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 2862273d9f13SBarry Smith } 2863273d9f13SBarry Smith 2864ab93d7beSBarry Smith /* b->ilen will count nonzeros in each row so far. */ 2865899cda47SBarry Smith for (i=0; i<B->rmap.n; i++) { b->ilen[i] = 0;} 2866ab93d7beSBarry Smith 2867273d9f13SBarry Smith /* allocate the matrix space */ 2868899cda47SBarry Smith ierr = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap.n+1,PetscInt,&b->i);CHKERRQ(ierr); 28699518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(B,(B->rmap.n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 2870bfeeae90SHong Zhang b->i[0] = 0; 2871899cda47SBarry Smith for (i=1; i<B->rmap.n+1; i++) { 28725da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 28735da197adSKris Buschelman } 2874273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 2875e6b907acSBarry Smith b->free_a = PETSC_TRUE; 2876e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 2877c461c341SBarry Smith } else { 2878e6b907acSBarry Smith b->free_a = PETSC_FALSE; 2879e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 2880c461c341SBarry Smith } 2881273d9f13SBarry Smith 2882273d9f13SBarry Smith b->nz = 0; 2883273d9f13SBarry Smith b->maxnz = nz; 2884273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 2885273d9f13SBarry Smith PetscFunctionReturn(0); 2886273d9f13SBarry Smith } 2887a23d5eceSKris Buschelman EXTERN_C_END 2888273d9f13SBarry Smith 2889a1661176SMatthew Knepley #undef __FUNCT__ 2890a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR" 2891a1661176SMatthew Knepley /*@C 2892a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 2893a1661176SMatthew Knepley 2894a1661176SMatthew Knepley Input Parameters: 2895a1661176SMatthew Knepley + B - the matrix 2896a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 2897a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 2898a1661176SMatthew Knepley - v - optional values in the matrix 2899a1661176SMatthew Knepley 2900d58b2322SMatthew Knepley Contributed by: Lisandro Dalchin 2901d58b2322SMatthew Knepley 2902a1661176SMatthew Knepley Level: developer 2903a1661176SMatthew Knepley 2904a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential 2905a1661176SMatthew Knepley 2906a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ 2907a1661176SMatthew Knepley @*/ 2908a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 2909a1661176SMatthew Knepley { 2910a1661176SMatthew Knepley PetscErrorCode (*f)(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]); 2911a1661176SMatthew Knepley PetscErrorCode ierr; 2912a1661176SMatthew Knepley 2913a1661176SMatthew Knepley PetscFunctionBegin; 2914a1661176SMatthew Knepley PetscValidHeaderSpecific(B,MAT_COOKIE,1); 2915a1661176SMatthew Knepley ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",(void (**)(void))&f);CHKERRQ(ierr); 2916a1661176SMatthew Knepley if (f) { 2917a1661176SMatthew Knepley ierr = (*f)(B,i,j,v);CHKERRQ(ierr); 2918a1661176SMatthew Knepley } 2919a1661176SMatthew Knepley PetscFunctionReturn(0); 2920a1661176SMatthew Knepley } 2921a1661176SMatthew Knepley 2922a1661176SMatthew Knepley EXTERN_C_BEGIN 2923a1661176SMatthew Knepley #undef __FUNCT__ 2924a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR_SeqAIJ" 2925b7940d39SSatish Balay PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 2926a1661176SMatthew Knepley { 2927a1661176SMatthew Knepley PetscInt i; 2928a1661176SMatthew Knepley PetscInt m,n; 2929a1661176SMatthew Knepley PetscInt nz; 2930a1661176SMatthew Knepley PetscInt *nnz, nz_max = 0; 2931a1661176SMatthew Knepley PetscScalar *values; 2932a1661176SMatthew Knepley PetscErrorCode ierr; 2933a1661176SMatthew Knepley 2934a1661176SMatthew Knepley PetscFunctionBegin; 2935a1661176SMatthew Knepley ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 2936a1661176SMatthew Knepley 2937b7940d39SSatish Balay if (Ii[0]) { 2938b7940d39SSatish Balay SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 2939a1661176SMatthew Knepley } 2940a1661176SMatthew Knepley ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr); 2941a1661176SMatthew Knepley for(i = 0; i < m; i++) { 2942b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 2943a1661176SMatthew Knepley nz_max = PetscMax(nz_max, nz); 2944a1661176SMatthew Knepley if (nz < 0) { 2945a1661176SMatthew Knepley SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 2946a1661176SMatthew Knepley } 2947a1661176SMatthew Knepley nnz[i] = nz; 2948a1661176SMatthew Knepley } 2949a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 2950a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 2951a1661176SMatthew Knepley 2952a1661176SMatthew Knepley if (v) { 2953a1661176SMatthew Knepley values = (PetscScalar*) v; 2954a1661176SMatthew Knepley } else { 2955a1661176SMatthew Knepley ierr = PetscMalloc((nz_max+1)*sizeof(PetscScalar), &values);CHKERRQ(ierr); 2956a1661176SMatthew Knepley ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr); 2957a1661176SMatthew Knepley } 2958a1661176SMatthew Knepley 2959*4e0d8c25SBarry Smith ierr = MatSetOption(B,MAT_COLUMNS_SORTED,PETSC_TRUE);CHKERRQ(ierr); 2960a1661176SMatthew Knepley 2961a1661176SMatthew Knepley for(i = 0; i < m; i++) { 2962b7940d39SSatish Balay nz = Ii[i+1] - Ii[i]; 2963b7940d39SSatish Balay ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr); 2964a1661176SMatthew Knepley } 2965a1661176SMatthew Knepley 2966a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2967a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2968*4e0d8c25SBarry Smith ierr = MatSetOption(B,MAT_COLUMNS_SORTED,PETSC_FALSE);CHKERRQ(ierr); 2969a1661176SMatthew Knepley 2970a1661176SMatthew Knepley if (!v) { 2971a1661176SMatthew Knepley ierr = PetscFree(values);CHKERRQ(ierr); 2972a1661176SMatthew Knepley } 2973a1661176SMatthew Knepley PetscFunctionReturn(0); 2974a1661176SMatthew Knepley } 2975a1661176SMatthew Knepley EXTERN_C_END 2976a1661176SMatthew Knepley 29770bad9183SKris Buschelman /*MC 2978fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 29790bad9183SKris Buschelman based on compressed sparse row format. 29800bad9183SKris Buschelman 29810bad9183SKris Buschelman Options Database Keys: 29820bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 29830bad9183SKris Buschelman 29840bad9183SKris Buschelman Level: beginner 29850bad9183SKris Buschelman 2986f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 29870bad9183SKris Buschelman M*/ 29880bad9183SKris Buschelman 2989a6175056SHong Zhang EXTERN_C_BEGIN 299017667f90SBarry Smith extern PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqAIJ_SeqCRL(Mat,MatType,MatReuse,Mat*); 299117667f90SBarry Smith EXTERN_C_END 299217667f90SBarry Smith 299317667f90SBarry Smith EXTERN_C_BEGIN 29944a2ae208SSatish Balay #undef __FUNCT__ 29954a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ" 2996be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_SeqAIJ(Mat B) 2997273d9f13SBarry Smith { 2998273d9f13SBarry Smith Mat_SeqAIJ *b; 2999dfbe8321SBarry Smith PetscErrorCode ierr; 300038baddfdSBarry Smith PetscMPIInt size; 3001273d9f13SBarry Smith 3002273d9f13SBarry Smith PetscFunctionBegin; 3003273d9f13SBarry Smith ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr); 3004273d9f13SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 3005273d9f13SBarry Smith 300638f2d2fdSLisandro Dalcin ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr); 3007b0a32e0cSBarry Smith B->data = (void*)b; 3008549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 3009416022c9SBarry Smith B->factor = 0; 301090f02eecSBarry Smith B->mapping = 0; 3011416022c9SBarry Smith b->row = 0; 3012416022c9SBarry Smith b->col = 0; 301382bf6240SBarry Smith b->icol = 0; 3014b810aeb4SBarry Smith b->reallocs = 0; 3015f1e2ffcdSBarry Smith b->sorted = PETSC_FALSE; 301636db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 3017f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 3018416022c9SBarry Smith b->nonew = 0; 3019416022c9SBarry Smith b->diag = 0; 3020416022c9SBarry Smith b->solve_work = 0; 30212a1b7f2aSHong Zhang B->spptr = 0; 3022be6bf707SBarry Smith b->saved_values = 0; 3023d7f994e1SBarry Smith b->idiag = 0; 3024d7f994e1SBarry Smith b->ssor = 0; 3025f1e2ffcdSBarry Smith b->keepzeroedrows = PETSC_FALSE; 3026a30b2313SHong Zhang b->xtoy = 0; 3027a30b2313SHong Zhang b->XtoY = 0; 302873e7a558SHong Zhang b->compressedrow.use = PETSC_FALSE; 3029899cda47SBarry Smith b->compressedrow.nrows = B->rmap.n; 3030d487561eSHong Zhang b->compressedrow.i = PETSC_NULL; 3031d487561eSHong Zhang b->compressedrow.rindex = PETSC_NULL; 3032d487561eSHong Zhang b->compressedrow.checked = PETSC_FALSE; 303388e51ccdSHong Zhang B->same_nonzero = PETSC_FALSE; 303417ab2063SBarry Smith 303535d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 3036f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C", 3037bef8e0ddSBarry Smith "MatSeqAIJSetColumnIndices_SeqAIJ", 3038bc4b532fSSatish Balay MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 3039f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 3040be6bf707SBarry Smith "MatStoreValues_SeqAIJ", 3041bc4b532fSSatish Balay MatStoreValues_SeqAIJ);CHKERRQ(ierr); 3042f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 3043be6bf707SBarry Smith "MatRetrieveValues_SeqAIJ", 3044bc4b532fSSatish Balay MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 3045a6175056SHong Zhang ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C", 3046a6175056SHong Zhang "MatConvert_SeqAIJ_SeqSBAIJ", 3047a6175056SHong Zhang MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 304885fc7724SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C", 304985fc7724SBarry Smith "MatConvert_SeqAIJ_SeqBAIJ", 305085fc7724SBarry Smith MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 3051ba03775dSHong Zhang ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqcsrperm_C", 3052ba03775dSHong Zhang "MatConvert_SeqAIJ_SeqCSRPERM", 3053ba03775dSHong Zhang MatConvert_SeqAIJ_SeqCSRPERM);CHKERRQ(ierr); 305417667f90SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqcrl_C", 305517667f90SBarry Smith "MatConvert_SeqAIJ_SeqCRL", 305617667f90SBarry Smith MatConvert_SeqAIJ_SeqCRL);CHKERRQ(ierr); 30575fbd3699SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C", 30585fbd3699SBarry Smith "MatIsTranspose_SeqAIJ", 30595fbd3699SBarry Smith MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 30601cbb95d3SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsHermitianTranspose_C", 30611cbb95d3SBarry Smith "MatIsHermitianTranspose_SeqAIJ", 30621cbb95d3SBarry Smith MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 3063a23d5eceSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C", 3064a23d5eceSKris Buschelman "MatSeqAIJSetPreallocation_SeqAIJ", 3065a23d5eceSKris Buschelman MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 3066a1661176SMatthew Knepley ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C", 3067a1661176SMatthew Knepley "MatSeqAIJSetPreallocationCSR_SeqAIJ", 3068a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 306905b94e36SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C", 307005b94e36SKris Buschelman "MatReorderForNonzeroDiagonal_SeqAIJ", 307105b94e36SKris Buschelman MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 30724846f1f5SKris Buschelman ierr = MatCreate_Inode(B);CHKERRQ(ierr); 307317667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 30743a40ed3dSBarry Smith PetscFunctionReturn(0); 307517ab2063SBarry Smith } 3076273d9f13SBarry Smith EXTERN_C_END 307717ab2063SBarry Smith 30784a2ae208SSatish Balay #undef __FUNCT__ 30794a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqAIJ" 3080dfbe8321SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 308117ab2063SBarry Smith { 3082416022c9SBarry Smith Mat C; 3083416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 30846849ba73SBarry Smith PetscErrorCode ierr; 3085899cda47SBarry Smith PetscInt i,m = A->rmap.n; 308617ab2063SBarry Smith 30873a40ed3dSBarry Smith PetscFunctionBegin; 30884043dd9cSLois Curfman McInnes *B = 0; 3089f69a0ea3SMatthew Knepley ierr = MatCreate(A->comm,&C);CHKERRQ(ierr); 3090899cda47SBarry Smith ierr = MatSetSizes(C,A->rmap.n,A->cmap.n,A->rmap.n,A->cmap.n);CHKERRQ(ierr); 3091be5d1d56SKris Buschelman ierr = MatSetType(C,A->type_name);CHKERRQ(ierr); 30921d5dac46SHong Zhang ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 30931d5dac46SHong Zhang 3094899cda47SBarry Smith ierr = PetscMapCopy(A->comm,&A->rmap,&C->rmap);CHKERRQ(ierr); 3095899cda47SBarry Smith ierr = PetscMapCopy(A->comm,&A->cmap,&C->cmap);CHKERRQ(ierr); 3096899cda47SBarry Smith 3097273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 3098273d9f13SBarry Smith 3099416022c9SBarry Smith C->factor = A->factor; 31006ad4291fSHong Zhang 3101416022c9SBarry Smith c->row = 0; 3102416022c9SBarry Smith c->col = 0; 310382bf6240SBarry Smith c->icol = 0; 31046ad4291fSHong Zhang c->reallocs = 0; 310517ab2063SBarry Smith 31066ad4291fSHong Zhang C->assembled = PETSC_TRUE; 310717ab2063SBarry Smith 310833b91e9fSSatish Balay ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr); 31099518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 311017ab2063SBarry Smith for (i=0; i<m; i++) { 3111416022c9SBarry Smith c->imax[i] = a->imax[i]; 3112416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 311317ab2063SBarry Smith } 311417ab2063SBarry Smith 311517ab2063SBarry Smith /* allocate the matrix space */ 3116a96a251dSBarry Smith ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr); 31179518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 3118f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 311997f1f81fSBarry Smith ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 312017ab2063SBarry Smith if (m > 0) { 312197f1f81fSBarry Smith ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr); 3122be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 3123bfeeae90SHong Zhang ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 3124be6bf707SBarry Smith } else { 3125bfeeae90SHong Zhang ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 312617ab2063SBarry Smith } 312708480c60SBarry Smith } 312817ab2063SBarry Smith 3129416022c9SBarry Smith c->sorted = a->sorted; 31306ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 3131416022c9SBarry Smith c->roworiented = a->roworiented; 3132416022c9SBarry Smith c->nonew = a->nonew; 3133416022c9SBarry Smith if (a->diag) { 313497f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr); 313552e6d16bSBarry Smith ierr = PetscLogObjectMemory(C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 313617ab2063SBarry Smith for (i=0; i<m; i++) { 3137416022c9SBarry Smith c->diag[i] = a->diag[i]; 313817ab2063SBarry Smith } 31393a40ed3dSBarry Smith } else c->diag = 0; 31406ad4291fSHong Zhang c->solve_work = 0; 31416ad4291fSHong Zhang c->saved_values = 0; 31426ad4291fSHong Zhang c->idiag = 0; 31436ad4291fSHong Zhang c->ssor = 0; 31446ad4291fSHong Zhang c->keepzeroedrows = a->keepzeroedrows; 3145e6b907acSBarry Smith c->free_a = PETSC_TRUE; 3146e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 31476ad4291fSHong Zhang c->xtoy = 0; 31486ad4291fSHong Zhang c->XtoY = 0; 31496ad4291fSHong Zhang 3150416022c9SBarry Smith c->nz = a->nz; 3151416022c9SBarry Smith c->maxnz = a->maxnz; 3152273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 3153754ec7b1SSatish Balay 31546ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 31556ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 31566ad4291fSHong Zhang c->compressedrow.checked = a->compressedrow.checked; 31576ad4291fSHong Zhang if ( a->compressedrow.checked && a->compressedrow.use){ 31586ad4291fSHong Zhang i = a->compressedrow.nrows; 31596ad4291fSHong Zhang ierr = PetscMalloc((2*i+1)*sizeof(PetscInt),&c->compressedrow.i);CHKERRQ(ierr); 31606ad4291fSHong Zhang c->compressedrow.rindex = c->compressedrow.i + i + 1; 31616ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr); 31626ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr); 316327ea64f8SHong Zhang } else { 316427ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 316527ea64f8SHong Zhang c->compressedrow.i = PETSC_NULL; 316627ea64f8SHong Zhang c->compressedrow.rindex = PETSC_NULL; 31676ad4291fSHong Zhang } 316888e51ccdSHong Zhang C->same_nonzero = A->same_nonzero; 31694846f1f5SKris Buschelman ierr = MatDuplicate_Inode(A,cpvalues,&C);CHKERRQ(ierr); 31704846f1f5SKris Buschelman 3171416022c9SBarry Smith *B = C; 3172b0a32e0cSBarry Smith ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 31733a40ed3dSBarry Smith PetscFunctionReturn(0); 317417ab2063SBarry Smith } 317517ab2063SBarry Smith 31764a2ae208SSatish Balay #undef __FUNCT__ 31774a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ" 3178f69a0ea3SMatthew Knepley PetscErrorCode MatLoad_SeqAIJ(PetscViewer viewer, MatType type,Mat *A) 317917ab2063SBarry Smith { 3180416022c9SBarry Smith Mat_SeqAIJ *a; 3181416022c9SBarry Smith Mat B; 31826849ba73SBarry Smith PetscErrorCode ierr; 31833c601197SSatish Balay PetscInt i,sum,nz,header[4],*rowlengths = 0,M,N; 318438baddfdSBarry Smith int fd; 318538baddfdSBarry Smith PetscMPIInt size; 3186bcd2baecSBarry Smith MPI_Comm comm; 318717ab2063SBarry Smith 31883a40ed3dSBarry Smith PetscFunctionBegin; 3189e864ced6SBarry Smith ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 3190d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 319129bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,"view must have one processor"); 3192b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 31930752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 3194552e946dSBarry Smith if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 319517ab2063SBarry Smith M = header[1]; N = header[2]; nz = header[3]; 319617ab2063SBarry Smith 3197d64ed03dSBarry Smith if (nz < 0) { 319829bbc08cSBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 3199d64ed03dSBarry Smith } 3200d64ed03dSBarry Smith 320117ab2063SBarry Smith /* read in row lengths */ 320297f1f81fSBarry Smith ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr); 32030752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 320417ab2063SBarry Smith 32053c601197SSatish Balay /* check if sum of rowlengths is same as nz */ 32063c601197SSatish Balay for (i=0,sum=0; i< M; i++) sum +=rowlengths[i]; 32073c601197SSatish Balay if (sum != nz) SETERRQ2(PETSC_ERR_FILE_READ,"Inconsistant matrix data in file. no-nonzeros = %d, sum-row-lengths = %d\n",nz,sum); 32083c601197SSatish Balay 320917ab2063SBarry Smith /* create our matrix */ 3210f69a0ea3SMatthew Knepley ierr = MatCreate(comm,&B);CHKERRQ(ierr); 3211f69a0ea3SMatthew Knepley ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 3212b3a1e11cSKris Buschelman ierr = MatSetType(B,type);CHKERRQ(ierr); 3213ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(B,0,rowlengths);CHKERRQ(ierr); 3214416022c9SBarry Smith a = (Mat_SeqAIJ*)B->data; 321517ab2063SBarry Smith 32160752156aSBarry Smith ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 321717ab2063SBarry Smith 321817ab2063SBarry Smith /* read in nonzero values */ 32190752156aSBarry Smith ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 322017ab2063SBarry Smith 322117ab2063SBarry Smith /* set matrix "i" values */ 3222efb16452SHong Zhang a->i[0] = 0; 322317ab2063SBarry Smith for (i=1; i<= M; i++) { 3224416022c9SBarry Smith a->i[i] = a->i[i-1] + rowlengths[i-1]; 3225416022c9SBarry Smith a->ilen[i-1] = rowlengths[i-1]; 322617ab2063SBarry Smith } 3227606d414cSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 322817ab2063SBarry Smith 32296d4a8577SBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 32306d4a8577SBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3231b3a1e11cSKris Buschelman *A = B; 32323a40ed3dSBarry Smith PetscFunctionReturn(0); 323317ab2063SBarry Smith } 323417ab2063SBarry Smith 32354a2ae208SSatish Balay #undef __FUNCT__ 3236b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ" 3237dfbe8321SBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg) 32387264ac53SSatish Balay { 32397264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data; 3240dfbe8321SBarry Smith PetscErrorCode ierr; 32417264ac53SSatish Balay 32423a40ed3dSBarry Smith PetscFunctionBegin; 3243bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 3244899cda47SBarry Smith if ((A->rmap.n != B->rmap.n) || (A->cmap.n != B->cmap.n) ||(a->nz != b->nz)) { 3245ca44d042SBarry Smith *flg = PETSC_FALSE; 3246ca44d042SBarry Smith PetscFunctionReturn(0); 3247bcd2baecSBarry Smith } 32487264ac53SSatish Balay 32497264ac53SSatish Balay /* if the a->i are the same */ 3250899cda47SBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->rmap.n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr); 3251abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 32527264ac53SSatish Balay 32537264ac53SSatish Balay /* if a->j are the same */ 325497f1f81fSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr); 3255abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 3256bcd2baecSBarry Smith 3257bcd2baecSBarry Smith /* if a->a are the same */ 325887828ca2SBarry Smith ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 32590f5bd95cSBarry Smith 32603a40ed3dSBarry Smith PetscFunctionReturn(0); 32617264ac53SSatish Balay 32627264ac53SSatish Balay } 326336db0b34SBarry Smith 32644a2ae208SSatish Balay #undef __FUNCT__ 32654a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays" 326605869f15SSatish Balay /*@ 326736db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 326836db0b34SBarry Smith provided by the user. 326936db0b34SBarry Smith 3270c75a6043SHong Zhang Collective on MPI_Comm 327136db0b34SBarry Smith 327236db0b34SBarry Smith Input Parameters: 327336db0b34SBarry Smith + comm - must be an MPI communicator of size 1 327436db0b34SBarry Smith . m - number of rows 327536db0b34SBarry Smith . n - number of columns 327636db0b34SBarry Smith . i - row indices 327736db0b34SBarry Smith . j - column indices 327836db0b34SBarry Smith - a - matrix values 327936db0b34SBarry Smith 328036db0b34SBarry Smith Output Parameter: 328136db0b34SBarry Smith . mat - the matrix 328236db0b34SBarry Smith 328336db0b34SBarry Smith Level: intermediate 328436db0b34SBarry Smith 328536db0b34SBarry Smith Notes: 32860551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 328736db0b34SBarry Smith once the matrix is destroyed 328836db0b34SBarry Smith 328936db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 329036db0b34SBarry Smith 3291bfeeae90SHong Zhang The i and j indices are 0 based 329236db0b34SBarry Smith 3293a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 3294a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 3295a4552177SSatish Balay as shown: 3296a4552177SSatish Balay 3297a4552177SSatish Balay 1 0 0 3298a4552177SSatish Balay 2 0 3 3299a4552177SSatish Balay 4 5 6 3300a4552177SSatish Balay 3301a4552177SSatish Balay i = {0,1,3,6} [size = nrow+1 = 3+1] 3302a4552177SSatish Balay j = {0,0,2,0,1,2} [size = nz = 6] 3303a4552177SSatish Balay v = {1,2,3,4,5,6} [size = nz = 6] 3304a4552177SSatish Balay 33052fb0ec9aSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 330636db0b34SBarry Smith 330736db0b34SBarry Smith @*/ 3308be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat) 330936db0b34SBarry Smith { 3310dfbe8321SBarry Smith PetscErrorCode ierr; 331197f1f81fSBarry Smith PetscInt ii; 331236db0b34SBarry Smith Mat_SeqAIJ *aij; 331336db0b34SBarry Smith 331436db0b34SBarry Smith PetscFunctionBegin; 3315a96a251dSBarry Smith if (i[0]) { 3316634064b4SBarry Smith SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 331736db0b34SBarry Smith } 3318f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 3319f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 3320ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 3321ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 3322ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 3323ab93d7beSBarry Smith ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr); 3324ab93d7beSBarry Smith 332536db0b34SBarry Smith aij->i = i; 332636db0b34SBarry Smith aij->j = j; 332736db0b34SBarry Smith aij->a = a; 332836db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 332936db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 3330e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 3331e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 333236db0b34SBarry Smith 333336db0b34SBarry Smith for (ii=0; ii<m; ii++) { 333436db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 33352515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 333679a5c55eSBarry Smith if (i[ii+1] - i[ii] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Negative row length in i (row indices) row = %d length = %d",ii,i[ii+1] - i[ii]); 333736db0b34SBarry Smith #endif 333836db0b34SBarry Smith } 33392515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 334036db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 334179a5c55eSBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]); 334279a5c55eSBarry Smith if (j[ii] > n - 1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column index to large at location = %d index = %d",ii,j[ii]); 334336db0b34SBarry Smith } 334436db0b34SBarry Smith #endif 334536db0b34SBarry Smith 3346b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3347b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 334836db0b34SBarry Smith PetscFunctionReturn(0); 334936db0b34SBarry Smith } 335036db0b34SBarry Smith 3351cc8ba8e1SBarry Smith #undef __FUNCT__ 3352ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ" 3353dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring) 3354cc8ba8e1SBarry Smith { 3355dfbe8321SBarry Smith PetscErrorCode ierr; 3356cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 335736db0b34SBarry Smith 3358cc8ba8e1SBarry Smith PetscFunctionBegin; 33598ee2e534SBarry Smith if (coloring->ctype == IS_COLORING_GLOBAL) { 3360cc8ba8e1SBarry Smith ierr = ISColoringReference(coloring);CHKERRQ(ierr); 3361cc8ba8e1SBarry Smith a->coloring = coloring; 336212c595b3SBarry Smith } else if (coloring->ctype == IS_COLORING_GHOSTED) { 336397f1f81fSBarry Smith PetscInt i,*larray; 336412c595b3SBarry Smith ISColoring ocoloring; 336508b6dcc0SBarry Smith ISColoringValue *colors; 336612c595b3SBarry Smith 336712c595b3SBarry Smith /* set coloring for diagonal portion */ 3368899cda47SBarry Smith ierr = PetscMalloc((A->cmap.n+1)*sizeof(PetscInt),&larray);CHKERRQ(ierr); 3369899cda47SBarry Smith for (i=0; i<A->cmap.n; i++) { 337012c595b3SBarry Smith larray[i] = i; 337112c595b3SBarry Smith } 3372899cda47SBarry Smith ierr = ISGlobalToLocalMappingApply(A->mapping,IS_GTOLM_MASK,A->cmap.n,larray,PETSC_NULL,larray);CHKERRQ(ierr); 3373899cda47SBarry Smith ierr = PetscMalloc((A->cmap.n+1)*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); 3374899cda47SBarry Smith for (i=0; i<A->cmap.n; i++) { 337512c595b3SBarry Smith colors[i] = coloring->colors[larray[i]]; 337612c595b3SBarry Smith } 337712c595b3SBarry Smith ierr = PetscFree(larray);CHKERRQ(ierr); 337895a80f87SBarry Smith ierr = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap.n,colors,&ocoloring);CHKERRQ(ierr); 337912c595b3SBarry Smith a->coloring = ocoloring; 338012c595b3SBarry Smith } 3381cc8ba8e1SBarry Smith PetscFunctionReturn(0); 3382cc8ba8e1SBarry Smith } 3383cc8ba8e1SBarry Smith 3384dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC) 3385ee4f033dSBarry Smith EXTERN_C_BEGIN 338629c1e371SBarry Smith #include "adic/ad_utils.h" 3387ee4f033dSBarry Smith EXTERN_C_END 3388cc8ba8e1SBarry Smith 3389cc8ba8e1SBarry Smith #undef __FUNCT__ 3390ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ" 3391dfbe8321SBarry Smith PetscErrorCode MatSetValuesAdic_SeqAIJ(Mat A,void *advalues) 3392cc8ba8e1SBarry Smith { 3393cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3394899cda47SBarry Smith PetscInt m = A->rmap.n,*ii = a->i,*jj = a->j,nz,i,j,nlen; 33954440f671SBarry Smith PetscScalar *v = a->a,*values = ((PetscScalar*)advalues)+1; 339608b6dcc0SBarry Smith ISColoringValue *color; 3397cc8ba8e1SBarry Smith 3398cc8ba8e1SBarry Smith PetscFunctionBegin; 3399e005ede5SBarry Smith if (!a->coloring) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix"); 34004440f671SBarry Smith nlen = PetscADGetDerivTypeSize()/sizeof(PetscScalar); 3401cc8ba8e1SBarry Smith color = a->coloring->colors; 3402cc8ba8e1SBarry Smith /* loop over rows */ 3403cc8ba8e1SBarry Smith for (i=0; i<m; i++) { 3404cc8ba8e1SBarry Smith nz = ii[i+1] - ii[i]; 3405cc8ba8e1SBarry Smith /* loop over columns putting computed value into matrix */ 3406cc8ba8e1SBarry Smith for (j=0; j<nz; j++) { 3407cc8ba8e1SBarry Smith *v++ = values[color[*jj++]]; 3408cc8ba8e1SBarry Smith } 34094440f671SBarry Smith values += nlen; /* jump to next row of derivatives */ 3410ee4f033dSBarry Smith } 3411ee4f033dSBarry Smith PetscFunctionReturn(0); 3412ee4f033dSBarry Smith } 3413ee4f033dSBarry Smith #endif 3414ee4f033dSBarry Smith 3415ee4f033dSBarry Smith #undef __FUNCT__ 3416ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ" 341797f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues) 3418ee4f033dSBarry Smith { 3419ee4f033dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3420899cda47SBarry Smith PetscInt m = A->rmap.n,*ii = a->i,*jj = a->j,nz,i,j; 342187828ca2SBarry Smith PetscScalar *v = a->a,*values = (PetscScalar *)advalues; 342208b6dcc0SBarry Smith ISColoringValue *color; 3423ee4f033dSBarry Smith 3424ee4f033dSBarry Smith PetscFunctionBegin; 3425e005ede5SBarry Smith if (!a->coloring) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix"); 3426ee4f033dSBarry Smith color = a->coloring->colors; 3427ee4f033dSBarry Smith /* loop over rows */ 3428ee4f033dSBarry Smith for (i=0; i<m; i++) { 3429ee4f033dSBarry Smith nz = ii[i+1] - ii[i]; 3430ee4f033dSBarry Smith /* loop over columns putting computed value into matrix */ 3431ee4f033dSBarry Smith for (j=0; j<nz; j++) { 3432ee4f033dSBarry Smith *v++ = values[color[*jj++]]; 3433ee4f033dSBarry Smith } 3434ee4f033dSBarry Smith values += nl; /* jump to next row of derivatives */ 3435cc8ba8e1SBarry Smith } 3436cc8ba8e1SBarry Smith PetscFunctionReturn(0); 3437cc8ba8e1SBarry Smith } 343836db0b34SBarry Smith 343981824310SBarry Smith /* 344081824310SBarry Smith Special version for direct calls from Fortran 344181824310SBarry Smith */ 344281824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 344381824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 344481824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 344581824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 344681824310SBarry Smith #endif 344781824310SBarry Smith 344881824310SBarry Smith /* Change these macros so can be used in void function */ 344981824310SBarry Smith #undef CHKERRQ 345081824310SBarry Smith #define CHKERRQ(ierr) CHKERRABORT(A->comm,ierr) 345181824310SBarry Smith #undef SETERRQ2 345281824310SBarry Smith #define SETERRQ2(ierr,b,c,d) CHKERRABORT(A->comm,ierr) 345381824310SBarry Smith 345481824310SBarry Smith EXTERN_C_BEGIN 345581824310SBarry Smith #undef __FUNCT__ 345681824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_" 34571f6cc5b2SSatish Balay void PETSC_STDCALL matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr) 345881824310SBarry Smith { 345981824310SBarry Smith Mat A = *AA; 346081824310SBarry Smith PetscInt m = *mm, n = *nn; 346181824310SBarry Smith InsertMode is = *isis; 346281824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 346381824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 346481824310SBarry Smith PetscInt *imax,*ai,*ailen; 346581824310SBarry Smith PetscErrorCode ierr; 346681824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 346781824310SBarry Smith PetscScalar *ap,value,*aa; 3468edb03aefSBarry Smith PetscTruth ignorezeroentries = a->ignorezeroentries; 346981824310SBarry Smith PetscTruth roworiented = a->roworiented; 347081824310SBarry Smith 347181824310SBarry Smith PetscFunctionBegin; 347281824310SBarry Smith MatPreallocated(A); 347381824310SBarry Smith imax = a->imax; 347481824310SBarry Smith ai = a->i; 347581824310SBarry Smith ailen = a->ilen; 347681824310SBarry Smith aj = a->j; 347781824310SBarry Smith aa = a->a; 347881824310SBarry Smith 347981824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 348081824310SBarry Smith row = im[k]; 348181824310SBarry Smith if (row < 0) continue; 348281824310SBarry Smith #if defined(PETSC_USE_DEBUG) 3483899cda47SBarry Smith if (row >= A->rmap.n) SETERRABORT(A->comm,PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 348481824310SBarry Smith #endif 348581824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 348681824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 348781824310SBarry Smith low = 0; 348881824310SBarry Smith high = nrow; 348981824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 349081824310SBarry Smith if (in[l] < 0) continue; 349181824310SBarry Smith #if defined(PETSC_USE_DEBUG) 3492899cda47SBarry Smith if (in[l] >= A->cmap.n) SETERRABORT(A->comm,PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 349381824310SBarry Smith #endif 349481824310SBarry Smith col = in[l]; 349581824310SBarry Smith if (roworiented) { 349681824310SBarry Smith value = v[l + k*n]; 349781824310SBarry Smith } else { 349881824310SBarry Smith value = v[k + l*m]; 349981824310SBarry Smith } 350081824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 350181824310SBarry Smith 350281824310SBarry Smith if (col <= lastcol) low = 0; else high = nrow; 350381824310SBarry Smith lastcol = col; 350481824310SBarry Smith while (high-low > 5) { 350581824310SBarry Smith t = (low+high)/2; 350681824310SBarry Smith if (rp[t] > col) high = t; 350781824310SBarry Smith else low = t; 350881824310SBarry Smith } 350981824310SBarry Smith for (i=low; i<high; i++) { 351081824310SBarry Smith if (rp[i] > col) break; 351181824310SBarry Smith if (rp[i] == col) { 351281824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 351381824310SBarry Smith else ap[i] = value; 351481824310SBarry Smith goto noinsert; 351581824310SBarry Smith } 351681824310SBarry Smith } 351781824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 351881824310SBarry Smith if (nonew == 1) goto noinsert; 351981824310SBarry Smith if (nonew == -1) SETERRABORT(A->comm,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 3520421e10b8SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap.n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 352181824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 352281824310SBarry Smith /* shift up all the later entries in this row */ 352381824310SBarry Smith for (ii=N; ii>=i; ii--) { 352481824310SBarry Smith rp[ii+1] = rp[ii]; 352581824310SBarry Smith ap[ii+1] = ap[ii]; 352681824310SBarry Smith } 352781824310SBarry Smith rp[i] = col; 352881824310SBarry Smith ap[i] = value; 352981824310SBarry Smith noinsert:; 353081824310SBarry Smith low = i + 1; 353181824310SBarry Smith } 353281824310SBarry Smith ailen[row] = nrow; 353381824310SBarry Smith } 353481824310SBarry Smith A->same_nonzero = PETSC_FALSE; 353581824310SBarry Smith PetscFunctionReturnVoid(); 353681824310SBarry Smith } 353781824310SBarry Smith EXTERN_C_END 3538