13a7fca6bSBarry Smith 2*5c897100SBarry Smith /*$Id: aij.c,v 1.382 2001/08/24 15:26:27 bsmith Exp bsmith $*/ 3d5d45c9bSBarry Smith /* 43369ce9aSBarry Smith Defines the basic matrix operations for the AIJ (compressed row) 5d5d45c9bSBarry Smith matrix storage format. 6d5d45c9bSBarry Smith */ 73369ce9aSBarry Smith 8a375949dSSatish Balay #include "petscsys.h" /*I "petscmat.h" I*/ 970f55243SBarry Smith #include "src/mat/impls/aij/seq/aij.h" 10f5eb4b81SSatish Balay #include "src/vec/vecimpl.h" 11f5eb4b81SSatish Balay #include "src/inline/spops.h" 128d195f9aSBarry Smith #include "src/inline/dot.h" 130a835dfdSSatish Balay #include "petscbt.h" 1417ab2063SBarry Smith 15a2ce50c7SBarry Smith 16ca44d042SBarry Smith EXTERN int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**); 1717ab2063SBarry Smith 184a2ae208SSatish Balay #undef __FUNCT__ 194a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ" 2036db0b34SBarry Smith int MatGetRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *m,int **ia,int **ja,PetscTruth *done) 2117ab2063SBarry Smith { 22416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 236945ee14SBarry Smith int ierr,i,ishift; 2417ab2063SBarry Smith 253a40ed3dSBarry Smith PetscFunctionBegin; 2631625ec5SSatish Balay *m = A->m; 273a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 286945ee14SBarry Smith ishift = a->indexshift; 2953e63a63SBarry Smith if (symmetric && !A->structurally_symmetric) { 30273d9f13SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr); 316945ee14SBarry Smith } else if (oshift == 0 && ishift == -1) { 32435da068SBarry Smith int nz = a->i[A->m] - 1; 333b2fbd54SBarry Smith /* malloc space and subtract 1 from i and j indices */ 34b0a32e0cSBarry Smith ierr = PetscMalloc((A->m+1)*sizeof(int),ia);CHKERRQ(ierr); 35b0a32e0cSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(int),ja);CHKERRQ(ierr); 363b2fbd54SBarry Smith for (i=0; i<nz; i++) (*ja)[i] = a->j[i] - 1; 37273d9f13SBarry Smith for (i=0; i<A->m+1; i++) (*ia)[i] = a->i[i] - 1; 386945ee14SBarry Smith } else if (oshift == 1 && ishift == 0) { 39435da068SBarry Smith int nz = a->i[A->m]; 403b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 411bc30dd5SBarry Smith ierr = PetscMalloc((A->m+1)*sizeof(int),ia);CHKERRQ(ierr); 42b0a32e0cSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(int),ja);CHKERRQ(ierr); 433b2fbd54SBarry Smith for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1; 44273d9f13SBarry Smith for (i=0; i<A->m+1; i++) (*ia)[i] = a->i[i] + 1; 456945ee14SBarry Smith } else { 466945ee14SBarry Smith *ia = a->i; *ja = a->j; 47a2ce50c7SBarry Smith } 483a40ed3dSBarry Smith PetscFunctionReturn(0); 49a2744918SBarry Smith } 50a2744918SBarry Smith 514a2ae208SSatish Balay #undef __FUNCT__ 524a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ" 5336db0b34SBarry Smith int MatRestoreRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja,PetscTruth *done) 546945ee14SBarry Smith { 556945ee14SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 56606d414cSSatish Balay int ishift = a->indexshift,ierr; 576945ee14SBarry Smith 583a40ed3dSBarry Smith PetscFunctionBegin; 593a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 6053e63a63SBarry Smith if ((symmetric && !A->structurally_symmetric) || (oshift == 0 && ishift == -1) || (oshift == 1 && ishift == 0)) { 61606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 62606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 63bcd2baecSBarry Smith } 643a40ed3dSBarry Smith PetscFunctionReturn(0); 6517ab2063SBarry Smith } 6617ab2063SBarry Smith 674a2ae208SSatish Balay #undef __FUNCT__ 684a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ" 6936db0b34SBarry Smith int MatGetColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done) 703b2fbd54SBarry Smith { 713b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 72a93ec695SBarry Smith int ierr,i,ishift = a->indexshift,*collengths,*cia,*cja,n = A->n,m = A->m; 73a93ec695SBarry Smith int nz = a->i[m]+ishift,row,*jj,mr,col; 743b2fbd54SBarry Smith 753a40ed3dSBarry Smith PetscFunctionBegin; 763b2fbd54SBarry Smith *nn = A->n; 773a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 783b2fbd54SBarry Smith if (symmetric) { 79273d9f13SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr); 803b2fbd54SBarry Smith } else { 81b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&collengths);CHKERRQ(ierr); 82549d3d68SSatish Balay ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr); 83b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&cia);CHKERRQ(ierr); 84b0a32e0cSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(int),&cja);CHKERRQ(ierr); 853b2fbd54SBarry Smith jj = a->j; 863b2fbd54SBarry Smith for (i=0; i<nz; i++) { 873b2fbd54SBarry Smith collengths[jj[i] + ishift]++; 883b2fbd54SBarry Smith } 893b2fbd54SBarry Smith cia[0] = oshift; 903b2fbd54SBarry Smith for (i=0; i<n; i++) { 913b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 923b2fbd54SBarry Smith } 93549d3d68SSatish Balay ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr); 943b2fbd54SBarry Smith jj = a->j; 95a93ec695SBarry Smith for (row=0; row<m; row++) { 96a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 97a93ec695SBarry Smith for (i=0; i<mr; i++) { 983b2fbd54SBarry Smith col = *jj++ + ishift; 993b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 1003b2fbd54SBarry Smith } 1013b2fbd54SBarry Smith } 102606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 1033b2fbd54SBarry Smith *ia = cia; *ja = cja; 1043b2fbd54SBarry Smith } 1053a40ed3dSBarry Smith PetscFunctionReturn(0); 1063b2fbd54SBarry Smith } 1073b2fbd54SBarry Smith 1084a2ae208SSatish Balay #undef __FUNCT__ 1094a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ" 11036db0b34SBarry Smith int MatRestoreColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja,PetscTruth *done) 1113b2fbd54SBarry Smith { 112606d414cSSatish Balay int ierr; 113606d414cSSatish Balay 1143a40ed3dSBarry Smith PetscFunctionBegin; 1153a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 1163b2fbd54SBarry Smith 117606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 118606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 1193b2fbd54SBarry Smith 1203a40ed3dSBarry Smith PetscFunctionReturn(0); 1213b2fbd54SBarry Smith } 1223b2fbd54SBarry Smith 123227d817aSBarry Smith #define CHUNKSIZE 15 12417ab2063SBarry Smith 1254a2ae208SSatish Balay #undef __FUNCT__ 1264a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ" 12787828ca2SBarry Smith int MatSetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,PetscScalar *v,InsertMode is) 12817ab2063SBarry Smith { 129416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 130416022c9SBarry Smith int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted = a->sorted; 131273d9f13SBarry Smith int *imax = a->imax,*ai = a->i,*ailen = a->ilen; 132549d3d68SSatish Balay int *aj = a->j,nonew = a->nonew,shift = a->indexshift,ierr; 13387828ca2SBarry Smith PetscScalar *ap,value,*aa = a->a; 13436db0b34SBarry Smith PetscTruth ignorezeroentries = ((a->ignorezeroentries && is == ADD_VALUES) ? PETSC_TRUE:PETSC_FALSE); 135273d9f13SBarry Smith PetscTruth roworiented = a->roworiented; 13617ab2063SBarry Smith 1373a40ed3dSBarry Smith PetscFunctionBegin; 13817ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 139416022c9SBarry Smith row = im[k]; 1405ef9f2a5SBarry Smith if (row < 0) continue; 141aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 142273d9f13SBarry Smith if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m); 1433b2fbd54SBarry Smith #endif 14417ab2063SBarry Smith rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 14517ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 146416022c9SBarry Smith low = 0; 14717ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 1485ef9f2a5SBarry Smith if (in[l] < 0) continue; 149aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 150273d9f13SBarry Smith if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n); 1513b2fbd54SBarry Smith #endif 1524b0e389bSBarry Smith col = in[l] - shift; 1534b0e389bSBarry Smith if (roworiented) { 1545ef9f2a5SBarry Smith value = v[l + k*n]; 155bef8e0ddSBarry Smith } else { 1564b0e389bSBarry Smith value = v[k + l*m]; 1574b0e389bSBarry Smith } 15836db0b34SBarry Smith if (value == 0.0 && ignorezeroentries) continue; 15936db0b34SBarry Smith 160416022c9SBarry Smith if (!sorted) low = 0; high = nrow; 161416022c9SBarry Smith while (high-low > 5) { 162416022c9SBarry Smith t = (low+high)/2; 163416022c9SBarry Smith if (rp[t] > col) high = t; 164416022c9SBarry Smith else low = t; 16517ab2063SBarry Smith } 166416022c9SBarry Smith for (i=low; i<high; i++) { 16717ab2063SBarry Smith if (rp[i] > col) break; 16817ab2063SBarry Smith if (rp[i] == col) { 169416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 17017ab2063SBarry Smith else ap[i] = value; 17117ab2063SBarry Smith goto noinsert; 17217ab2063SBarry Smith } 17317ab2063SBarry Smith } 174c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 17529bbc08cSBarry Smith else if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%d,%d) in the matrix",row,col); 17617ab2063SBarry Smith if (nrow >= rmax) { 17717ab2063SBarry Smith /* there is no extra room in row, therefore enlarge */ 178273d9f13SBarry Smith int new_nz = ai[A->m] + CHUNKSIZE,len,*new_i,*new_j; 17987828ca2SBarry Smith PetscScalar *new_a; 18017ab2063SBarry Smith 18129bbc08cSBarry Smith if (nonew == -2) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%d,%d) in the matrix requiring new malloc()",row,col); 18296854ed6SLois Curfman McInnes 18317ab2063SBarry Smith /* malloc new storage space */ 18487828ca2SBarry Smith len = new_nz*(sizeof(int)+sizeof(PetscScalar))+(A->m+1)*sizeof(int); 185b0a32e0cSBarry Smith ierr = PetscMalloc(len,&new_a);CHKERRQ(ierr); 18617ab2063SBarry Smith new_j = (int*)(new_a + new_nz); 18717ab2063SBarry Smith new_i = new_j + new_nz; 18817ab2063SBarry Smith 18917ab2063SBarry Smith /* copy over old data into new slots */ 19017ab2063SBarry Smith for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];} 191273d9f13SBarry Smith for (ii=row+1; ii<A->m+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;} 192549d3d68SSatish Balay ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow+shift)*sizeof(int));CHKERRQ(ierr); 193416022c9SBarry Smith len = (new_nz - CHUNKSIZE - ai[row] - nrow - shift); 194549d3d68SSatish Balay ierr = PetscMemcpy(new_j+ai[row]+shift+nrow+CHUNKSIZE,aj+ai[row]+shift+nrow,len*sizeof(int));CHKERRQ(ierr); 19587828ca2SBarry Smith ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow+shift)*sizeof(PetscScalar));CHKERRQ(ierr); 19687828ca2SBarry Smith ierr = PetscMemcpy(new_a+ai[row]+shift+nrow+CHUNKSIZE,aa+ai[row]+shift+nrow,len*sizeof(PetscScalar));CHKERRQ(ierr); 19717ab2063SBarry Smith /* free up old matrix storage */ 198606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 199606d414cSSatish Balay if (!a->singlemalloc) { 200606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 201606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 202606d414cSSatish Balay } 203416022c9SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 204f1e2ffcdSBarry Smith a->singlemalloc = PETSC_TRUE; 20517ab2063SBarry Smith 20617ab2063SBarry Smith rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 207416022c9SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 20887828ca2SBarry Smith PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + sizeof(PetscScalar))); 209416022c9SBarry Smith a->maxnz += CHUNKSIZE; 210b810aeb4SBarry Smith a->reallocs++; 21117ab2063SBarry Smith } 212416022c9SBarry Smith N = nrow++ - 1; a->nz++; 213416022c9SBarry Smith /* shift up all the later entries in this row */ 214416022c9SBarry Smith for (ii=N; ii>=i; ii--) { 21517ab2063SBarry Smith rp[ii+1] = rp[ii]; 21617ab2063SBarry Smith ap[ii+1] = ap[ii]; 21717ab2063SBarry Smith } 21817ab2063SBarry Smith rp[i] = col; 21917ab2063SBarry Smith ap[i] = value; 22017ab2063SBarry Smith noinsert:; 221416022c9SBarry Smith low = i + 1; 22217ab2063SBarry Smith } 22317ab2063SBarry Smith ailen[row] = nrow; 22417ab2063SBarry Smith } 2253a40ed3dSBarry Smith PetscFunctionReturn(0); 22617ab2063SBarry Smith } 22717ab2063SBarry Smith 2284a2ae208SSatish Balay #undef __FUNCT__ 2294a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ" 23087828ca2SBarry Smith int MatGetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,PetscScalar *v) 2317eb43aa7SLois Curfman McInnes { 2327eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 233b49de8d1SLois Curfman McInnes int *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 2347eb43aa7SLois Curfman McInnes int *ai = a->i,*ailen = a->ilen,shift = a->indexshift; 23587828ca2SBarry Smith PetscScalar *ap,*aa = a->a,zero = 0.0; 2367eb43aa7SLois Curfman McInnes 2373a40ed3dSBarry Smith PetscFunctionBegin; 2387eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 2397eb43aa7SLois Curfman McInnes row = im[k]; 24029bbc08cSBarry Smith if (row < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %d",row); 241273d9f13SBarry Smith if (row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: %d",row); 2427eb43aa7SLois Curfman McInnes rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 2437eb43aa7SLois Curfman McInnes nrow = ailen[row]; 2447eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 24529bbc08cSBarry Smith if (in[l] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %d",in[l]); 246273d9f13SBarry Smith if (in[l] >= A->n) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: %d",in[l]); 2477eb43aa7SLois Curfman McInnes col = in[l] - shift; 2487eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 2497eb43aa7SLois Curfman McInnes while (high-low > 5) { 2507eb43aa7SLois Curfman McInnes t = (low+high)/2; 2517eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 2527eb43aa7SLois Curfman McInnes else low = t; 2537eb43aa7SLois Curfman McInnes } 2547eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 2557eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 2567eb43aa7SLois Curfman McInnes if (rp[i] == col) { 257b49de8d1SLois Curfman McInnes *v++ = ap[i]; 2587eb43aa7SLois Curfman McInnes goto finished; 2597eb43aa7SLois Curfman McInnes } 2607eb43aa7SLois Curfman McInnes } 261b49de8d1SLois Curfman McInnes *v++ = zero; 2627eb43aa7SLois Curfman McInnes finished:; 2637eb43aa7SLois Curfman McInnes } 2647eb43aa7SLois Curfman McInnes } 2653a40ed3dSBarry Smith PetscFunctionReturn(0); 2667eb43aa7SLois Curfman McInnes } 2677eb43aa7SLois Curfman McInnes 26817ab2063SBarry Smith 2694a2ae208SSatish Balay #undef __FUNCT__ 2704a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary" 271b0a32e0cSBarry Smith int MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer) 27217ab2063SBarry Smith { 273416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 274416022c9SBarry Smith int i,fd,*col_lens,ierr; 27517ab2063SBarry Smith 2763a40ed3dSBarry Smith PetscFunctionBegin; 277b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 278b0a32e0cSBarry Smith ierr = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr); 279416022c9SBarry Smith col_lens[0] = MAT_COOKIE; 280273d9f13SBarry Smith col_lens[1] = A->m; 281273d9f13SBarry Smith col_lens[2] = A->n; 282416022c9SBarry Smith col_lens[3] = a->nz; 283416022c9SBarry Smith 284416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 285273d9f13SBarry Smith for (i=0; i<A->m; i++) { 286416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 28717ab2063SBarry Smith } 288273d9f13SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr); 289606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 290416022c9SBarry Smith 291416022c9SBarry Smith /* store column indices (zero start index) */ 292416022c9SBarry Smith if (a->indexshift) { 293416022c9SBarry Smith for (i=0; i<a->nz; i++) a->j[i]--; 29417ab2063SBarry Smith } 2950752156aSBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,0);CHKERRQ(ierr); 296416022c9SBarry Smith if (a->indexshift) { 297416022c9SBarry Smith for (i=0; i<a->nz; i++) a->j[i]++; 29817ab2063SBarry Smith } 299416022c9SBarry Smith 300416022c9SBarry Smith /* store nonzero values */ 3010752156aSBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,0);CHKERRQ(ierr); 3023a40ed3dSBarry Smith PetscFunctionReturn(0); 30317ab2063SBarry Smith } 304416022c9SBarry Smith 3054a2ae208SSatish Balay #undef __FUNCT__ 3064a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII" 307b0a32e0cSBarry Smith int MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 308416022c9SBarry Smith { 309416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 310fb9695e5SSatish Balay int ierr,i,j,m = A->m,shift = a->indexshift; 311fb9695e5SSatish Balay char *name; 312f3ef73ceSBarry Smith PetscViewerFormat format; 31317ab2063SBarry Smith 3143a40ed3dSBarry Smith PetscFunctionBegin; 315435da068SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 316b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 317fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_INFO_LONG || format == PETSC_VIEWER_ASCII_INFO) { 3186831982aSBarry Smith if (a->inode.size) { 319b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"using I-node routines: found %d nodes, limit used is %d\n",a->inode.node_count,a->inode.limit);CHKERRQ(ierr); 3206831982aSBarry Smith } else { 321b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"not using I-node routines\n");CHKERRQ(ierr); 3226831982aSBarry Smith } 323fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_MATLAB) { 324d00d2cf4SBarry Smith int nofinalvalue = 0; 325273d9f13SBarry Smith if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->n-!shift)) { 326d00d2cf4SBarry Smith nofinalvalue = 1; 327d00d2cf4SBarry Smith } 328b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 329b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %d %d \n",m,A->n);CHKERRQ(ierr); 330b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %d \n",a->nz);CHKERRQ(ierr); 331b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%d,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 332b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 33317ab2063SBarry Smith 33417ab2063SBarry Smith for (i=0; i<m; i++) { 335416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 336aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 337b0a32e0cSBarry 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); 33817ab2063SBarry Smith #else 339b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%d %d %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr); 34017ab2063SBarry Smith #endif 34117ab2063SBarry Smith } 34217ab2063SBarry Smith } 343d00d2cf4SBarry Smith if (nofinalvalue) { 344b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%d %d %18.16e\n",m,A->n,0.0);CHKERRQ(ierr); 345d00d2cf4SBarry Smith } 346fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 347b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 348fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 349b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 35044cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 351b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr); 35244cd7ae7SLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 353aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 35436db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 355b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g + %g i",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 35636db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 357b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g - %g i",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 35836db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 359b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 3606831982aSBarry Smith } 36144cd7ae7SLois Curfman McInnes #else 362b0a32e0cSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);} 36344cd7ae7SLois Curfman McInnes #endif 36444cd7ae7SLois Curfman McInnes } 365b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 36644cd7ae7SLois Curfman McInnes } 367b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 368fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 369496be53dSLois Curfman McInnes int nzd=0,fshift=1,*sptr; 370b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 371b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&sptr);CHKERRQ(ierr); 372496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 373496be53dSLois Curfman McInnes sptr[i] = nzd+1; 374496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 375496be53dSLois Curfman McInnes if (a->j[j] >= i) { 376aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 37736db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 378496be53dSLois Curfman McInnes #else 379496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 380496be53dSLois Curfman McInnes #endif 381496be53dSLois Curfman McInnes } 382496be53dSLois Curfman McInnes } 383496be53dSLois Curfman McInnes } 3842e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 385b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %d\n\n",m,nzd);CHKERRQ(ierr); 3862e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 387b0a32e0cSBarry 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);} 388b0a32e0cSBarry 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);} 389b0a32e0cSBarry 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);} 390b0a32e0cSBarry Smith else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);} 391b0a32e0cSBarry Smith else if (i<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);} 392b0a32e0cSBarry Smith else {ierr = PetscViewerASCIIPrintf(viewer," %d\n",sptr[i]);CHKERRQ(ierr);} 393496be53dSLois Curfman McInnes } 394b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 395606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 396496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 397496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 398b0a32e0cSBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %d ",a->j[j]+fshift);CHKERRQ(ierr);} 399496be53dSLois Curfman McInnes } 400b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 401496be53dSLois Curfman McInnes } 402b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 403496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 404496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 405496be53dSLois Curfman McInnes if (a->j[j] >= i) { 406aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 40736db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 408b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 4096831982aSBarry Smith } 410496be53dSLois Curfman McInnes #else 411b0a32e0cSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);} 412496be53dSLois Curfman McInnes #endif 413496be53dSLois Curfman McInnes } 414496be53dSLois Curfman McInnes } 415b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 416496be53dSLois Curfman McInnes } 417b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 418fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 41902594712SBarry Smith int cnt = 0,jcnt; 42087828ca2SBarry Smith PetscScalar value; 42102594712SBarry Smith 422b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 42302594712SBarry Smith for (i=0; i<m; i++) { 42402594712SBarry Smith jcnt = 0; 425273d9f13SBarry Smith for (j=0; j<A->n; j++) { 426e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 42702594712SBarry Smith value = a->a[cnt++]; 428e24b481bSBarry Smith jcnt++; 42902594712SBarry Smith } else { 43002594712SBarry Smith value = 0.0; 43102594712SBarry Smith } 432aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 433b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr); 43402594712SBarry Smith #else 435b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr); 43602594712SBarry Smith #endif 43702594712SBarry Smith } 438b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 43902594712SBarry Smith } 440b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 4413a40ed3dSBarry Smith } else { 442b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 44317ab2063SBarry Smith for (i=0; i<m; i++) { 444b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr); 445416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 446aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 44736db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 448b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g + %g i",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 44936db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 450b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g - %g i",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 4513a40ed3dSBarry Smith } else { 452b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 45317ab2063SBarry Smith } 45417ab2063SBarry Smith #else 455b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 45617ab2063SBarry Smith #endif 45717ab2063SBarry Smith } 458b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 45917ab2063SBarry Smith } 460b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 46117ab2063SBarry Smith } 462b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 4633a40ed3dSBarry Smith PetscFunctionReturn(0); 464416022c9SBarry Smith } 465416022c9SBarry Smith 4664a2ae208SSatish Balay #undef __FUNCT__ 4674a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom" 468b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 469416022c9SBarry Smith { 470480ef9eaSBarry Smith Mat A = (Mat) Aa; 471416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 472273d9f13SBarry Smith int ierr,i,j,m = A->m,shift = a->indexshift,color; 47336db0b34SBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0; 474b0a32e0cSBarry Smith PetscViewer viewer; 475f3ef73ceSBarry Smith PetscViewerFormat format; 476cddf8d76SBarry Smith 4773a40ed3dSBarry Smith PetscFunctionBegin; 478480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 479b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 48019bcc07fSBarry Smith 481b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 482416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 4830513a670SBarry Smith 484fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 4850513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 486b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 487416022c9SBarry Smith for (i=0; i<m; i++) { 488cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 489416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 490cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 491aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 49236db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 493cddf8d76SBarry Smith #else 494cddf8d76SBarry Smith if (a->a[j] >= 0.) continue; 495cddf8d76SBarry Smith #endif 496b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 497cddf8d76SBarry Smith } 498cddf8d76SBarry Smith } 499b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 500cddf8d76SBarry Smith for (i=0; i<m; i++) { 501cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 502cddf8d76SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 503cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 504cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 505b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 506cddf8d76SBarry Smith } 507cddf8d76SBarry Smith } 508b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 509cddf8d76SBarry Smith for (i=0; i<m; i++) { 510cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 511cddf8d76SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 512cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 513aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 51436db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 515cddf8d76SBarry Smith #else 516cddf8d76SBarry Smith if (a->a[j] <= 0.) continue; 517cddf8d76SBarry Smith #endif 518b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 519416022c9SBarry Smith } 520416022c9SBarry Smith } 5210513a670SBarry Smith } else { 5220513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 5230513a670SBarry Smith /* first determine max of all nonzero values */ 5240513a670SBarry Smith int nz = a->nz,count; 525b0a32e0cSBarry Smith PetscDraw popup; 52636db0b34SBarry Smith PetscReal scale; 5270513a670SBarry Smith 5280513a670SBarry Smith for (i=0; i<nz; i++) { 5290513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 5300513a670SBarry Smith } 531b0a32e0cSBarry Smith scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv; 532b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 533b0a32e0cSBarry Smith if (popup) {ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);} 5340513a670SBarry Smith count = 0; 5350513a670SBarry Smith for (i=0; i<m; i++) { 5360513a670SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 5370513a670SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 5380513a670SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 539b0a32e0cSBarry Smith color = PETSC_DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(a->a[count])); 540b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 5410513a670SBarry Smith count++; 5420513a670SBarry Smith } 5430513a670SBarry Smith } 5440513a670SBarry Smith } 545480ef9eaSBarry Smith PetscFunctionReturn(0); 546480ef9eaSBarry Smith } 547cddf8d76SBarry Smith 5484a2ae208SSatish Balay #undef __FUNCT__ 5494a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw" 550b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 551480ef9eaSBarry Smith { 552480ef9eaSBarry Smith int ierr; 553b0a32e0cSBarry Smith PetscDraw draw; 55436db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 555480ef9eaSBarry Smith PetscTruth isnull; 556480ef9eaSBarry Smith 557480ef9eaSBarry Smith PetscFunctionBegin; 558b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 559b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 560480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 561480ef9eaSBarry Smith 562480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 563273d9f13SBarry Smith xr = A->n; yr = A->m; h = yr/10.0; w = xr/10.0; 564480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 565b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 566b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 567480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 5683a40ed3dSBarry Smith PetscFunctionReturn(0); 569416022c9SBarry Smith } 570416022c9SBarry Smith 5714a2ae208SSatish Balay #undef __FUNCT__ 5724a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ" 573b0a32e0cSBarry Smith int MatView_SeqAIJ(Mat A,PetscViewer viewer) 574416022c9SBarry Smith { 575416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 576bcd2baecSBarry Smith int ierr; 5776831982aSBarry Smith PetscTruth issocket,isascii,isbinary,isdraw; 578416022c9SBarry Smith 5793a40ed3dSBarry Smith PetscFunctionBegin; 580b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr); 581b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);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); 5840f5bd95cSBarry Smith if (issocket) { 58501820c62SBarry Smith if (a->indexshift) { 58629bbc08cSBarry Smith SETERRQ(1,"Can only socket send sparse matrix with 0 based indexing"); 58701820c62SBarry Smith } 588b0a32e0cSBarry Smith ierr = PetscViewerSocketPutSparse_Private(viewer,A->m,A->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr); 5890f5bd95cSBarry Smith } else if (isascii) { 5903a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 5910f5bd95cSBarry Smith } else if (isbinary) { 5923a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 5930f5bd95cSBarry Smith } else if (isdraw) { 5943a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 5955cd90555SBarry Smith } else { 59629bbc08cSBarry Smith SETERRQ1(1,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name); 59717ab2063SBarry Smith } 5983a40ed3dSBarry Smith PetscFunctionReturn(0); 59917ab2063SBarry Smith } 60019bcc07fSBarry Smith 6013a7fca6bSBarry Smith EXTERN int Mat_AIJ_CheckInode(Mat,PetscTruth); 6024a2ae208SSatish Balay #undef __FUNCT__ 6034a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ" 6048f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 60517ab2063SBarry Smith { 606416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 60741c01911SSatish Balay int fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax,ierr; 608273d9f13SBarry Smith int m = A->m,*ip,N,*ailen = a->ilen,shift = a->indexshift,rmax = 0; 60987828ca2SBarry Smith PetscScalar *aa = a->a,*ap; 61017ab2063SBarry Smith 6113a40ed3dSBarry Smith PetscFunctionBegin; 6123a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 61317ab2063SBarry Smith 61443ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 61517ab2063SBarry Smith for (i=1; i<m; i++) { 616416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 61717ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 61894a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 61917ab2063SBarry Smith if (fshift) { 6200f5bd95cSBarry Smith ip = aj + ai[i] + shift; 6210f5bd95cSBarry Smith ap = aa + ai[i] + shift; 62217ab2063SBarry Smith N = ailen[i]; 62317ab2063SBarry Smith for (j=0; j<N; j++) { 62417ab2063SBarry Smith ip[j-fshift] = ip[j]; 62517ab2063SBarry Smith ap[j-fshift] = ap[j]; 62617ab2063SBarry Smith } 62717ab2063SBarry Smith } 62817ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 62917ab2063SBarry Smith } 63017ab2063SBarry Smith if (m) { 63117ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 63217ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 63317ab2063SBarry Smith } 63417ab2063SBarry Smith /* reset ilen and imax for each row */ 63517ab2063SBarry Smith for (i=0; i<m; i++) { 63617ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 63717ab2063SBarry Smith } 638416022c9SBarry Smith a->nz = ai[m] + shift; 63917ab2063SBarry Smith 64017ab2063SBarry Smith /* diagonals may have moved, so kill the diagonal pointers */ 641416022c9SBarry Smith if (fshift && a->diag) { 642606d414cSSatish Balay ierr = PetscFree(a->diag);CHKERRQ(ierr); 643b0a32e0cSBarry Smith PetscLogObjectMemory(A,-(m+1)*sizeof(int)); 644416022c9SBarry Smith a->diag = 0; 64517ab2063SBarry Smith } 646b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded,%d used\n",m,A->n,fshift,a->nz); 647b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues() is %d\n",a->reallocs); 648b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Most nonzeros in any row is %d\n",rmax); 649dd5f02e7SSatish Balay a->reallocs = 0; 6504e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift; 65136db0b34SBarry Smith a->rmax = rmax; 6524e220ebcSLois Curfman McInnes 65376dd722bSSatish Balay /* check out for identical nodes. If found, use inode functions */ 6543a7fca6bSBarry Smith ierr = Mat_AIJ_CheckInode(A,(PetscTruth)(!fshift));CHKERRQ(ierr); 6553a40ed3dSBarry Smith PetscFunctionReturn(0); 65617ab2063SBarry Smith } 65717ab2063SBarry Smith 6584a2ae208SSatish Balay #undef __FUNCT__ 6594a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ" 6608f6be9afSLois Curfman McInnes int MatZeroEntries_SeqAIJ(Mat A) 66117ab2063SBarry Smith { 662416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 663549d3d68SSatish Balay int ierr; 6643a40ed3dSBarry Smith 6653a40ed3dSBarry Smith PetscFunctionBegin; 66687828ca2SBarry Smith ierr = PetscMemzero(a->a,(a->i[A->m]+a->indexshift)*sizeof(PetscScalar));CHKERRQ(ierr); 6673a40ed3dSBarry Smith PetscFunctionReturn(0); 66817ab2063SBarry Smith } 669416022c9SBarry Smith 6704a2ae208SSatish Balay #undef __FUNCT__ 6714a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ" 672e1311b90SBarry Smith int MatDestroy_SeqAIJ(Mat A) 67317ab2063SBarry Smith { 674416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 67582bf6240SBarry Smith int ierr; 676d5d45c9bSBarry Smith 6773a40ed3dSBarry Smith PetscFunctionBegin; 678aa482453SBarry Smith #if defined(PETSC_USE_LOG) 679b0a32e0cSBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz); 68017ab2063SBarry Smith #endif 68136db0b34SBarry Smith if (a->freedata) { 682606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 683606d414cSSatish Balay if (!a->singlemalloc) { 684606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 685606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 686606d414cSSatish Balay } 68736db0b34SBarry Smith } 688c38d4ed2SBarry Smith if (a->row) { 689c38d4ed2SBarry Smith ierr = ISDestroy(a->row);CHKERRQ(ierr); 690c38d4ed2SBarry Smith } 691c38d4ed2SBarry Smith if (a->col) { 692c38d4ed2SBarry Smith ierr = ISDestroy(a->col);CHKERRQ(ierr); 693c38d4ed2SBarry Smith } 694606d414cSSatish Balay if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);} 695606d414cSSatish Balay if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);} 696606d414cSSatish Balay if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);} 697273d9f13SBarry Smith if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);} 698606d414cSSatish Balay if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);} 699606d414cSSatish Balay if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);} 70082bf6240SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 701606d414cSSatish Balay if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);} 702cc8ba8e1SBarry Smith if (a->coloring) {ierr = ISColoringDestroy(a->coloring);CHKERRQ(ierr);} 703606d414cSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 7043a40ed3dSBarry Smith PetscFunctionReturn(0); 70517ab2063SBarry Smith } 70617ab2063SBarry Smith 7074a2ae208SSatish Balay #undef __FUNCT__ 7084a2ae208SSatish Balay #define __FUNCT__ "MatCompress_SeqAIJ" 7098f6be9afSLois Curfman McInnes int MatCompress_SeqAIJ(Mat A) 71017ab2063SBarry Smith { 7113a40ed3dSBarry Smith PetscFunctionBegin; 7123a40ed3dSBarry Smith PetscFunctionReturn(0); 71317ab2063SBarry Smith } 71417ab2063SBarry Smith 7154a2ae208SSatish Balay #undef __FUNCT__ 7164a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ" 7178f6be9afSLois Curfman McInnes int MatSetOption_SeqAIJ(Mat A,MatOption op) 71817ab2063SBarry Smith { 719416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 7203a40ed3dSBarry Smith 7213a40ed3dSBarry Smith PetscFunctionBegin; 722a65d3064SKris Buschelman switch (op) { 723a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 724a65d3064SKris Buschelman a->roworiented = PETSC_TRUE; 725a65d3064SKris Buschelman break; 726a65d3064SKris Buschelman case MAT_KEEP_ZEROED_ROWS: 727a65d3064SKris Buschelman a->keepzeroedrows = PETSC_TRUE; 728a65d3064SKris Buschelman break; 729a65d3064SKris Buschelman case MAT_COLUMN_ORIENTED: 730a65d3064SKris Buschelman a->roworiented = PETSC_FALSE; 731a65d3064SKris Buschelman break; 732a65d3064SKris Buschelman case MAT_COLUMNS_SORTED: 733a65d3064SKris Buschelman a->sorted = PETSC_TRUE; 734a65d3064SKris Buschelman break; 735a65d3064SKris Buschelman case MAT_COLUMNS_UNSORTED: 736a65d3064SKris Buschelman a->sorted = PETSC_FALSE; 737a65d3064SKris Buschelman break; 738a65d3064SKris Buschelman case MAT_NO_NEW_NONZERO_LOCATIONS: 739a65d3064SKris Buschelman a->nonew = 1; 740a65d3064SKris Buschelman break; 741a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 742a65d3064SKris Buschelman a->nonew = -1; 743a65d3064SKris Buschelman break; 744a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 745a65d3064SKris Buschelman a->nonew = -2; 746a65d3064SKris Buschelman break; 747a65d3064SKris Buschelman case MAT_YES_NEW_NONZERO_LOCATIONS: 748a65d3064SKris Buschelman a->nonew = 0; 749a65d3064SKris Buschelman break; 750a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 751a65d3064SKris Buschelman a->ignorezeroentries = PETSC_TRUE; 752a65d3064SKris Buschelman break; 753a65d3064SKris Buschelman case MAT_USE_INODES: 754a65d3064SKris Buschelman a->inode.use = PETSC_TRUE; 755a65d3064SKris Buschelman break; 756a65d3064SKris Buschelman case MAT_DO_NOT_USE_INODES: 757a65d3064SKris Buschelman a->inode.use = PETSC_FALSE; 758a65d3064SKris Buschelman break; 759a65d3064SKris Buschelman case MAT_ROWS_SORTED: 760a65d3064SKris Buschelman case MAT_ROWS_UNSORTED: 761a65d3064SKris Buschelman case MAT_YES_NEW_DIAGONALS: 762a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 763a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 764d03495bdSKris Buschelman case MAT_USE_SINGLE_PRECISION_SOLVES: 765b0a32e0cSBarry Smith PetscLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n"); 766a65d3064SKris Buschelman break; 767a65d3064SKris Buschelman case MAT_NO_NEW_DIAGONALS: 76829bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS"); 769a65d3064SKris Buschelman break; 770a65d3064SKris Buschelman case MAT_INODE_LIMIT_1: 771a65d3064SKris Buschelman a->inode.limit = 1; 772a65d3064SKris Buschelman break; 773a65d3064SKris Buschelman case MAT_INODE_LIMIT_2: 774a65d3064SKris Buschelman a->inode.limit = 2; 775a65d3064SKris Buschelman break; 776a65d3064SKris Buschelman case MAT_INODE_LIMIT_3: 777a65d3064SKris Buschelman a->inode.limit = 3; 778a65d3064SKris Buschelman break; 779a65d3064SKris Buschelman case MAT_INODE_LIMIT_4: 780a65d3064SKris Buschelman a->inode.limit = 4; 781a65d3064SKris Buschelman break; 782a65d3064SKris Buschelman case MAT_INODE_LIMIT_5: 783a65d3064SKris Buschelman a->inode.limit = 5; 784a65d3064SKris Buschelman break; 785a65d3064SKris Buschelman default: 786a65d3064SKris Buschelman SETERRQ(PETSC_ERR_SUP,"unknown option"); 787a65d3064SKris Buschelman break; 788a65d3064SKris Buschelman } 7893a40ed3dSBarry Smith PetscFunctionReturn(0); 79017ab2063SBarry Smith } 79117ab2063SBarry Smith 7924a2ae208SSatish Balay #undef __FUNCT__ 7934a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ" 7948f6be9afSLois Curfman McInnes int MatGetDiagonal_SeqAIJ(Mat A,Vec v) 79517ab2063SBarry Smith { 796416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 7973a40ed3dSBarry Smith int i,j,n,shift = a->indexshift,ierr; 79887828ca2SBarry Smith PetscScalar *x,zero = 0.0; 79917ab2063SBarry Smith 8003a40ed3dSBarry Smith PetscFunctionBegin; 8013a40ed3dSBarry Smith ierr = VecSet(&zero,v);CHKERRQ(ierr); 80236db0b34SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 80336db0b34SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 804273d9f13SBarry Smith if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 805273d9f13SBarry Smith for (i=0; i<A->m; i++) { 806416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 807416022c9SBarry Smith if (a->j[j]+shift == i) { 808416022c9SBarry Smith x[i] = a->a[j]; 80917ab2063SBarry Smith break; 81017ab2063SBarry Smith } 81117ab2063SBarry Smith } 81217ab2063SBarry Smith } 81336db0b34SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 8143a40ed3dSBarry Smith PetscFunctionReturn(0); 81517ab2063SBarry Smith } 81617ab2063SBarry Smith 817d5d45c9bSBarry Smith 8184a2ae208SSatish Balay #undef __FUNCT__ 8194a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ" 8207c922b88SBarry Smith int MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 82117ab2063SBarry Smith { 822416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 823*5c897100SBarry Smith PetscScalar *x,*y; 824*5c897100SBarry Smith int ierr,m = A->m,shift = a->indexshift; 825*5c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 826*5c897100SBarry Smith PetscScalar *v,alpha; 827*5c897100SBarry Smith int n,i,*idx; 828*5c897100SBarry Smith #endif 82917ab2063SBarry Smith 8303a40ed3dSBarry Smith PetscFunctionBegin; 8312e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 832e1311b90SBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 833e1311b90SBarry Smith ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 83417ab2063SBarry Smith y = y + shift; /* shift for Fortran start by 1 indexing */ 835*5c897100SBarry Smith 836*5c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 837*5c897100SBarry Smith fortranmulttransposeaddaij_(&m,x,a->i,a->j+shift,a->a+shift,y); 838*5c897100SBarry Smith #else 83917ab2063SBarry Smith for (i=0; i<m; i++) { 840416022c9SBarry Smith idx = a->j + a->i[i] + shift; 841416022c9SBarry Smith v = a->a + a->i[i] + shift; 842416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 84317ab2063SBarry Smith alpha = x[i]; 84417ab2063SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 84517ab2063SBarry Smith } 846*5c897100SBarry Smith #endif 847b0a32e0cSBarry Smith PetscLogFlops(2*a->nz); 848e1311b90SBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 849e1311b90SBarry Smith ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 8503a40ed3dSBarry Smith PetscFunctionReturn(0); 85117ab2063SBarry Smith } 85217ab2063SBarry Smith 8534a2ae208SSatish Balay #undef __FUNCT__ 854*5c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ" 855*5c897100SBarry Smith int MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 856*5c897100SBarry Smith { 857*5c897100SBarry Smith PetscScalar zero = 0.0;; 858*5c897100SBarry Smith int ierr; 859*5c897100SBarry Smith 860*5c897100SBarry Smith PetscFunctionBegin; 861*5c897100SBarry Smith ierr = VecSet(&zero,yy);CHKERRQ(ierr); 862*5c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 863*5c897100SBarry Smith PetscFunctionReturn(0); 864*5c897100SBarry Smith } 865*5c897100SBarry Smith 866*5c897100SBarry Smith 867*5c897100SBarry Smith #undef __FUNCT__ 8684a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ" 86944cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 87017ab2063SBarry Smith { 871416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 87287828ca2SBarry Smith PetscScalar *x,*y,*v,sum; 873273d9f13SBarry Smith int ierr,m = A->m,*idx,shift = a->indexshift,*ii; 874aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 875e36a17ebSSatish Balay int n,i,jrow,j; 876e36a17ebSSatish Balay #endif 87717ab2063SBarry Smith 878aa482453SBarry Smith #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 879fee21e36SBarry Smith #pragma disjoint(*x,*y,*v) 880fee21e36SBarry Smith #endif 881fee21e36SBarry Smith 8823a40ed3dSBarry Smith PetscFunctionBegin; 883e1311b90SBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 884e1311b90SBarry Smith ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 88517ab2063SBarry Smith x = x + shift; /* shift for Fortran start by 1 indexing */ 886416022c9SBarry Smith idx = a->j; 887d64ed03dSBarry Smith v = a->a; 888416022c9SBarry Smith ii = a->i; 889aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 89029b5ca8aSSatish Balay fortranmultaij_(&m,x,ii,idx+shift,v+shift,y); 8918d195f9aSBarry Smith #else 892d64ed03dSBarry Smith v += shift; /* shift for Fortran start by 1 indexing */ 893d64ed03dSBarry Smith idx += shift; 89417ab2063SBarry Smith for (i=0; i<m; i++) { 8959ea0dfa2SSatish Balay jrow = ii[i]; 8969ea0dfa2SSatish Balay n = ii[i+1] - jrow; 89717ab2063SBarry Smith sum = 0.0; 8989ea0dfa2SSatish Balay for (j=0; j<n; j++) { 8999ea0dfa2SSatish Balay sum += v[jrow]*x[idx[jrow]]; jrow++; 9009ea0dfa2SSatish Balay } 90117ab2063SBarry Smith y[i] = sum; 90217ab2063SBarry Smith } 9038d195f9aSBarry Smith #endif 904b0a32e0cSBarry Smith PetscLogFlops(2*a->nz - m); 905e1311b90SBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 906e1311b90SBarry Smith ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 9073a40ed3dSBarry Smith PetscFunctionReturn(0); 90817ab2063SBarry Smith } 90917ab2063SBarry Smith 9104a2ae208SSatish Balay #undef __FUNCT__ 9114a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ" 91244cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 91317ab2063SBarry Smith { 914416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 91587828ca2SBarry Smith PetscScalar *x,*y,*z,*v,sum; 916273d9f13SBarry Smith int ierr,m = A->m,*idx,shift = a->indexshift,*ii; 917aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 918e36a17ebSSatish Balay int n,i,jrow,j; 919e36a17ebSSatish Balay #endif 9209ea0dfa2SSatish Balay 9213a40ed3dSBarry Smith PetscFunctionBegin; 922e1311b90SBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 923e1311b90SBarry Smith ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 9242e8a6d31SBarry Smith if (zz != yy) { 925e1311b90SBarry Smith ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 9262e8a6d31SBarry Smith } else { 9272e8a6d31SBarry Smith z = y; 9282e8a6d31SBarry Smith } 92917ab2063SBarry Smith x = x + shift; /* shift for Fortran start by 1 indexing */ 930cddf8d76SBarry Smith idx = a->j; 931d64ed03dSBarry Smith v = a->a; 932cddf8d76SBarry Smith ii = a->i; 933aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 93429b5ca8aSSatish Balay fortranmultaddaij_(&m,x,ii,idx+shift,v+shift,y,z); 93502ab625aSSatish Balay #else 936d64ed03dSBarry Smith v += shift; /* shift for Fortran start by 1 indexing */ 937d64ed03dSBarry Smith idx += shift; 93817ab2063SBarry Smith for (i=0; i<m; i++) { 9399ea0dfa2SSatish Balay jrow = ii[i]; 9409ea0dfa2SSatish Balay n = ii[i+1] - jrow; 94117ab2063SBarry Smith sum = y[i]; 9429ea0dfa2SSatish Balay for (j=0; j<n; j++) { 9439ea0dfa2SSatish Balay sum += v[jrow]*x[idx[jrow]]; jrow++; 9449ea0dfa2SSatish Balay } 94517ab2063SBarry Smith z[i] = sum; 94617ab2063SBarry Smith } 94702ab625aSSatish Balay #endif 948b0a32e0cSBarry Smith PetscLogFlops(2*a->nz); 949e1311b90SBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 950e1311b90SBarry Smith ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 9512e8a6d31SBarry Smith if (zz != yy) { 952e1311b90SBarry Smith ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 9532e8a6d31SBarry Smith } 9543a40ed3dSBarry Smith PetscFunctionReturn(0); 95517ab2063SBarry Smith } 95617ab2063SBarry Smith 95717ab2063SBarry Smith /* 95817ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 95917ab2063SBarry Smith */ 9604a2ae208SSatish Balay #undef __FUNCT__ 9614a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ" 962f1e2ffcdSBarry Smith int MatMarkDiagonal_SeqAIJ(Mat A) 96317ab2063SBarry Smith { 964416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 965b0a32e0cSBarry Smith int i,j,*diag,m = A->m,shift = a->indexshift,ierr; 96617ab2063SBarry Smith 9673a40ed3dSBarry Smith PetscFunctionBegin; 968f1e2ffcdSBarry Smith if (a->diag) PetscFunctionReturn(0); 969f1e2ffcdSBarry Smith 970b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&diag);CHKERRQ(ierr); 971b0a32e0cSBarry Smith PetscLogObjectMemory(A,(m+1)*sizeof(int)); 972273d9f13SBarry Smith for (i=0; i<A->m; i++) { 97335b0346bSBarry Smith diag[i] = a->i[i+1]; 974416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 975416022c9SBarry Smith if (a->j[j]+shift == i) { 97617ab2063SBarry Smith diag[i] = j - shift; 97717ab2063SBarry Smith break; 97817ab2063SBarry Smith } 97917ab2063SBarry Smith } 98017ab2063SBarry Smith } 981416022c9SBarry Smith a->diag = diag; 9823a40ed3dSBarry Smith PetscFunctionReturn(0); 98317ab2063SBarry Smith } 98417ab2063SBarry Smith 985be5855fcSBarry Smith /* 986be5855fcSBarry Smith Checks for missing diagonals 987be5855fcSBarry Smith */ 9884a2ae208SSatish Balay #undef __FUNCT__ 9894a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ" 990f1e2ffcdSBarry Smith int MatMissingDiagonal_SeqAIJ(Mat A) 991be5855fcSBarry Smith { 992be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 993f1e2ffcdSBarry Smith int *diag,*jj = a->j,i,shift = a->indexshift,ierr; 994be5855fcSBarry Smith 995be5855fcSBarry Smith PetscFunctionBegin; 996f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 997f1e2ffcdSBarry Smith diag = a->diag; 998273d9f13SBarry Smith for (i=0; i<A->m; i++) { 999be5855fcSBarry Smith if (jj[diag[i]+shift] != i-shift) { 100029bbc08cSBarry Smith SETERRQ1(1,"Matrix is missing diagonal number %d",i); 1001be5855fcSBarry Smith } 1002be5855fcSBarry Smith } 1003be5855fcSBarry Smith PetscFunctionReturn(0); 1004be5855fcSBarry Smith } 1005be5855fcSBarry Smith 10064a2ae208SSatish Balay #undef __FUNCT__ 10074a2ae208SSatish Balay #define __FUNCT__ "MatRelax_SeqAIJ" 100836db0b34SBarry Smith int MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,int its,Vec xx) 100917ab2063SBarry Smith { 1010416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 101187828ca2SBarry Smith PetscScalar *x,*b,*bs, d,*xs,sum,*v = a->a,*t=0,scale,*ts,*xb,*idiag=0; 1012273d9f13SBarry Smith int ierr,*idx,*diag,n = A->n,m = A->m,i,shift = a->indexshift; 101317ab2063SBarry Smith 10143a40ed3dSBarry Smith PetscFunctionBegin; 1015e1311b90SBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 1016fb2e594dSBarry Smith if (xx != bb) { 1017e1311b90SBarry Smith ierr = VecGetArray(bb,&b);CHKERRQ(ierr); 1018fb2e594dSBarry Smith } else { 1019fb2e594dSBarry Smith b = x; 1020fb2e594dSBarry Smith } 1021fb2e594dSBarry Smith 1022f1e2ffcdSBarry Smith if (!a->diag) {ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);} 1023416022c9SBarry Smith diag = a->diag; 1024416022c9SBarry Smith xs = x + shift; /* shifted by one for index start of a or a->j*/ 102517ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 102617ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 102717ab2063SBarry Smith bs = b + shift; 102817ab2063SBarry Smith for (i=0; i<m; i++) { 1029416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 1030416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1031b0a32e0cSBarry Smith PetscLogFlops(2*n-1); 1032416022c9SBarry Smith idx = a->j + diag[i] + (!shift); 1033416022c9SBarry Smith v = a->a + diag[i] + (!shift); 103417ab2063SBarry Smith sum = b[i]*d/omega; 103517ab2063SBarry Smith SPARSEDENSEDOT(sum,bs,v,idx,n); 103617ab2063SBarry Smith x[i] = sum; 103717ab2063SBarry Smith } 1038cb5b572fSBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 1039fb2e594dSBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 10403a40ed3dSBarry Smith PetscFunctionReturn(0); 104117ab2063SBarry Smith } 1042c783ea89SBarry Smith 1043c783ea89SBarry Smith /* setup workspace for Eisenstat */ 1044c783ea89SBarry Smith if (flag & SOR_EISENSTAT) { 1045c783ea89SBarry Smith if (!a->idiag) { 104687828ca2SBarry Smith ierr = PetscMalloc(2*m*sizeof(PetscScalar),&a->idiag);CHKERRQ(ierr); 1047c783ea89SBarry Smith a->ssor = a->idiag + m; 1048c783ea89SBarry Smith v = a->a; 1049c783ea89SBarry Smith for (i=0; i<m; i++) { a->idiag[i] = 1.0/v[diag[i]];} 1050c783ea89SBarry Smith } 1051c783ea89SBarry Smith t = a->ssor; 1052c783ea89SBarry Smith idiag = a->idiag; 1053c783ea89SBarry Smith } 1054fc3d8934SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1055fc3d8934SBarry Smith U is upper triangular, E is diagonal; This routine applies 1056fc3d8934SBarry Smith 1057fc3d8934SBarry Smith (L + E)^{-1} A (U + E)^{-1} 1058fc3d8934SBarry Smith 1059fc3d8934SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 1060fc3d8934SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 106148af12d7SBarry Smith is the relaxation factor. 1062fc3d8934SBarry Smith */ 1063fc3d8934SBarry Smith 106448af12d7SBarry Smith if (flag == SOR_APPLY_LOWER) { 106529bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 106648af12d7SBarry Smith } else if ((flag & SOR_EISENSTAT) && omega == 1.0 && shift == 0 && fshift == 0.0) { 106748af12d7SBarry Smith /* special case for omega = 1.0 saves flops and some integer ops */ 106887828ca2SBarry Smith PetscScalar *v2; 106948af12d7SBarry Smith 1070733d66baSBarry Smith v2 = a->a; 1071fc3d8934SBarry Smith /* x = (E + U)^{-1} b */ 1072fc3d8934SBarry Smith for (i=m-1; i>=0; i--) { 1073fc3d8934SBarry Smith n = a->i[i+1] - diag[i] - 1; 1074fc3d8934SBarry Smith idx = a->j + diag[i] + 1; 1075fc3d8934SBarry Smith v = a->a + diag[i] + 1; 1076fc3d8934SBarry Smith sum = b[i]; 1077fc3d8934SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1078b4632166SBarry Smith x[i] = sum*idiag[i]; 1079fc3d8934SBarry Smith 1080fc3d8934SBarry Smith /* t = b - (2*E - D)x */ 1081733d66baSBarry Smith t[i] = b[i] - (v2[diag[i]])*x[i]; 1082733d66baSBarry Smith } 1083fc3d8934SBarry Smith 1084fc3d8934SBarry Smith /* t = (E + L)^{-1}t */ 1085fc3d8934SBarry Smith diag = a->diag; 1086fc3d8934SBarry Smith for (i=0; i<m; i++) { 1087fc3d8934SBarry Smith n = diag[i] - a->i[i]; 1088fc3d8934SBarry Smith idx = a->j + a->i[i]; 1089fc3d8934SBarry Smith v = a->a + a->i[i]; 1090fc3d8934SBarry Smith sum = t[i]; 1091fc3d8934SBarry Smith SPARSEDENSEMDOT(sum,t,v,idx,n); 1092b4632166SBarry Smith t[i] = sum*idiag[i]; 1093fc3d8934SBarry Smith 1094fc3d8934SBarry Smith /* x = x + t */ 1095733d66baSBarry Smith x[i] += t[i]; 1096733d66baSBarry Smith } 1097733d66baSBarry Smith 1098b0a32e0cSBarry Smith PetscLogFlops(3*m-1 + 2*a->nz); 1099fc3d8934SBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 1100fc3d8934SBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 1101fc3d8934SBarry Smith PetscFunctionReturn(0); 11023a40ed3dSBarry Smith } else if (flag & SOR_EISENSTAT) { 110317ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 110417ab2063SBarry Smith U is upper triangular, E is diagonal; This routine applies 110517ab2063SBarry Smith 110617ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 110717ab2063SBarry Smith 110817ab2063SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 110917ab2063SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 111017ab2063SBarry Smith is the relaxation factor. 111117ab2063SBarry Smith */ 111217ab2063SBarry Smith scale = (2.0/omega) - 1.0; 111317ab2063SBarry Smith 111417ab2063SBarry Smith /* x = (E + U)^{-1} b */ 111517ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1116416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 1117416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1118416022c9SBarry Smith idx = a->j + diag[i] + (!shift); 1119416022c9SBarry Smith v = a->a + diag[i] + (!shift); 112017ab2063SBarry Smith sum = b[i]; 112117ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 112217ab2063SBarry Smith x[i] = omega*(sum/d); 112317ab2063SBarry Smith } 112417ab2063SBarry Smith 112517ab2063SBarry Smith /* t = b - (2*E - D)x */ 1126416022c9SBarry Smith v = a->a; 112717ab2063SBarry Smith for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++ + shift])*x[i]; } 112817ab2063SBarry Smith 112917ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1130416022c9SBarry Smith ts = t + shift; /* shifted by one for index start of a or a->j*/ 1131416022c9SBarry Smith diag = a->diag; 113217ab2063SBarry Smith for (i=0; i<m; i++) { 1133416022c9SBarry Smith d = fshift + a->a[diag[i]+shift]; 1134416022c9SBarry Smith n = diag[i] - a->i[i]; 1135416022c9SBarry Smith idx = a->j + a->i[i] + shift; 1136416022c9SBarry Smith v = a->a + a->i[i] + shift; 113717ab2063SBarry Smith sum = t[i]; 113817ab2063SBarry Smith SPARSEDENSEMDOT(sum,ts,v,idx,n); 113917ab2063SBarry Smith t[i] = omega*(sum/d); 1140733d66baSBarry Smith /* x = x + t */ 1141733d66baSBarry Smith x[i] += t[i]; 114217ab2063SBarry Smith } 114317ab2063SBarry Smith 1144b0a32e0cSBarry Smith PetscLogFlops(6*m-1 + 2*a->nz); 1145cb5b572fSBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 1146fb2e594dSBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 11473a40ed3dSBarry Smith PetscFunctionReturn(0); 114817ab2063SBarry Smith } 114917ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 115017ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 115177d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 115277d8c4bbSBarry Smith fortranrelaxaijforwardzero_(&m,&omega,x,a->i,a->j,diag,a->a,b); 115377d8c4bbSBarry Smith #else 115417ab2063SBarry Smith for (i=0; i<m; i++) { 1155416022c9SBarry Smith d = fshift + a->a[diag[i]+shift]; 1156416022c9SBarry Smith n = diag[i] - a->i[i]; 1157b0a32e0cSBarry Smith PetscLogFlops(2*n-1); 1158416022c9SBarry Smith idx = a->j + a->i[i] + shift; 1159416022c9SBarry Smith v = a->a + a->i[i] + shift; 116017ab2063SBarry Smith sum = b[i]; 116117ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 116217ab2063SBarry Smith x[i] = omega*(sum/d); 116317ab2063SBarry Smith } 116477d8c4bbSBarry Smith #endif 116517ab2063SBarry Smith xb = x; 11663a40ed3dSBarry Smith } else xb = b; 116717ab2063SBarry Smith if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) && 116817ab2063SBarry Smith (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) { 116917ab2063SBarry Smith for (i=0; i<m; i++) { 1170416022c9SBarry Smith x[i] *= a->a[diag[i]+shift]; 117117ab2063SBarry Smith } 1172b0a32e0cSBarry Smith PetscLogFlops(m); 117317ab2063SBarry Smith } 117417ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 117577d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 117677d8c4bbSBarry Smith fortranrelaxaijbackwardzero_(&m,&omega,x,a->i,a->j,diag,a->a,xb); 117777d8c4bbSBarry Smith #else 117817ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1179416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 1180416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1181b0a32e0cSBarry Smith PetscLogFlops(2*n-1); 1182416022c9SBarry Smith idx = a->j + diag[i] + (!shift); 1183416022c9SBarry Smith v = a->a + diag[i] + (!shift); 118417ab2063SBarry Smith sum = xb[i]; 118517ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 118617ab2063SBarry Smith x[i] = omega*(sum/d); 118717ab2063SBarry Smith } 118877d8c4bbSBarry Smith #endif 118917ab2063SBarry Smith } 119017ab2063SBarry Smith its--; 119117ab2063SBarry Smith } 119217ab2063SBarry Smith while (its--) { 119317ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 119477d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 119577d8c4bbSBarry Smith fortranrelaxaijforward_(&m,&omega,x,a->i,a->j,diag,a->a,b); 119677d8c4bbSBarry Smith #else 119717ab2063SBarry Smith for (i=0; i<m; i++) { 1198416022c9SBarry Smith d = fshift + a->a[diag[i]+shift]; 1199416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1200b0a32e0cSBarry Smith PetscLogFlops(2*n-1); 1201416022c9SBarry Smith idx = a->j + a->i[i] + shift; 1202416022c9SBarry Smith v = a->a + a->i[i] + shift; 120317ab2063SBarry Smith sum = b[i]; 120417ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 12057e33a6baSBarry Smith x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d; 120617ab2063SBarry Smith } 120777d8c4bbSBarry Smith #endif 120817ab2063SBarry Smith } 120917ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 121077d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 121177d8c4bbSBarry Smith fortranrelaxaijbackward_(&m,&omega,x,a->i,a->j,diag,a->a,b); 121277d8c4bbSBarry Smith #else 121317ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1214416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 1215416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1216b0a32e0cSBarry Smith PetscLogFlops(2*n-1); 1217416022c9SBarry Smith idx = a->j + a->i[i] + shift; 1218416022c9SBarry Smith v = a->a + a->i[i] + shift; 121917ab2063SBarry Smith sum = b[i]; 122017ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 12217e33a6baSBarry Smith x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d; 122217ab2063SBarry Smith } 122377d8c4bbSBarry Smith #endif 122417ab2063SBarry Smith } 122517ab2063SBarry Smith } 1226cb5b572fSBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 1227fb2e594dSBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 12283a40ed3dSBarry Smith PetscFunctionReturn(0); 122917ab2063SBarry Smith } 123017ab2063SBarry Smith 12314a2ae208SSatish Balay #undef __FUNCT__ 12324a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ" 12338f6be9afSLois Curfman McInnes int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 123417ab2063SBarry Smith { 1235416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 12364e220ebcSLois Curfman McInnes 12373a40ed3dSBarry Smith PetscFunctionBegin; 1238273d9f13SBarry Smith info->rows_global = (double)A->m; 1239273d9f13SBarry Smith info->columns_global = (double)A->n; 1240273d9f13SBarry Smith info->rows_local = (double)A->m; 1241273d9f13SBarry Smith info->columns_local = (double)A->n; 12424e220ebcSLois Curfman McInnes info->block_size = 1.0; 12434e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 12444e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 12454e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 12464e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 12474e220ebcSLois Curfman McInnes info->mallocs = (double)a->reallocs; 12484e220ebcSLois Curfman McInnes info->memory = A->mem; 12494e220ebcSLois Curfman McInnes if (A->factor) { 12504e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 12514e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 12524e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 12534e220ebcSLois Curfman McInnes } else { 12544e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 12554e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 12564e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 12574e220ebcSLois Curfman McInnes } 12583a40ed3dSBarry Smith PetscFunctionReturn(0); 125917ab2063SBarry Smith } 126017ab2063SBarry Smith 1261b9b97703SBarry Smith EXTERN int MatLUFactorSymbolic_SeqAIJ(Mat,IS,IS,MatLUInfo*,Mat*); 1262ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqAIJ(Mat,Mat*); 1263b9b97703SBarry Smith EXTERN int MatLUFactor_SeqAIJ(Mat,IS,IS,MatLUInfo*); 1264ca44d042SBarry Smith EXTERN int MatSolve_SeqAIJ(Mat,Vec,Vec); 1265ca44d042SBarry Smith EXTERN int MatSolveAdd_SeqAIJ(Mat,Vec,Vec,Vec); 1266ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqAIJ(Mat,Vec,Vec); 1267ca44d042SBarry Smith EXTERN int MatSolveTransposeAdd_SeqAIJ(Mat,Vec,Vec,Vec); 126817ab2063SBarry Smith 12694a2ae208SSatish Balay #undef __FUNCT__ 12704a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ" 127187828ca2SBarry Smith int MatZeroRows_SeqAIJ(Mat A,IS is,PetscScalar *diag) 127217ab2063SBarry Smith { 1273416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1274273d9f13SBarry Smith int i,ierr,N,*rows,m = A->m - 1,shift = a->indexshift; 127517ab2063SBarry Smith 12763a40ed3dSBarry Smith PetscFunctionBegin; 1277b9b97703SBarry Smith ierr = ISGetLocalSize(is,&N);CHKERRQ(ierr); 127817ab2063SBarry Smith ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 1279f1e2ffcdSBarry Smith if (a->keepzeroedrows) { 1280f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 128129bbc08cSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"row out of range"); 128287828ca2SBarry Smith ierr = PetscMemzero(&a->a[a->i[rows[i]]+shift],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 1283f1e2ffcdSBarry Smith } 1284f1e2ffcdSBarry Smith if (diag) { 1285f1e2ffcdSBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1286f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1287f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1288f1e2ffcdSBarry Smith a->a[a->diag[rows[i]]] = *diag; 1289f1e2ffcdSBarry Smith } 1290f1e2ffcdSBarry Smith } 1291f1e2ffcdSBarry Smith } else { 129217ab2063SBarry Smith if (diag) { 129317ab2063SBarry Smith for (i=0; i<N; i++) { 129429bbc08cSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"row out of range"); 12957ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1296416022c9SBarry Smith a->ilen[rows[i]] = 1; 1297416022c9SBarry Smith a->a[a->i[rows[i]]+shift] = *diag; 1298416022c9SBarry Smith a->j[a->i[rows[i]]+shift] = rows[i]+shift; 12997ae801bdSBarry Smith } else { /* in case row was completely empty */ 1300d64ed03dSBarry Smith ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr); 130117ab2063SBarry Smith } 130217ab2063SBarry Smith } 13033a40ed3dSBarry Smith } else { 130417ab2063SBarry Smith for (i=0; i<N; i++) { 130529bbc08cSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"row out of range"); 1306416022c9SBarry Smith a->ilen[rows[i]] = 0; 130717ab2063SBarry Smith } 130817ab2063SBarry Smith } 1309f1e2ffcdSBarry Smith } 13107ae801bdSBarry Smith ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 131143a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13123a40ed3dSBarry Smith PetscFunctionReturn(0); 131317ab2063SBarry Smith } 131417ab2063SBarry Smith 13154a2ae208SSatish Balay #undef __FUNCT__ 13164a2ae208SSatish Balay #define __FUNCT__ "MatGetOwnershipRange_SeqAIJ" 13178f6be9afSLois Curfman McInnes int MatGetOwnershipRange_SeqAIJ(Mat A,int *m,int *n) 131817ab2063SBarry Smith { 13193a40ed3dSBarry Smith PetscFunctionBegin; 13204c49b128SBarry Smith if (m) *m = 0; 1321273d9f13SBarry Smith if (n) *n = A->m; 13223a40ed3dSBarry Smith PetscFunctionReturn(0); 132317ab2063SBarry Smith } 1324026e39d0SSatish Balay 13254a2ae208SSatish Balay #undef __FUNCT__ 13264a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ" 132787828ca2SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v) 132817ab2063SBarry Smith { 1329416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1330b0a32e0cSBarry Smith int *itmp,i,shift = a->indexshift,ierr; 133117ab2063SBarry Smith 13323a40ed3dSBarry Smith PetscFunctionBegin; 1333273d9f13SBarry Smith if (row < 0 || row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %d out of range",row); 133417ab2063SBarry Smith 1335416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1336416022c9SBarry Smith if (v) *v = a->a + a->i[row] + shift; 133717ab2063SBarry Smith if (idx) { 1338416022c9SBarry Smith itmp = a->j + a->i[row] + shift; 13394e093b46SBarry Smith if (*nz && shift) { 1340b0a32e0cSBarry Smith ierr = PetscMalloc((*nz)*sizeof(int),idx);CHKERRQ(ierr); 134117ab2063SBarry Smith for (i=0; i<(*nz); i++) {(*idx)[i] = itmp[i] + shift;} 13424e093b46SBarry Smith } else if (*nz) { 13434e093b46SBarry Smith *idx = itmp; 134417ab2063SBarry Smith } 134517ab2063SBarry Smith else *idx = 0; 134617ab2063SBarry Smith } 13473a40ed3dSBarry Smith PetscFunctionReturn(0); 134817ab2063SBarry Smith } 134917ab2063SBarry Smith 13504a2ae208SSatish Balay #undef __FUNCT__ 13514a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ" 135287828ca2SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v) 135317ab2063SBarry Smith { 13544e093b46SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1355606d414cSSatish Balay int ierr; 13563a40ed3dSBarry Smith 13573a40ed3dSBarry Smith PetscFunctionBegin; 1358606d414cSSatish Balay if (idx) {if (*idx && a->indexshift) {ierr = PetscFree(*idx);CHKERRQ(ierr);}} 13593a40ed3dSBarry Smith PetscFunctionReturn(0); 136017ab2063SBarry Smith } 136117ab2063SBarry Smith 13624a2ae208SSatish Balay #undef __FUNCT__ 13634a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ" 136436db0b34SBarry Smith int MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *norm) 136517ab2063SBarry Smith { 1366416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 136787828ca2SBarry Smith PetscScalar *v = a->a; 136836db0b34SBarry Smith PetscReal sum = 0.0; 1369549d3d68SSatish Balay int i,j,shift = a->indexshift,ierr; 137017ab2063SBarry Smith 13713a40ed3dSBarry Smith PetscFunctionBegin; 137217ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1373416022c9SBarry Smith for (i=0; i<a->nz; i++) { 1374aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 137536db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 137617ab2063SBarry Smith #else 137717ab2063SBarry Smith sum += (*v)*(*v); v++; 137817ab2063SBarry Smith #endif 137917ab2063SBarry Smith } 138017ab2063SBarry Smith *norm = sqrt(sum); 13813a40ed3dSBarry Smith } else if (type == NORM_1) { 138236db0b34SBarry Smith PetscReal *tmp; 1383416022c9SBarry Smith int *jj = a->j; 1384b0a32e0cSBarry Smith ierr = PetscMalloc((A->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr); 1385273d9f13SBarry Smith ierr = PetscMemzero(tmp,A->n*sizeof(PetscReal));CHKERRQ(ierr); 138617ab2063SBarry Smith *norm = 0.0; 1387416022c9SBarry Smith for (j=0; j<a->nz; j++) { 1388a2744918SBarry Smith tmp[*jj++ + shift] += PetscAbsScalar(*v); v++; 138917ab2063SBarry Smith } 1390273d9f13SBarry Smith for (j=0; j<A->n; j++) { 139117ab2063SBarry Smith if (tmp[j] > *norm) *norm = tmp[j]; 139217ab2063SBarry Smith } 1393606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 13943a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 139517ab2063SBarry Smith *norm = 0.0; 1396273d9f13SBarry Smith for (j=0; j<A->m; j++) { 1397416022c9SBarry Smith v = a->a + a->i[j] + shift; 139817ab2063SBarry Smith sum = 0.0; 1399416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 1400cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 140117ab2063SBarry Smith } 140217ab2063SBarry Smith if (sum > *norm) *norm = sum; 140317ab2063SBarry Smith } 14043a40ed3dSBarry Smith } else { 140529bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"No support for two norm"); 140617ab2063SBarry Smith } 14073a40ed3dSBarry Smith PetscFunctionReturn(0); 140817ab2063SBarry Smith } 140917ab2063SBarry Smith 14104a2ae208SSatish Balay #undef __FUNCT__ 14114a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ" 14128f6be9afSLois Curfman McInnes int MatTranspose_SeqAIJ(Mat A,Mat *B) 141317ab2063SBarry Smith { 1414416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1415416022c9SBarry Smith Mat C; 1416273d9f13SBarry Smith int i,ierr,*aj = a->j,*ai = a->i,m = A->m,len,*col; 1417273d9f13SBarry Smith int shift = a->indexshift; 141887828ca2SBarry Smith PetscScalar *array = a->a; 141917ab2063SBarry Smith 14203a40ed3dSBarry Smith PetscFunctionBegin; 1421273d9f13SBarry Smith if (!B && m != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Square matrix only for in-place"); 1422b0a32e0cSBarry Smith ierr = PetscMalloc((1+A->n)*sizeof(int),&col);CHKERRQ(ierr); 1423273d9f13SBarry Smith ierr = PetscMemzero(col,(1+A->n)*sizeof(int));CHKERRQ(ierr); 142417ab2063SBarry Smith if (shift) { 142517ab2063SBarry Smith for (i=0; i<ai[m]-1; i++) aj[i] -= 1; 142617ab2063SBarry Smith } 142717ab2063SBarry Smith for (i=0; i<ai[m]+shift; i++) col[aj[i]] += 1; 1428273d9f13SBarry Smith ierr = MatCreateSeqAIJ(A->comm,A->n,m,0,col,&C);CHKERRQ(ierr); 1429606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 143017ab2063SBarry Smith for (i=0; i<m; i++) { 143117ab2063SBarry Smith len = ai[i+1]-ai[i]; 1432416022c9SBarry Smith ierr = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 1433b9b97703SBarry Smith array += len; 1434b9b97703SBarry Smith aj += len; 143517ab2063SBarry Smith } 143617ab2063SBarry Smith if (shift) { 143717ab2063SBarry Smith for (i=0; i<ai[m]-1; i++) aj[i] += 1; 143817ab2063SBarry Smith } 143917ab2063SBarry Smith 14406d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14416d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 144217ab2063SBarry Smith 1443f1e2ffcdSBarry Smith if (B) { 1444416022c9SBarry Smith *B = C; 144517ab2063SBarry Smith } else { 1446273d9f13SBarry Smith ierr = MatHeaderCopy(A,C);CHKERRQ(ierr); 144717ab2063SBarry Smith } 14483a40ed3dSBarry Smith PetscFunctionReturn(0); 144917ab2063SBarry Smith } 145017ab2063SBarry Smith 14514a2ae208SSatish Balay #undef __FUNCT__ 14524a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ" 14538f6be9afSLois Curfman McInnes int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 145417ab2063SBarry Smith { 1455416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 145687828ca2SBarry Smith PetscScalar *l,*r,x,*v; 1457273d9f13SBarry Smith int ierr,i,j,m = A->m,n = A->n,M,nz = a->nz,*jj,shift = a->indexshift; 145817ab2063SBarry Smith 14593a40ed3dSBarry Smith PetscFunctionBegin; 146017ab2063SBarry Smith if (ll) { 14613ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 14623ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 1463e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 1464273d9f13SBarry Smith if (m != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 1465e1311b90SBarry Smith ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 1466416022c9SBarry Smith v = a->a; 146717ab2063SBarry Smith for (i=0; i<m; i++) { 146817ab2063SBarry Smith x = l[i]; 1469416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 147017ab2063SBarry Smith for (j=0; j<M; j++) { (*v++) *= x;} 147117ab2063SBarry Smith } 1472e1311b90SBarry Smith ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 1473b0a32e0cSBarry Smith PetscLogFlops(nz); 147417ab2063SBarry Smith } 147517ab2063SBarry Smith if (rr) { 1476e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 1477273d9f13SBarry Smith if (n != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 1478e1311b90SBarry Smith ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 1479416022c9SBarry Smith v = a->a; jj = a->j; 148017ab2063SBarry Smith for (i=0; i<nz; i++) { 148117ab2063SBarry Smith (*v++) *= r[*jj++ + shift]; 148217ab2063SBarry Smith } 1483e1311b90SBarry Smith ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 1484b0a32e0cSBarry Smith PetscLogFlops(nz); 148517ab2063SBarry Smith } 14863a40ed3dSBarry Smith PetscFunctionReturn(0); 148717ab2063SBarry Smith } 148817ab2063SBarry Smith 14894a2ae208SSatish Balay #undef __FUNCT__ 14904a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ" 14917b2a1423SBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatReuse scall,Mat *B) 149217ab2063SBarry Smith { 1493db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 1494273d9f13SBarry Smith int *smap,i,k,kstart,kend,ierr,oldcols = A->n,*lens; 149536db0b34SBarry Smith int row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 149699141d43SSatish Balay int *irow,*icol,nrows,ncols,shift = a->indexshift,*ssmap; 149799141d43SSatish Balay int *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 149887828ca2SBarry Smith PetscScalar *a_new,*mat_a; 1499416022c9SBarry Smith Mat C; 1500fee21e36SBarry Smith PetscTruth stride; 150117ab2063SBarry Smith 15023a40ed3dSBarry Smith PetscFunctionBegin; 1503d64ed03dSBarry Smith ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr); 150429bbc08cSBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted"); 1505d64ed03dSBarry Smith ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr); 150629bbc08cSBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted"); 150799141d43SSatish Balay 150817ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 1509b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 1510b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 151117ab2063SBarry Smith 1512fee21e36SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 1513fee21e36SBarry Smith ierr = ISStride(iscol,&stride);CHKERRQ(ierr); 1514fee21e36SBarry Smith if (stride && step == 1) { 151502834360SBarry Smith /* special case of contiguous rows */ 151631ebf83bSSatish Balay ierr = PetscMalloc((2*nrows+1)*sizeof(int),&lens);CHKERRQ(ierr); 151731ebf83bSSatish Balay starts = lens + nrows; 151802834360SBarry Smith /* loop over new rows determining lens and starting points */ 151902834360SBarry Smith for (i=0; i<nrows; i++) { 1520a2744918SBarry Smith kstart = ai[irow[i]]+shift; 1521a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 152202834360SBarry Smith for (k=kstart; k<kend; k++) { 1523d8ced48eSBarry Smith if (aj[k]+shift >= first) { 152402834360SBarry Smith starts[i] = k; 152502834360SBarry Smith break; 152602834360SBarry Smith } 152702834360SBarry Smith } 1528a2744918SBarry Smith sum = 0; 152902834360SBarry Smith while (k < kend) { 1530d8ced48eSBarry Smith if (aj[k++]+shift >= first+ncols) break; 1531a2744918SBarry Smith sum++; 153202834360SBarry Smith } 1533a2744918SBarry Smith lens[i] = sum; 153402834360SBarry Smith } 153502834360SBarry Smith /* create submatrix */ 1536cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 153708480c60SBarry Smith int n_cols,n_rows; 153808480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 153929bbc08cSBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 1540d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 154108480c60SBarry Smith C = *B; 15423a40ed3dSBarry Smith } else { 154302834360SBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 154408480c60SBarry Smith } 1545db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 1546db02288aSLois Curfman McInnes 154702834360SBarry Smith /* loop over rows inserting into submatrix */ 1548db02288aSLois Curfman McInnes a_new = c->a; 1549db02288aSLois Curfman McInnes j_new = c->j; 1550db02288aSLois Curfman McInnes i_new = c->i; 1551db02288aSLois Curfman McInnes i_new[0] = -shift; 155202834360SBarry Smith for (i=0; i<nrows; i++) { 1553a2744918SBarry Smith ii = starts[i]; 1554a2744918SBarry Smith lensi = lens[i]; 1555a2744918SBarry Smith for (k=0; k<lensi; k++) { 1556a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 155702834360SBarry Smith } 155887828ca2SBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr); 1559a2744918SBarry Smith a_new += lensi; 1560a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 1561a2744918SBarry Smith c->ilen[i] = lensi; 156202834360SBarry Smith } 1563606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 15643a40ed3dSBarry Smith } else { 156502834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 1566b0a32e0cSBarry Smith ierr = PetscMalloc((1+oldcols)*sizeof(int),&smap);CHKERRQ(ierr); 156702834360SBarry Smith ssmap = smap + shift; 1568b0a32e0cSBarry Smith ierr = PetscMalloc((1+nrows)*sizeof(int),&lens);CHKERRQ(ierr); 1569549d3d68SSatish Balay ierr = PetscMemzero(smap,oldcols*sizeof(int));CHKERRQ(ierr); 157017ab2063SBarry Smith for (i=0; i<ncols; i++) smap[icol[i]] = i+1; 157102834360SBarry Smith /* determine lens of each row */ 157202834360SBarry Smith for (i=0; i<nrows; i++) { 1573d8ced48eSBarry Smith kstart = ai[irow[i]]+shift; 157402834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 157502834360SBarry Smith lens[i] = 0; 157602834360SBarry Smith for (k=kstart; k<kend; k++) { 1577d8ced48eSBarry Smith if (ssmap[aj[k]]) { 157802834360SBarry Smith lens[i]++; 157902834360SBarry Smith } 158002834360SBarry Smith } 158102834360SBarry Smith } 158217ab2063SBarry Smith /* Create and fill new matrix */ 1583a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 15840f5bd95cSBarry Smith PetscTruth equal; 15850f5bd95cSBarry Smith 158699141d43SSatish Balay c = (Mat_SeqAIJ *)((*B)->data); 1587273d9f13SBarry Smith if ((*B)->m != nrows || (*B)->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 1588273d9f13SBarry Smith ierr = PetscMemcmp(c->ilen,lens,(*B)->m*sizeof(int),&equal);CHKERRQ(ierr); 15890f5bd95cSBarry Smith if (!equal) { 159029bbc08cSBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 159199141d43SSatish Balay } 1592273d9f13SBarry Smith ierr = PetscMemzero(c->ilen,(*B)->m*sizeof(int));CHKERRQ(ierr); 159308480c60SBarry Smith C = *B; 15943a40ed3dSBarry Smith } else { 159502834360SBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 159608480c60SBarry Smith } 159799141d43SSatish Balay c = (Mat_SeqAIJ *)(C->data); 159817ab2063SBarry Smith for (i=0; i<nrows; i++) { 159999141d43SSatish Balay row = irow[i]; 160099141d43SSatish Balay kstart = ai[row]+shift; 160199141d43SSatish Balay kend = kstart + a->ilen[row]; 160299141d43SSatish Balay mat_i = c->i[i]+shift; 160399141d43SSatish Balay mat_j = c->j + mat_i; 160499141d43SSatish Balay mat_a = c->a + mat_i; 160599141d43SSatish Balay mat_ilen = c->ilen + i; 160617ab2063SBarry Smith for (k=kstart; k<kend; k++) { 160799141d43SSatish Balay if ((tcol=ssmap[a->j[k]])) { 160899141d43SSatish Balay *mat_j++ = tcol - (!shift); 160999141d43SSatish Balay *mat_a++ = a->a[k]; 161099141d43SSatish Balay (*mat_ilen)++; 161199141d43SSatish Balay 161217ab2063SBarry Smith } 161317ab2063SBarry Smith } 161417ab2063SBarry Smith } 161502834360SBarry Smith /* Free work space */ 161602834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 1617606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 1618606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 161902834360SBarry Smith } 16206d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16216d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 162217ab2063SBarry Smith 162317ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 1624416022c9SBarry Smith *B = C; 16253a40ed3dSBarry Smith PetscFunctionReturn(0); 162617ab2063SBarry Smith } 162717ab2063SBarry Smith 1628a871dcd8SBarry Smith /* 1629a871dcd8SBarry Smith */ 16304a2ae208SSatish Balay #undef __FUNCT__ 16314a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ" 16325ef9f2a5SBarry Smith int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatILUInfo *info) 1633a871dcd8SBarry Smith { 163463b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 163508480c60SBarry Smith int ierr; 163663b91edcSBarry Smith Mat outA; 1637b8a78c4aSBarry Smith PetscTruth row_identity,col_identity; 163863b91edcSBarry Smith 16393a40ed3dSBarry Smith PetscFunctionBegin; 164029bbc08cSBarry Smith if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 1641b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 1642b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 1643b8a78c4aSBarry Smith if (!row_identity || !col_identity) { 164429bbc08cSBarry Smith SETERRQ(1,"Row and column permutations must be identity for in-place ILU"); 1645b8a78c4aSBarry Smith } 1646a871dcd8SBarry Smith 164763b91edcSBarry Smith outA = inA; 164863b91edcSBarry Smith inA->factor = FACTOR_LU; 164963b91edcSBarry Smith a->row = row; 165063b91edcSBarry Smith a->col = col; 1651c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1652c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 165363b91edcSBarry Smith 165436db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 1655b9b97703SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */ 16564c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 1657b0a32e0cSBarry Smith PetscLogObjectParent(inA,a->icol); 1658f0ec6fceSSatish Balay 165994a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 166087828ca2SBarry Smith ierr = PetscMalloc((inA->m+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr); 166194a9d846SBarry Smith } 166263b91edcSBarry Smith 166308480c60SBarry Smith if (!a->diag) { 1664f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 166563b91edcSBarry Smith } 166663b91edcSBarry Smith ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA);CHKERRQ(ierr); 16673a40ed3dSBarry Smith PetscFunctionReturn(0); 1668a871dcd8SBarry Smith } 1669a871dcd8SBarry Smith 1670d9eff348SSatish Balay #include "petscblaslapack.h" 16714a2ae208SSatish Balay #undef __FUNCT__ 16724a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ" 167387828ca2SBarry Smith int MatScale_SeqAIJ(PetscScalar *alpha,Mat inA) 1674f0b747eeSBarry Smith { 1675f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 1676f0b747eeSBarry Smith int one = 1; 16773a40ed3dSBarry Smith 16783a40ed3dSBarry Smith PetscFunctionBegin; 1679f0b747eeSBarry Smith BLscal_(&a->nz,alpha,a->a,&one); 1680b0a32e0cSBarry Smith PetscLogFlops(a->nz); 16813a40ed3dSBarry Smith PetscFunctionReturn(0); 1682f0b747eeSBarry Smith } 1683f0b747eeSBarry Smith 16844a2ae208SSatish Balay #undef __FUNCT__ 16854a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ" 16867b2a1423SBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n,IS *irow,IS *icol,MatReuse scall,Mat **B) 1687cddf8d76SBarry Smith { 1688cddf8d76SBarry Smith int ierr,i; 1689cddf8d76SBarry Smith 16903a40ed3dSBarry Smith PetscFunctionBegin; 1691cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 1692b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr); 1693cddf8d76SBarry Smith } 1694cddf8d76SBarry Smith 1695cddf8d76SBarry Smith for (i=0; i<n; i++) { 16966a6a5d1dSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 1697cddf8d76SBarry Smith } 16983a40ed3dSBarry Smith PetscFunctionReturn(0); 1699cddf8d76SBarry Smith } 1700cddf8d76SBarry Smith 17014a2ae208SSatish Balay #undef __FUNCT__ 17024a2ae208SSatish Balay #define __FUNCT__ "MatGetBlockSize_SeqAIJ" 17038f6be9afSLois Curfman McInnes int MatGetBlockSize_SeqAIJ(Mat A,int *bs) 17045a838052SSatish Balay { 1705f830108cSBarry Smith PetscFunctionBegin; 17065a838052SSatish Balay *bs = 1; 17073a40ed3dSBarry Smith PetscFunctionReturn(0); 17085a838052SSatish Balay } 17095a838052SSatish Balay 17104a2ae208SSatish Balay #undef __FUNCT__ 17114a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ" 17128f6be9afSLois Curfman McInnes int MatIncreaseOverlap_SeqAIJ(Mat A,int is_max,IS *is,int ov) 17134dcbc457SBarry Smith { 1714e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 171506763907SSatish Balay int shift,row,i,j,k,l,m,n,*idx,ierr,*nidx,isz,val; 17168a047759SSatish Balay int start,end,*ai,*aj; 1717f1af5d2fSBarry Smith PetscBT table; 1718bbd702dbSSatish Balay 17193a40ed3dSBarry Smith PetscFunctionBegin; 17208a047759SSatish Balay shift = a->indexshift; 1721273d9f13SBarry Smith m = A->m; 1722e4d965acSSatish Balay ai = a->i; 17238a047759SSatish Balay aj = a->j+shift; 17248a047759SSatish Balay 172529bbc08cSBarry Smith if (ov < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"illegal overlap value used"); 172606763907SSatish Balay 1727b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&nidx);CHKERRQ(ierr); 17286831982aSBarry Smith ierr = PetscBTCreate(m,table);CHKERRQ(ierr); 172906763907SSatish Balay 1730e4d965acSSatish Balay for (i=0; i<is_max; i++) { 1731b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 1732e4d965acSSatish Balay isz = 0; 17336831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 1734e4d965acSSatish Balay 1735e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 17364dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 1737b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 1738e4d965acSSatish Balay 1739dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 1740e4d965acSSatish Balay for (j=0; j<n ; ++j){ 1741f1af5d2fSBarry Smith if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];} 17424dcbc457SBarry Smith } 174306763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 174406763907SSatish Balay ierr = ISDestroy(is[i]);CHKERRQ(ierr); 1745e4d965acSSatish Balay 174604a348a9SBarry Smith k = 0; 174704a348a9SBarry Smith for (j=0; j<ov; j++){ /* for each overlap */ 174804a348a9SBarry Smith n = isz; 174906763907SSatish Balay for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */ 1750e4d965acSSatish Balay row = nidx[k]; 1751e4d965acSSatish Balay start = ai[row]; 1752e4d965acSSatish Balay end = ai[row+1]; 175304a348a9SBarry Smith for (l = start; l<end ; l++){ 17548a047759SSatish Balay val = aj[l] + shift; 1755f1af5d2fSBarry Smith if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;} 1756e4d965acSSatish Balay } 1757e4d965acSSatish Balay } 1758e4d965acSSatish Balay } 1759029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr); 1760e4d965acSSatish Balay } 17616831982aSBarry Smith ierr = PetscBTDestroy(table);CHKERRQ(ierr); 1762606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 17633a40ed3dSBarry Smith PetscFunctionReturn(0); 17644dcbc457SBarry Smith } 176517ab2063SBarry Smith 17660513a670SBarry Smith /* -------------------------------------------------------------- */ 17674a2ae208SSatish Balay #undef __FUNCT__ 17684a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ" 17690513a670SBarry Smith int MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 17700513a670SBarry Smith { 17710513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 177287828ca2SBarry Smith PetscScalar *vwork; 1773273d9f13SBarry Smith int i,ierr,nz,m = A->m,n = A->n,*cwork; 17740513a670SBarry Smith int *row,*col,*cnew,j,*lens; 177556cd22aeSBarry Smith IS icolp,irowp; 17760513a670SBarry Smith 17773a40ed3dSBarry Smith PetscFunctionBegin; 17784c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 177956cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 17804c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 178156cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 17820513a670SBarry Smith 17830513a670SBarry Smith /* determine lengths of permuted rows */ 1784b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&lens);CHKERRQ(ierr); 17850513a670SBarry Smith for (i=0; i<m; i++) { 17860513a670SBarry Smith lens[row[i]] = a->i[i+1] - a->i[i]; 17870513a670SBarry Smith } 17880513a670SBarry Smith ierr = MatCreateSeqAIJ(A->comm,m,n,0,lens,B);CHKERRQ(ierr); 1789606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 17900513a670SBarry Smith 1791b0a32e0cSBarry Smith ierr = PetscMalloc(n*sizeof(int),&cnew);CHKERRQ(ierr); 17920513a670SBarry Smith for (i=0; i<m; i++) { 17930513a670SBarry Smith ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 17940513a670SBarry Smith for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];} 17950513a670SBarry Smith ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 17960513a670SBarry Smith ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 17970513a670SBarry Smith } 1798606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 17990513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18000513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 180156cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 180256cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 180356cd22aeSBarry Smith ierr = ISDestroy(irowp);CHKERRQ(ierr); 180456cd22aeSBarry Smith ierr = ISDestroy(icolp);CHKERRQ(ierr); 18053a40ed3dSBarry Smith PetscFunctionReturn(0); 18060513a670SBarry Smith } 18070513a670SBarry Smith 18084a2ae208SSatish Balay #undef __FUNCT__ 18094a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqAIJ" 1810682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A) 1811682d7d0cSBarry Smith { 1812c38d4ed2SBarry Smith static PetscTruth called = PETSC_FALSE; 1813682d7d0cSBarry Smith MPI_Comm comm = A->comm; 1814d132466eSBarry Smith int ierr; 1815682d7d0cSBarry Smith 18163a40ed3dSBarry Smith PetscFunctionBegin; 1817c38d4ed2SBarry Smith if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE; 1818d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr); 1819d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr); 1820d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr); 1821d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_no_inode: Do not use inodes\n");CHKERRQ(ierr); 1822d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");CHKERRQ(ierr); 1823aa482453SBarry Smith #if defined(PETSC_HAVE_ESSL) 1824d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_essl: Use IBM sparse LU factorization and solve.\n");CHKERRQ(ierr); 1825682d7d0cSBarry Smith #endif 1826cd5578b5SBarry Smith #if defined(PETSC_HAVE_LUSOL) 1827cd5578b5SBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_lusol: Use the Stanford LUSOL sparse factorization and solve.\n");CHKERRQ(ierr); 1828cd5578b5SBarry Smith #endif 182987828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) 1830ca44d042SBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_matlab: Use Matlab engine sparse LU factorization and solve.\n");CHKERRQ(ierr); 1831ca44d042SBarry Smith #endif 18323a40ed3dSBarry Smith PetscFunctionReturn(0); 1833682d7d0cSBarry Smith } 1834ca44d042SBarry Smith EXTERN int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg); 1835ca44d042SBarry Smith EXTERN int MatFDColoringCreate_SeqAIJ(Mat,ISColoring,MatFDColoring); 1836ca44d042SBarry Smith EXTERN int MatILUDTFactor_SeqAIJ(Mat,MatILUInfo*,IS,IS,Mat*); 18374a2ae208SSatish Balay #undef __FUNCT__ 18384a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ" 1839cb5b572fSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 1840cb5b572fSBarry Smith { 1841be6bf707SBarry Smith int ierr; 1842273d9f13SBarry Smith PetscTruth flg; 1843cb5b572fSBarry Smith 1844cb5b572fSBarry Smith PetscFunctionBegin; 1845273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)B,MATSEQAIJ,&flg);CHKERRQ(ierr); 1846273d9f13SBarry Smith if (str == SAME_NONZERO_PATTERN && flg) { 1847be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1848be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 1849be6bf707SBarry Smith 1850273d9f13SBarry Smith if (a->i[A->m]+a->indexshift != b->i[B->m]+a->indexshift) { 185129bbc08cSBarry Smith SETERRQ(1,"Number of nonzeros in two matrices are different"); 1852cb5b572fSBarry Smith } 185387828ca2SBarry Smith ierr = PetscMemcpy(b->a,a->a,(a->i[A->m]+a->indexshift)*sizeof(PetscScalar));CHKERRQ(ierr); 1854cb5b572fSBarry Smith } else { 1855cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1856cb5b572fSBarry Smith } 1857cb5b572fSBarry Smith PetscFunctionReturn(0); 1858cb5b572fSBarry Smith } 1859cb5b572fSBarry Smith 18604a2ae208SSatish Balay #undef __FUNCT__ 18614a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ" 1862273d9f13SBarry Smith int MatSetUpPreallocation_SeqAIJ(Mat A) 1863273d9f13SBarry Smith { 1864273d9f13SBarry Smith int ierr; 1865273d9f13SBarry Smith 1866273d9f13SBarry Smith PetscFunctionBegin; 1867273d9f13SBarry Smith ierr = MatSeqAIJSetPreallocation(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 1868273d9f13SBarry Smith PetscFunctionReturn(0); 1869273d9f13SBarry Smith } 1870273d9f13SBarry Smith 18714a2ae208SSatish Balay #undef __FUNCT__ 18724a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ" 187387828ca2SBarry Smith int MatGetArray_SeqAIJ(Mat A,PetscScalar **array) 18746c0721eeSBarry Smith { 18756c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18766c0721eeSBarry Smith PetscFunctionBegin; 18776c0721eeSBarry Smith *array = a->a; 18786c0721eeSBarry Smith PetscFunctionReturn(0); 18796c0721eeSBarry Smith } 18806c0721eeSBarry Smith 18814a2ae208SSatish Balay #undef __FUNCT__ 18824a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ" 188387828ca2SBarry Smith int MatRestoreArray_SeqAIJ(Mat A,PetscScalar **array) 18846c0721eeSBarry Smith { 18856c0721eeSBarry Smith PetscFunctionBegin; 18866c0721eeSBarry Smith PetscFunctionReturn(0); 18876c0721eeSBarry Smith } 1888273d9f13SBarry Smith 1889ee4f033dSBarry Smith #undef __FUNCT__ 1890ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ" 1891ee4f033dSBarry Smith int MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 1892ee4f033dSBarry Smith { 1893ee4f033dSBarry Smith int (*f)(void *,Vec,Vec,void*) = (int (*)(void *,Vec,Vec,void *))coloring->f; 1894ee4f033dSBarry Smith int k,ierr,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2; 189587828ca2SBarry Smith PetscScalar dx,mone = -1.0,*y,*xx,*w3_array; 189687828ca2SBarry Smith PetscScalar *vscale_array; 1897ee4f033dSBarry Smith PetscReal epsilon = coloring->error_rel,umin = coloring->umin; 1898ee4f033dSBarry Smith Vec w1,w2,w3; 1899ee4f033dSBarry Smith void *fctx = coloring->fctx; 1900ee4f033dSBarry Smith PetscTruth flg; 1901ee4f033dSBarry Smith 1902ee4f033dSBarry Smith PetscFunctionBegin; 1903ee4f033dSBarry Smith if (!coloring->w1) { 1904ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr); 1905ee4f033dSBarry Smith PetscLogObjectParent(coloring,coloring->w1); 1906ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr); 1907ee4f033dSBarry Smith PetscLogObjectParent(coloring,coloring->w2); 1908ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr); 1909ee4f033dSBarry Smith PetscLogObjectParent(coloring,coloring->w3); 1910ee4f033dSBarry Smith } 1911ee4f033dSBarry Smith w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3; 1912ee4f033dSBarry Smith 1913ee4f033dSBarry Smith ierr = MatSetUnfactored(J);CHKERRQ(ierr); 1914ee4f033dSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_fd_coloring_dont_rezero",&flg);CHKERRQ(ierr); 1915ee4f033dSBarry Smith if (flg) { 1916ee4f033dSBarry Smith PetscLogInfo(coloring,"MatFDColoringApply_SeqAIJ: Not calling MatZeroEntries()\n"); 1917ee4f033dSBarry Smith } else { 1918ee4f033dSBarry Smith ierr = MatZeroEntries(J);CHKERRQ(ierr); 1919ee4f033dSBarry Smith } 1920ee4f033dSBarry Smith 1921ee4f033dSBarry Smith ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr); 1922ee4f033dSBarry Smith ierr = VecGetSize(x1,&N);CHKERRQ(ierr); 1923ee4f033dSBarry Smith 1924ee4f033dSBarry Smith /* 1925ee4f033dSBarry Smith This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets 1926ee4f033dSBarry Smith coloring->F for the coarser grids from the finest 1927ee4f033dSBarry Smith */ 1928ee4f033dSBarry Smith if (coloring->F) { 1929ee4f033dSBarry Smith ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr); 1930ee4f033dSBarry Smith ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr); 1931ee4f033dSBarry Smith if (m1 != m2) { 1932ee4f033dSBarry Smith coloring->F = 0; 1933ee4f033dSBarry Smith } 1934ee4f033dSBarry Smith } 1935ee4f033dSBarry Smith 1936ee4f033dSBarry Smith if (coloring->F) { 1937ee4f033dSBarry Smith w1 = coloring->F; 1938ee4f033dSBarry Smith coloring->F = 0; 1939ee4f033dSBarry Smith } else { 1940ee4f033dSBarry Smith ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr); 1941ee4f033dSBarry Smith } 1942ee4f033dSBarry Smith 1943ee4f033dSBarry Smith /* 1944ee4f033dSBarry Smith Compute all the scale factors and share with other processors 1945ee4f033dSBarry Smith */ 1946ee4f033dSBarry Smith ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start; 1947ee4f033dSBarry Smith ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start; 1948ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 1949ee4f033dSBarry Smith /* 1950ee4f033dSBarry Smith Loop over each column associated with color adding the 1951ee4f033dSBarry Smith perturbation to the vector w3. 1952ee4f033dSBarry Smith */ 1953ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 1954ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 1955ee4f033dSBarry Smith dx = xx[col]; 1956ee4f033dSBarry Smith if (dx == 0.0) dx = 1.0; 1957ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 1958ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 1959ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 1960ee4f033dSBarry Smith #else 1961ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 1962ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 1963ee4f033dSBarry Smith #endif 1964ee4f033dSBarry Smith dx *= epsilon; 1965ee4f033dSBarry Smith vscale_array[col] = 1.0/dx; 1966ee4f033dSBarry Smith } 1967ee4f033dSBarry Smith } 1968ee4f033dSBarry Smith vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 1969ee4f033dSBarry Smith ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1970ee4f033dSBarry Smith ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1971ee4f033dSBarry Smith 1972ee4f033dSBarry Smith /* ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD); 1973ee4f033dSBarry Smith ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/ 1974ee4f033dSBarry Smith 1975ee4f033dSBarry Smith if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow; 1976ee4f033dSBarry Smith else vscaleforrow = coloring->columnsforrow; 1977ee4f033dSBarry Smith 1978ee4f033dSBarry Smith ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 1979ee4f033dSBarry Smith /* 1980ee4f033dSBarry Smith Loop over each color 1981ee4f033dSBarry Smith */ 1982ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 1983ee4f033dSBarry Smith ierr = VecCopy(x1,w3);CHKERRQ(ierr); 1984ee4f033dSBarry Smith ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start; 1985ee4f033dSBarry Smith /* 1986ee4f033dSBarry Smith Loop over each column associated with color adding the 1987ee4f033dSBarry Smith perturbation to the vector w3. 1988ee4f033dSBarry Smith */ 1989ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 1990ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 1991ee4f033dSBarry Smith dx = xx[col]; 1992ee4f033dSBarry Smith if (dx == 0.0) dx = 1.0; 1993ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 1994ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 1995ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 1996ee4f033dSBarry Smith #else 1997ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 1998ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 1999ee4f033dSBarry Smith #endif 2000ee4f033dSBarry Smith dx *= epsilon; 2001ee4f033dSBarry Smith if (!PetscAbsScalar(dx)) SETERRQ(1,"Computed 0 differencing parameter"); 2002ee4f033dSBarry Smith w3_array[col] += dx; 2003ee4f033dSBarry Smith } 2004ee4f033dSBarry Smith w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr); 2005ee4f033dSBarry Smith 2006ee4f033dSBarry Smith /* 2007ee4f033dSBarry Smith Evaluate function at x1 + dx (here dx is a vector of perturbations) 2008ee4f033dSBarry Smith */ 2009ee4f033dSBarry Smith 2010ee4f033dSBarry Smith ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr); 2011ee4f033dSBarry Smith ierr = VecAXPY(&mone,w1,w2);CHKERRQ(ierr); 2012ee4f033dSBarry Smith 2013ee4f033dSBarry Smith /* 2014ee4f033dSBarry Smith Loop over rows of vector, putting results into Jacobian matrix 2015ee4f033dSBarry Smith */ 2016ee4f033dSBarry Smith ierr = VecGetArray(w2,&y);CHKERRQ(ierr); 2017ee4f033dSBarry Smith for (l=0; l<coloring->nrows[k]; l++) { 2018ee4f033dSBarry Smith row = coloring->rows[k][l]; 2019ee4f033dSBarry Smith col = coloring->columnsforrow[k][l]; 2020ee4f033dSBarry Smith y[row] *= vscale_array[vscaleforrow[k][l]]; 2021ee4f033dSBarry Smith srow = row + start; 2022ee4f033dSBarry Smith ierr = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr); 2023ee4f033dSBarry Smith } 2024ee4f033dSBarry Smith ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr); 2025ee4f033dSBarry Smith } 2026ee4f033dSBarry Smith ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2027ee4f033dSBarry Smith xx = xx + start; ierr = VecRestoreArray(x1,&xx);CHKERRQ(ierr); 2028ee4f033dSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2029ee4f033dSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2030ee4f033dSBarry Smith PetscFunctionReturn(0); 2031ee4f033dSBarry Smith } 2032ee4f033dSBarry Smith 2033682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 20340a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ, 2035cb5b572fSBarry Smith MatGetRow_SeqAIJ, 2036cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 2037cb5b572fSBarry Smith MatMult_SeqAIJ, 2038cb5b572fSBarry Smith MatMultAdd_SeqAIJ, 20397c922b88SBarry Smith MatMultTranspose_SeqAIJ, 20407c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 2041cb5b572fSBarry Smith MatSolve_SeqAIJ, 2042cb5b572fSBarry Smith MatSolveAdd_SeqAIJ, 20437c922b88SBarry Smith MatSolveTranspose_SeqAIJ, 20447c922b88SBarry Smith MatSolveTransposeAdd_SeqAIJ, 2045cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 2046cb5b572fSBarry Smith 0, 204717ab2063SBarry Smith MatRelax_SeqAIJ, 204817ab2063SBarry Smith MatTranspose_SeqAIJ, 2049cb5b572fSBarry Smith MatGetInfo_SeqAIJ, 2050cb5b572fSBarry Smith MatEqual_SeqAIJ, 2051cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 2052cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 2053cb5b572fSBarry Smith MatNorm_SeqAIJ, 2054cb5b572fSBarry Smith 0, 2055cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 205617ab2063SBarry Smith MatCompress_SeqAIJ, 2057cb5b572fSBarry Smith MatSetOption_SeqAIJ, 2058cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 2059cb5b572fSBarry Smith MatZeroRows_SeqAIJ, 2060cb5b572fSBarry Smith MatLUFactorSymbolic_SeqAIJ, 2061cb5b572fSBarry Smith MatLUFactorNumeric_SeqAIJ, 2062cb5b572fSBarry Smith 0, 2063cb5b572fSBarry Smith 0, 2064273d9f13SBarry Smith MatSetUpPreallocation_SeqAIJ, 2065273d9f13SBarry Smith 0, 2066cb5b572fSBarry Smith MatGetOwnershipRange_SeqAIJ, 2067cb5b572fSBarry Smith MatILUFactorSymbolic_SeqAIJ, 2068cb5b572fSBarry Smith 0, 20696c0721eeSBarry Smith MatGetArray_SeqAIJ, 20706c0721eeSBarry Smith MatRestoreArray_SeqAIJ, 2071be6bf707SBarry Smith MatDuplicate_SeqAIJ, 2072cb5b572fSBarry Smith 0, 2073cb5b572fSBarry Smith 0, 2074cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 2075cb5b572fSBarry Smith 0, 2076cb5b572fSBarry Smith 0, 2077cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 2078cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 2079cb5b572fSBarry Smith MatGetValues_SeqAIJ, 2080cb5b572fSBarry Smith MatCopy_SeqAIJ, 2081f0b747eeSBarry Smith MatPrintHelp_SeqAIJ, 2082cb5b572fSBarry Smith MatScale_SeqAIJ, 2083cb5b572fSBarry Smith 0, 2084cb5b572fSBarry Smith 0, 20856945ee14SBarry Smith MatILUDTFactor_SeqAIJ, 20866945ee14SBarry Smith MatGetBlockSize_SeqAIJ, 20873b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 20883b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 20893b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 2090a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 2091a93ec695SBarry Smith MatFDColoringCreate_SeqAIJ, 2092b9617806SBarry Smith 0, 20930513a670SBarry Smith 0, 2094cda55fadSBarry Smith MatPermute_SeqAIJ, 2095cda55fadSBarry Smith 0, 2096cda55fadSBarry Smith 0, 2097b9b97703SBarry Smith MatDestroy_SeqAIJ, 2098b9b97703SBarry Smith MatView_SeqAIJ, 20998a124369SBarry Smith MatGetPetscMaps_Petsc, 2100ee4f033dSBarry Smith 0, 2101ee4f033dSBarry Smith 0, 2102ee4f033dSBarry Smith 0, 2103ee4f033dSBarry Smith 0, 2104ee4f033dSBarry Smith 0, 2105ee4f033dSBarry Smith 0, 2106ee4f033dSBarry Smith 0, 2107ee4f033dSBarry Smith 0, 2108ee4f033dSBarry Smith MatSetColoring_SeqAIJ, 2109ee4f033dSBarry Smith MatSetValuesAdic_SeqAIJ, 2110ee4f033dSBarry Smith MatSetValuesAdifor_SeqAIJ, 2111ee4f033dSBarry Smith MatFDColoringApply_SeqAIJ}; 211217ab2063SBarry Smith 2113ca44d042SBarry Smith EXTERN int MatUseSuperLU_SeqAIJ(Mat); 2114ca44d042SBarry Smith EXTERN int MatUseEssl_SeqAIJ(Mat); 2115cd5578b5SBarry Smith EXTERN int MatUseLUSOL_SeqAIJ(Mat); 2116ca44d042SBarry Smith EXTERN int MatUseMatlab_SeqAIJ(Mat); 2117ca44d042SBarry Smith EXTERN int MatUseDXML_SeqAIJ(Mat); 211817ab2063SBarry Smith 2119fb2e594dSBarry Smith EXTERN_C_BEGIN 21204a2ae208SSatish Balay #undef __FUNCT__ 21214a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ" 212215091d37SBarry Smith 2123bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices) 2124bef8e0ddSBarry Smith { 2125bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2126bef8e0ddSBarry Smith int i,nz,n; 2127bef8e0ddSBarry Smith 2128bef8e0ddSBarry Smith PetscFunctionBegin; 2129bef8e0ddSBarry Smith 2130bef8e0ddSBarry Smith nz = aij->maxnz; 2131273d9f13SBarry Smith n = mat->n; 2132bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 2133bef8e0ddSBarry Smith aij->j[i] = indices[i]; 2134bef8e0ddSBarry Smith } 2135bef8e0ddSBarry Smith aij->nz = nz; 2136bef8e0ddSBarry Smith for (i=0; i<n; i++) { 2137bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 2138bef8e0ddSBarry Smith } 2139bef8e0ddSBarry Smith 2140bef8e0ddSBarry Smith PetscFunctionReturn(0); 2141bef8e0ddSBarry Smith } 2142fb2e594dSBarry Smith EXTERN_C_END 2143bef8e0ddSBarry Smith 21444a2ae208SSatish Balay #undef __FUNCT__ 21454a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices" 2146bef8e0ddSBarry Smith /*@ 2147bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 2148bef8e0ddSBarry Smith in the matrix. 2149bef8e0ddSBarry Smith 2150bef8e0ddSBarry Smith Input Parameters: 2151bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 2152bef8e0ddSBarry Smith - indices - the column indices 2153bef8e0ddSBarry Smith 215415091d37SBarry Smith Level: advanced 215515091d37SBarry Smith 2156bef8e0ddSBarry Smith Notes: 2157bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 2158bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 2159bef8e0ddSBarry Smith of the MatSetValues() operation. 2160bef8e0ddSBarry Smith 2161bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 2162bef8e0ddSBarry Smith MatCreateSeqAIJ(). 2163bef8e0ddSBarry Smith 2164bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 2165bef8e0ddSBarry Smith 2166b9617806SBarry Smith The indices should start with zero, not one. 2167b9617806SBarry Smith 2168bef8e0ddSBarry Smith @*/ 2169bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices) 2170bef8e0ddSBarry Smith { 2171bef8e0ddSBarry Smith int ierr,(*f)(Mat,int *); 2172bef8e0ddSBarry Smith 2173bef8e0ddSBarry Smith PetscFunctionBegin; 2174bef8e0ddSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 2175b9617806SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void (**)())&f);CHKERRQ(ierr); 2176bef8e0ddSBarry Smith if (f) { 2177bef8e0ddSBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 2178bef8e0ddSBarry Smith } else { 217929bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to set column indices"); 2180bef8e0ddSBarry Smith } 2181bef8e0ddSBarry Smith PetscFunctionReturn(0); 2182bef8e0ddSBarry Smith } 2183bef8e0ddSBarry Smith 2184be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 2185be6bf707SBarry Smith 2186fb2e594dSBarry Smith EXTERN_C_BEGIN 21874a2ae208SSatish Balay #undef __FUNCT__ 21884a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ" 2189be6bf707SBarry Smith int MatStoreValues_SeqAIJ(Mat mat) 2190be6bf707SBarry Smith { 2191be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2192273d9f13SBarry Smith int nz = aij->i[mat->m]+aij->indexshift,ierr; 2193be6bf707SBarry Smith 2194be6bf707SBarry Smith PetscFunctionBegin; 2195be6bf707SBarry Smith if (aij->nonew != 1) { 219629bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2197be6bf707SBarry Smith } 2198be6bf707SBarry Smith 2199be6bf707SBarry Smith /* allocate space for values if not already there */ 2200be6bf707SBarry Smith if (!aij->saved_values) { 220187828ca2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr); 2202be6bf707SBarry Smith } 2203be6bf707SBarry Smith 2204be6bf707SBarry Smith /* copy values over */ 220587828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 2206be6bf707SBarry Smith PetscFunctionReturn(0); 2207be6bf707SBarry Smith } 2208fb2e594dSBarry Smith EXTERN_C_END 2209be6bf707SBarry Smith 22104a2ae208SSatish Balay #undef __FUNCT__ 2211b9617806SBarry Smith #define __FUNCT__ "MatStoreValues" 2212be6bf707SBarry Smith /*@ 2213be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 2214be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2215be6bf707SBarry Smith nonlinear portion. 2216be6bf707SBarry Smith 2217be6bf707SBarry Smith Collect on Mat 2218be6bf707SBarry Smith 2219be6bf707SBarry Smith Input Parameters: 2220be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2221be6bf707SBarry Smith 222215091d37SBarry Smith Level: advanced 222315091d37SBarry Smith 2224be6bf707SBarry Smith Common Usage, with SNESSolve(): 2225be6bf707SBarry Smith $ Create Jacobian matrix 2226be6bf707SBarry Smith $ Set linear terms into matrix 2227be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 2228be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 2229be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 2230be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2231be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2232be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 2233be6bf707SBarry Smith $ In your Jacobian routine 2234be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2235be6bf707SBarry Smith $ Set nonlinear terms in matrix 2236be6bf707SBarry Smith 2237be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 2238be6bf707SBarry Smith $ // build linear portion of Jacobian 2239be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2240be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2241be6bf707SBarry Smith $ loop over nonlinear iterations 2242be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2243be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 2244be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 2245be6bf707SBarry Smith $ Solve linear system with Jacobian 2246be6bf707SBarry Smith $ endloop 2247be6bf707SBarry Smith 2248be6bf707SBarry Smith Notes: 2249be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 2250be6bf707SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before 2251be6bf707SBarry Smith calling this routine. 2252be6bf707SBarry Smith 2253be6bf707SBarry Smith .seealso: MatRetrieveValues() 2254be6bf707SBarry Smith 2255be6bf707SBarry Smith @*/ 2256be6bf707SBarry Smith int MatStoreValues(Mat mat) 2257be6bf707SBarry Smith { 2258be6bf707SBarry Smith int ierr,(*f)(Mat); 2259be6bf707SBarry Smith 2260be6bf707SBarry Smith PetscFunctionBegin; 2261be6bf707SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 226229bbc08cSBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 226329bbc08cSBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2264be6bf707SBarry Smith 2265b9617806SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void (**)())&f);CHKERRQ(ierr); 2266be6bf707SBarry Smith if (f) { 2267be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2268be6bf707SBarry Smith } else { 226929bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to store values"); 2270be6bf707SBarry Smith } 2271be6bf707SBarry Smith PetscFunctionReturn(0); 2272be6bf707SBarry Smith } 2273be6bf707SBarry Smith 2274fb2e594dSBarry Smith EXTERN_C_BEGIN 22754a2ae208SSatish Balay #undef __FUNCT__ 22764a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ" 2277be6bf707SBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat) 2278be6bf707SBarry Smith { 2279be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2280273d9f13SBarry Smith int nz = aij->i[mat->m]+aij->indexshift,ierr; 2281be6bf707SBarry Smith 2282be6bf707SBarry Smith PetscFunctionBegin; 2283be6bf707SBarry Smith if (aij->nonew != 1) { 228429bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2285be6bf707SBarry Smith } 2286be6bf707SBarry Smith if (!aij->saved_values) { 228729bbc08cSBarry Smith SETERRQ(1,"Must call MatStoreValues(A);first"); 2288be6bf707SBarry Smith } 2289be6bf707SBarry Smith 2290be6bf707SBarry Smith /* copy values over */ 229187828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 2292be6bf707SBarry Smith PetscFunctionReturn(0); 2293be6bf707SBarry Smith } 2294fb2e594dSBarry Smith EXTERN_C_END 2295be6bf707SBarry Smith 22964a2ae208SSatish Balay #undef __FUNCT__ 22974a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues" 2298be6bf707SBarry Smith /*@ 2299be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 2300be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2301be6bf707SBarry Smith nonlinear portion. 2302be6bf707SBarry Smith 2303be6bf707SBarry Smith Collect on Mat 2304be6bf707SBarry Smith 2305be6bf707SBarry Smith Input Parameters: 2306be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2307be6bf707SBarry Smith 230815091d37SBarry Smith Level: advanced 230915091d37SBarry Smith 2310be6bf707SBarry Smith .seealso: MatStoreValues() 2311be6bf707SBarry Smith 2312be6bf707SBarry Smith @*/ 2313be6bf707SBarry Smith int MatRetrieveValues(Mat mat) 2314be6bf707SBarry Smith { 2315be6bf707SBarry Smith int ierr,(*f)(Mat); 2316be6bf707SBarry Smith 2317be6bf707SBarry Smith PetscFunctionBegin; 2318be6bf707SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 231929bbc08cSBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 232029bbc08cSBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2321be6bf707SBarry Smith 2322b9617806SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void (**)())&f);CHKERRQ(ierr); 2323be6bf707SBarry Smith if (f) { 2324be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2325be6bf707SBarry Smith } else { 232629bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to retrieve values"); 2327be6bf707SBarry Smith } 2328be6bf707SBarry Smith PetscFunctionReturn(0); 2329be6bf707SBarry Smith } 2330be6bf707SBarry Smith 2331f83d6046SBarry Smith /* 2332f83d6046SBarry Smith This allows SeqAIJ matrices to be passed to the matlab engine 2333f83d6046SBarry Smith */ 233487828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) 2335f83d6046SBarry Smith #include "engine.h" /* Matlab include file */ 2336f83d6046SBarry Smith #include "mex.h" /* Matlab include file */ 2337f83d6046SBarry Smith EXTERN_C_BEGIN 23384a2ae208SSatish Balay #undef __FUNCT__ 23394a2ae208SSatish Balay #define __FUNCT__ "MatMatlabEnginePut_SeqAIJ" 2340f83d6046SBarry Smith int MatMatlabEnginePut_SeqAIJ(PetscObject obj,void *engine) 2341f83d6046SBarry Smith { 234266826eb6SBarry Smith int ierr,i,*ai,*aj; 2343f83d6046SBarry Smith Mat B = (Mat)obj; 234487828ca2SBarry Smith PetscScalar*array; 2345f83d6046SBarry Smith mxArray *mat; 2346d79a51d8SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)B->data; 2347d79a51d8SBarry Smith 2348f83d6046SBarry Smith PetscFunctionBegin; 234901820c62SBarry Smith mat = mxCreateSparse(B->n,B->m,aij->nz,mxREAL); 235087828ca2SBarry Smith ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 2351d79a51d8SBarry Smith /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 235266826eb6SBarry Smith ierr = PetscMemcpy(mxGetIr(mat),aij->j,aij->nz*sizeof(int));CHKERRQ(ierr); 235366826eb6SBarry Smith ierr = PetscMemcpy(mxGetJc(mat),aij->i,(B->m+1)*sizeof(int));CHKERRQ(ierr); 2354f83d6046SBarry Smith 235501820c62SBarry Smith /* Matlab indices start at 0 for sparse (what a surprise) */ 235601820c62SBarry Smith if (aij->indexshift) { 235701820c62SBarry Smith for (i=0; i<B->m+1; i++) { 235801820c62SBarry Smith ai[i]--; 2359d79a51d8SBarry Smith } 2360d79a51d8SBarry Smith for (i=0; i<aij->nz; i++) { 236101820c62SBarry Smith aj[i]--; 2362d79a51d8SBarry Smith } 2363d79a51d8SBarry Smith } 2364ca44d042SBarry Smith ierr = PetscObjectName(obj);CHKERRQ(ierr); 2365f83d6046SBarry Smith mxSetName(mat,obj->name); 2366f83d6046SBarry Smith engPutArray((Engine *)engine,mat); 2367f83d6046SBarry Smith PetscFunctionReturn(0); 2368f83d6046SBarry Smith } 2369f83d6046SBarry Smith EXTERN_C_END 237066826eb6SBarry Smith 237166826eb6SBarry Smith EXTERN_C_BEGIN 23724a2ae208SSatish Balay #undef __FUNCT__ 23734a2ae208SSatish Balay #define __FUNCT__ "MatMatlabEngineGet_SeqAIJ" 237466826eb6SBarry Smith int MatMatlabEngineGet_SeqAIJ(PetscObject obj,void *engine) 237566826eb6SBarry Smith { 237666826eb6SBarry Smith int ierr,ii; 237766826eb6SBarry Smith Mat mat = (Mat)obj; 237866826eb6SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 237966826eb6SBarry Smith mxArray *mmat; 238066826eb6SBarry Smith 23816c0721eeSBarry Smith PetscFunctionBegin; 238266826eb6SBarry Smith ierr = PetscFree(aij->a);CHKERRQ(ierr); 238366826eb6SBarry Smith aij->indexshift = 0; 238466826eb6SBarry Smith 238566826eb6SBarry Smith mmat = engGetArray((Engine *)engine,obj->name); 238666826eb6SBarry Smith 2387a65776f3SBarry Smith aij->nz = (mxGetJc(mmat))[mat->m]; 238887828ca2SBarry Smith ierr = PetscMalloc(aij->nz*(sizeof(int)+sizeof(PetscScalar))+(mat->m+1)*sizeof(int),&aij->a);CHKERRQ(ierr); 238966826eb6SBarry Smith aij->j = (int*)(aij->a + aij->nz); 239066826eb6SBarry Smith aij->i = aij->j + aij->nz; 239166826eb6SBarry Smith aij->singlemalloc = PETSC_TRUE; 239266826eb6SBarry Smith aij->freedata = PETSC_TRUE; 239366826eb6SBarry Smith 239487828ca2SBarry Smith ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 239566826eb6SBarry Smith /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 239666826eb6SBarry Smith ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr); 239766826eb6SBarry Smith ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->m+1)*sizeof(int));CHKERRQ(ierr); 239866826eb6SBarry Smith 239966826eb6SBarry Smith for (ii=0; ii<mat->m; ii++) { 240066826eb6SBarry Smith aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii]; 240166826eb6SBarry Smith } 240266826eb6SBarry Smith 240366826eb6SBarry Smith ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 240466826eb6SBarry Smith ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 240566826eb6SBarry Smith 240666826eb6SBarry Smith PetscFunctionReturn(0); 240766826eb6SBarry Smith } 240866826eb6SBarry Smith EXTERN_C_END 2409f83d6046SBarry Smith #endif 2410f83d6046SBarry Smith 2411be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 2412cb5b572fSBarry Smith 24134a2ae208SSatish Balay #undef __FUNCT__ 24144a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ" 241517ab2063SBarry Smith /*@C 2416682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 24170d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 24186e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 241951c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 24202bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 242117ab2063SBarry Smith 2422db81eaa0SLois Curfman McInnes Collective on MPI_Comm 2423db81eaa0SLois Curfman McInnes 242417ab2063SBarry Smith Input Parameters: 2425db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 242617ab2063SBarry Smith . m - number of rows 242717ab2063SBarry Smith . n - number of columns 242817ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 242951c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 24302bd5e0b2SLois Curfman McInnes (possibly different for each row) or PETSC_NULL 243117ab2063SBarry Smith 243217ab2063SBarry Smith Output Parameter: 2433416022c9SBarry Smith . A - the matrix 243417ab2063SBarry Smith 2435b259b22eSLois Curfman McInnes Notes: 243617ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 243717ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 24380002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 243944cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 244017ab2063SBarry Smith 244117ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2442a40aa06bSLois Curfman McInnes Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 24433d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 24446da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 244517ab2063SBarry Smith 2446682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 24474fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 2448682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 24496c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 24506c7ebb05SLois Curfman McInnes 24516c7ebb05SLois Curfman McInnes Options Database Keys: 2452db81eaa0SLois Curfman McInnes + -mat_aij_no_inode - Do not use inodes 2453db81eaa0SLois Curfman McInnes . -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5) 2454db81eaa0SLois Curfman McInnes - -mat_aij_oneindex - Internally use indexing starting at 1 2455db81eaa0SLois Curfman McInnes rather than 0. Note that when calling MatSetValues(), 2456db81eaa0SLois Curfman McInnes the user still MUST index entries starting at 0! 245717ab2063SBarry Smith 2458027ccd11SLois Curfman McInnes Level: intermediate 2459027ccd11SLois Curfman McInnes 246036db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 246136db0b34SBarry Smith 246217ab2063SBarry Smith @*/ 2463416022c9SBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,int *nnz,Mat *A) 246417ab2063SBarry Smith { 2465273d9f13SBarry Smith int ierr; 24666945ee14SBarry Smith 24673a40ed3dSBarry Smith PetscFunctionBegin; 2468273d9f13SBarry Smith ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr); 2469273d9f13SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 2470273d9f13SBarry Smith ierr = MatSeqAIJSetPreallocation(*A,nz,nnz);CHKERRQ(ierr); 2471273d9f13SBarry Smith PetscFunctionReturn(0); 2472273d9f13SBarry Smith } 2473273d9f13SBarry Smith 24744a2ae208SSatish Balay #undef __FUNCT__ 24754a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation" 2476273d9f13SBarry Smith /*@C 2477273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 2478273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 2479273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 2480273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 2481273d9f13SBarry Smith 2482273d9f13SBarry Smith Collective on MPI_Comm 2483273d9f13SBarry Smith 2484273d9f13SBarry Smith Input Parameters: 2485273d9f13SBarry Smith + comm - MPI communicator, set to PETSC_COMM_SELF 2486273d9f13SBarry Smith . m - number of rows 2487273d9f13SBarry Smith . n - number of columns 2488273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 2489273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 2490273d9f13SBarry Smith (possibly different for each row) or PETSC_NULL 2491273d9f13SBarry Smith 2492273d9f13SBarry Smith Output Parameter: 2493273d9f13SBarry Smith . A - the matrix 2494273d9f13SBarry Smith 2495273d9f13SBarry Smith Notes: 2496273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 2497273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 2498273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 2499273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 2500273d9f13SBarry Smith 2501273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2502273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 2503273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 2504273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 2505273d9f13SBarry Smith 2506273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 2507273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 2508273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 2509273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 2510273d9f13SBarry Smith 2511273d9f13SBarry Smith Options Database Keys: 2512273d9f13SBarry Smith + -mat_aij_no_inode - Do not use inodes 2513273d9f13SBarry Smith . -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5) 2514273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 2515273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 2516273d9f13SBarry Smith the user still MUST index entries starting at 0! 2517273d9f13SBarry Smith 2518273d9f13SBarry Smith Level: intermediate 2519273d9f13SBarry Smith 2520273d9f13SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 2521273d9f13SBarry Smith 2522273d9f13SBarry Smith @*/ 2523273d9f13SBarry Smith int MatSeqAIJSetPreallocation(Mat B,int nz,int *nnz) 2524273d9f13SBarry Smith { 2525273d9f13SBarry Smith Mat_SeqAIJ *b; 2526273d9f13SBarry Smith int i,len,ierr; 2527273d9f13SBarry Smith PetscTruth flg2; 2528273d9f13SBarry Smith 2529273d9f13SBarry Smith PetscFunctionBegin; 2530273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)B,MATSEQAIJ,&flg2);CHKERRQ(ierr); 2531273d9f13SBarry Smith if (!flg2) PetscFunctionReturn(0); 2532d5d45c9bSBarry Smith 2533435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 2534435da068SBarry Smith if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 2535b73539f3SBarry Smith if (nnz) { 2536273d9f13SBarry Smith for (i=0; i<B->m; i++) { 253729bbc08cSBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 25383a7fca6bSBarry Smith if (nnz[i] > B->n) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than row length: local row %d value %d rowlength %d",i,nnz[i],B->n); 2539b73539f3SBarry Smith } 2540b73539f3SBarry Smith } 2541b73539f3SBarry Smith 2542273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 2543273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 2544273d9f13SBarry Smith 2545b0a32e0cSBarry Smith ierr = PetscMalloc((B->m+1)*sizeof(int),&b->imax);CHKERRQ(ierr); 2546273d9f13SBarry Smith if (!nnz) { 2547435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 2548273d9f13SBarry Smith else if (nz <= 0) nz = 1; 2549273d9f13SBarry Smith for (i=0; i<B->m; i++) b->imax[i] = nz; 2550273d9f13SBarry Smith nz = nz*B->m; 2551273d9f13SBarry Smith } else { 2552273d9f13SBarry Smith nz = 0; 2553273d9f13SBarry Smith for (i=0; i<B->m; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 2554273d9f13SBarry Smith } 2555273d9f13SBarry Smith 2556273d9f13SBarry Smith /* allocate the matrix space */ 255787828ca2SBarry Smith len = nz*(sizeof(int) + sizeof(PetscScalar)) + (B->m+1)*sizeof(int); 2558b0a32e0cSBarry Smith ierr = PetscMalloc(len,&b->a);CHKERRQ(ierr); 2559273d9f13SBarry Smith b->j = (int*)(b->a + nz); 2560273d9f13SBarry Smith ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr); 2561273d9f13SBarry Smith b->i = b->j + nz; 2562273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 2563273d9f13SBarry Smith b->freedata = PETSC_TRUE; 2564273d9f13SBarry Smith 2565273d9f13SBarry Smith b->i[0] = -b->indexshift; 2566273d9f13SBarry Smith for (i=1; i<B->m+1; i++) { 2567273d9f13SBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 2568273d9f13SBarry Smith } 2569273d9f13SBarry Smith 2570273d9f13SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 2571b0a32e0cSBarry Smith ierr = PetscMalloc((B->m+1)*sizeof(int),&b->ilen);CHKERRQ(ierr); 2572b0a32e0cSBarry Smith PetscLogObjectMemory(B,len+2*(B->m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2573273d9f13SBarry Smith for (i=0; i<B->m; i++) { b->ilen[i] = 0;} 2574273d9f13SBarry Smith 2575273d9f13SBarry Smith b->nz = 0; 2576273d9f13SBarry Smith b->maxnz = nz; 2577273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 2578273d9f13SBarry Smith PetscFunctionReturn(0); 2579273d9f13SBarry Smith } 2580273d9f13SBarry Smith 2581273d9f13SBarry Smith EXTERN_C_BEGIN 25824a2ae208SSatish Balay #undef __FUNCT__ 25834a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ" 2584273d9f13SBarry Smith int MatCreate_SeqAIJ(Mat B) 2585273d9f13SBarry Smith { 2586273d9f13SBarry Smith Mat_SeqAIJ *b; 2587273d9f13SBarry Smith int ierr,size; 2588273d9f13SBarry Smith PetscTruth flg; 2589273d9f13SBarry Smith 2590273d9f13SBarry Smith PetscFunctionBegin; 2591273d9f13SBarry Smith ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr); 2592273d9f13SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 2593273d9f13SBarry Smith 2594273d9f13SBarry Smith B->m = B->M = PetscMax(B->m,B->M); 2595273d9f13SBarry Smith B->n = B->N = PetscMax(B->n,B->N); 2596273d9f13SBarry Smith 2597b0a32e0cSBarry Smith ierr = PetscNew(Mat_SeqAIJ,&b);CHKERRQ(ierr); 2598b0a32e0cSBarry Smith B->data = (void*)b; 2599549d3d68SSatish Balay ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr); 2600549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 2601416022c9SBarry Smith B->factor = 0; 2602416022c9SBarry Smith B->lupivotthreshold = 1.0; 260390f02eecSBarry Smith B->mapping = 0; 260487828ca2SBarry Smith ierr = PetscOptionsGetReal(PETSC_NULL,"-mat_lu_pivotthreshold",&B->lupivotthreshold,PETSC_NULL);CHKERRQ(ierr); 2605b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-pc_ilu_preserve_row_sums",&b->ilu_preserve_row_sums);CHKERRQ(ierr); 2606416022c9SBarry Smith b->row = 0; 2607416022c9SBarry Smith b->col = 0; 260882bf6240SBarry Smith b->icol = 0; 2609416022c9SBarry Smith b->indexshift = 0; 2610b810aeb4SBarry Smith b->reallocs = 0; 2611b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_aij_oneindex",&flg);CHKERRQ(ierr); 261269957df2SSatish Balay if (flg) b->indexshift = -1; 261317ab2063SBarry Smith 26148a124369SBarry Smith ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr); 26158a124369SBarry Smith ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr); 2616a5ae1ecdSBarry Smith 2617f1e2ffcdSBarry Smith b->sorted = PETSC_FALSE; 261836db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 2619f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 2620416022c9SBarry Smith b->nonew = 0; 2621416022c9SBarry Smith b->diag = 0; 2622416022c9SBarry Smith b->solve_work = 0; 262371bd300dSLois Curfman McInnes b->spptr = 0; 2624b65db4caSBarry Smith b->inode.use = PETSC_TRUE; 2625754ec7b1SSatish Balay b->inode.node_count = 0; 2626754ec7b1SSatish Balay b->inode.size = 0; 26276c7ebb05SLois Curfman McInnes b->inode.limit = 5; 26286c7ebb05SLois Curfman McInnes b->inode.max_limit = 5; 2629be6bf707SBarry Smith b->saved_values = 0; 2630d7f994e1SBarry Smith b->idiag = 0; 2631d7f994e1SBarry Smith b->ssor = 0; 2632f1e2ffcdSBarry Smith b->keepzeroedrows = PETSC_FALSE; 263317ab2063SBarry Smith 263435d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 263535d8aa7fSBarry Smith 2636aa482453SBarry Smith #if defined(PETSC_HAVE_SUPERLU) 2637b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_aij_superlu",&flg);CHKERRQ(ierr); 263869957df2SSatish Balay if (flg) { ierr = MatUseSuperLU_SeqAIJ(B);CHKERRQ(ierr); } 26394b14c69eSBarry Smith #endif 2640b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_aij_essl",&flg);CHKERRQ(ierr); 264169957df2SSatish Balay if (flg) { ierr = MatUseEssl_SeqAIJ(B);CHKERRQ(ierr); } 2642b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_aij_lusol",&flg);CHKERRQ(ierr); 2643cd5578b5SBarry Smith if (flg) { ierr = MatUseLUSOL_SeqAIJ(B);CHKERRQ(ierr); } 2644b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_aij_matlab",&flg);CHKERRQ(ierr); 2645ca44d042SBarry Smith if (flg) {ierr = MatUseMatlab_SeqAIJ(B);CHKERRQ(ierr);} 2646b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_aij_dxml",&flg);CHKERRQ(ierr); 264769957df2SSatish Balay if (flg) { 264829bbc08cSBarry Smith if (!b->indexshift) SETERRQ(PETSC_ERR_LIB,"need -mat_aij_oneindex with -mat_aij_dxml"); 2649416022c9SBarry Smith ierr = MatUseDXML_SeqAIJ(B);CHKERRQ(ierr); 265017ab2063SBarry Smith } 2651f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C", 2652bef8e0ddSBarry Smith "MatSeqAIJSetColumnIndices_SeqAIJ", 2653bc4b532fSSatish Balay MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 2654f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 2655be6bf707SBarry Smith "MatStoreValues_SeqAIJ", 2656bc4b532fSSatish Balay MatStoreValues_SeqAIJ);CHKERRQ(ierr); 2657f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 2658be6bf707SBarry Smith "MatRetrieveValues_SeqAIJ", 2659bc4b532fSSatish Balay MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 266087828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) 2661f83d6046SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatMatlabEnginePut_SeqAIJ",MatMatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 266266826eb6SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatMatlabEngineGet_SeqAIJ",MatMatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 2663f83d6046SBarry Smith #endif 26643a40ed3dSBarry Smith PetscFunctionReturn(0); 266517ab2063SBarry Smith } 2666273d9f13SBarry Smith EXTERN_C_END 266717ab2063SBarry Smith 26684a2ae208SSatish Balay #undef __FUNCT__ 26694a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqAIJ" 2670be6bf707SBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 267117ab2063SBarry Smith { 2672416022c9SBarry Smith Mat C; 2673416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 2674273d9f13SBarry Smith int i,len,m = A->m,shift = a->indexshift,ierr; 267517ab2063SBarry Smith 26763a40ed3dSBarry Smith PetscFunctionBegin; 26774043dd9cSLois Curfman McInnes *B = 0; 2678273d9f13SBarry Smith ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr); 2679273d9f13SBarry Smith ierr = MatSetType(C,MATSEQAIJ);CHKERRQ(ierr); 2680273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 2681273d9f13SBarry Smith 2682416022c9SBarry Smith C->factor = A->factor; 2683416022c9SBarry Smith c->row = 0; 2684416022c9SBarry Smith c->col = 0; 268582bf6240SBarry Smith c->icol = 0; 2686416022c9SBarry Smith c->indexshift = shift; 2687f1e2ffcdSBarry Smith c->keepzeroedrows = a->keepzeroedrows; 2688c456f294SBarry Smith C->assembled = PETSC_TRUE; 268917ab2063SBarry Smith 2690273d9f13SBarry Smith C->M = A->m; 2691273d9f13SBarry Smith C->N = A->n; 269217ab2063SBarry Smith 2693b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&c->imax);CHKERRQ(ierr); 2694b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&c->ilen);CHKERRQ(ierr); 269517ab2063SBarry Smith for (i=0; i<m; i++) { 2696416022c9SBarry Smith c->imax[i] = a->imax[i]; 2697416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 269817ab2063SBarry Smith } 269917ab2063SBarry Smith 270017ab2063SBarry Smith /* allocate the matrix space */ 2701f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 270287828ca2SBarry Smith len = (m+1)*sizeof(int)+(a->i[m])*(sizeof(PetscScalar)+sizeof(int)); 2703b0a32e0cSBarry Smith ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr); 2704416022c9SBarry Smith c->j = (int*)(c->a + a->i[m] + shift); 2705416022c9SBarry Smith c->i = c->j + a->i[m] + shift; 2706549d3d68SSatish Balay ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));CHKERRQ(ierr); 270717ab2063SBarry Smith if (m > 0) { 2708549d3d68SSatish Balay ierr = PetscMemcpy(c->j,a->j,(a->i[m]+shift)*sizeof(int));CHKERRQ(ierr); 2709be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 271087828ca2SBarry Smith ierr = PetscMemcpy(c->a,a->a,(a->i[m]+shift)*sizeof(PetscScalar));CHKERRQ(ierr); 2711be6bf707SBarry Smith } else { 271287828ca2SBarry Smith ierr = PetscMemzero(c->a,(a->i[m]+shift)*sizeof(PetscScalar));CHKERRQ(ierr); 271317ab2063SBarry Smith } 271408480c60SBarry Smith } 271517ab2063SBarry Smith 2716b0a32e0cSBarry Smith PetscLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2717416022c9SBarry Smith c->sorted = a->sorted; 2718416022c9SBarry Smith c->roworiented = a->roworiented; 2719416022c9SBarry Smith c->nonew = a->nonew; 27207a743949SBarry Smith c->ilu_preserve_row_sums = a->ilu_preserve_row_sums; 2721be6bf707SBarry Smith c->saved_values = 0; 2722d7f994e1SBarry Smith c->idiag = 0; 2723d7f994e1SBarry Smith c->ssor = 0; 272436db0b34SBarry Smith c->ignorezeroentries = a->ignorezeroentries; 272536db0b34SBarry Smith c->freedata = PETSC_TRUE; 272617ab2063SBarry Smith 2727416022c9SBarry Smith if (a->diag) { 2728b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&c->diag);CHKERRQ(ierr); 2729b0a32e0cSBarry Smith PetscLogObjectMemory(C,(m+1)*sizeof(int)); 273017ab2063SBarry Smith for (i=0; i<m; i++) { 2731416022c9SBarry Smith c->diag[i] = a->diag[i]; 273217ab2063SBarry Smith } 27333a40ed3dSBarry Smith } else c->diag = 0; 2734b65db4caSBarry Smith c->inode.use = a->inode.use; 27356c7ebb05SLois Curfman McInnes c->inode.limit = a->inode.limit; 27366c7ebb05SLois Curfman McInnes c->inode.max_limit = a->inode.max_limit; 2737754ec7b1SSatish Balay if (a->inode.size){ 2738b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&c->inode.size);CHKERRQ(ierr); 2739754ec7b1SSatish Balay c->inode.node_count = a->inode.node_count; 2740549d3d68SSatish Balay ierr = PetscMemcpy(c->inode.size,a->inode.size,(m+1)*sizeof(int));CHKERRQ(ierr); 2741754ec7b1SSatish Balay } else { 2742754ec7b1SSatish Balay c->inode.size = 0; 2743754ec7b1SSatish Balay c->inode.node_count = 0; 2744754ec7b1SSatish Balay } 2745416022c9SBarry Smith c->nz = a->nz; 2746416022c9SBarry Smith c->maxnz = a->maxnz; 2747416022c9SBarry Smith c->solve_work = 0; 274876dd722bSSatish Balay c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 2749273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 2750754ec7b1SSatish Balay 2751416022c9SBarry Smith *B = C; 2752b0a32e0cSBarry Smith ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 27533a40ed3dSBarry Smith PetscFunctionReturn(0); 275417ab2063SBarry Smith } 275517ab2063SBarry Smith 2756273d9f13SBarry Smith EXTERN_C_BEGIN 27574a2ae208SSatish Balay #undef __FUNCT__ 27584a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ" 2759b0a32e0cSBarry Smith int MatLoad_SeqAIJ(PetscViewer viewer,MatType type,Mat *A) 276017ab2063SBarry Smith { 2761416022c9SBarry Smith Mat_SeqAIJ *a; 2762416022c9SBarry Smith Mat B; 276317699dbbSLois Curfman McInnes int i,nz,ierr,fd,header[4],size,*rowlengths = 0,M,N,shift; 2764bcd2baecSBarry Smith MPI_Comm comm; 276517ab2063SBarry Smith 27663a40ed3dSBarry Smith PetscFunctionBegin; 2767e864ced6SBarry Smith ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 2768d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 276929bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,"view must have one processor"); 2770b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 27710752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 277229bbc08cSBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 277317ab2063SBarry Smith M = header[1]; N = header[2]; nz = header[3]; 277417ab2063SBarry Smith 2775d64ed03dSBarry Smith if (nz < 0) { 277629bbc08cSBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 2777d64ed03dSBarry Smith } 2778d64ed03dSBarry Smith 277917ab2063SBarry Smith /* read in row lengths */ 2780b0a32e0cSBarry Smith ierr = PetscMalloc(M*sizeof(int),&rowlengths);CHKERRQ(ierr); 27810752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 278217ab2063SBarry Smith 278317ab2063SBarry Smith /* create our matrix */ 2784416022c9SBarry Smith ierr = MatCreateSeqAIJ(comm,M,N,0,rowlengths,A);CHKERRQ(ierr); 2785416022c9SBarry Smith B = *A; 2786416022c9SBarry Smith a = (Mat_SeqAIJ*)B->data; 2787416022c9SBarry Smith shift = a->indexshift; 278817ab2063SBarry Smith 278917ab2063SBarry Smith /* read in column indices and adjust for Fortran indexing*/ 27900752156aSBarry Smith ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 279117ab2063SBarry Smith if (shift) { 279217ab2063SBarry Smith for (i=0; i<nz; i++) { 2793416022c9SBarry Smith a->j[i] += 1; 279417ab2063SBarry Smith } 279517ab2063SBarry Smith } 279617ab2063SBarry Smith 279717ab2063SBarry Smith /* read in nonzero values */ 27980752156aSBarry Smith ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 279917ab2063SBarry Smith 280017ab2063SBarry Smith /* set matrix "i" values */ 2801416022c9SBarry Smith a->i[0] = -shift; 280217ab2063SBarry Smith for (i=1; i<= M; i++) { 2803416022c9SBarry Smith a->i[i] = a->i[i-1] + rowlengths[i-1]; 2804416022c9SBarry Smith a->ilen[i-1] = rowlengths[i-1]; 280517ab2063SBarry Smith } 2806606d414cSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 280717ab2063SBarry Smith 28086d4a8577SBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 28096d4a8577SBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 28103a40ed3dSBarry Smith PetscFunctionReturn(0); 281117ab2063SBarry Smith } 2812273d9f13SBarry Smith EXTERN_C_END 281317ab2063SBarry Smith 28144a2ae208SSatish Balay #undef __FUNCT__ 2815b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ" 28168f6be9afSLois Curfman McInnes int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg) 28177264ac53SSatish Balay { 28187264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data; 28190f5bd95cSBarry Smith int ierr; 2820273d9f13SBarry Smith PetscTruth flag; 28217264ac53SSatish Balay 28223a40ed3dSBarry Smith PetscFunctionBegin; 2823273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)B,MATSEQAIJ,&flag);CHKERRQ(ierr); 2824273d9f13SBarry Smith if (!flag) SETERRQ(PETSC_ERR_ARG_INCOMP,"Matrices must be same type"); 28257264ac53SSatish Balay 28267264ac53SSatish Balay /* If the matrix dimensions are not equal,or no of nonzeros or shift */ 2827273d9f13SBarry Smith if ((A->m != B->m) || (A->n != B->n) ||(a->nz != b->nz)|| (a->indexshift != b->indexshift)) { 2828ca44d042SBarry Smith *flg = PETSC_FALSE; 2829ca44d042SBarry Smith PetscFunctionReturn(0); 2830bcd2baecSBarry Smith } 28317264ac53SSatish Balay 28327264ac53SSatish Balay /* if the a->i are the same */ 2833273d9f13SBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->m+1)*sizeof(int),flg);CHKERRQ(ierr); 28340f5bd95cSBarry Smith if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 28357264ac53SSatish Balay 28367264ac53SSatish Balay /* if a->j are the same */ 28370f5bd95cSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(int),flg);CHKERRQ(ierr); 28380f5bd95cSBarry Smith if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 2839bcd2baecSBarry Smith 2840bcd2baecSBarry Smith /* if a->a are the same */ 284187828ca2SBarry Smith ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 28420f5bd95cSBarry Smith 28433a40ed3dSBarry Smith PetscFunctionReturn(0); 28447264ac53SSatish Balay 28457264ac53SSatish Balay } 284636db0b34SBarry Smith 28474a2ae208SSatish Balay #undef __FUNCT__ 28484a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays" 284936db0b34SBarry Smith /*@C 285036db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 285136db0b34SBarry Smith provided by the user. 285236db0b34SBarry Smith 285336db0b34SBarry Smith Coolective on MPI_Comm 285436db0b34SBarry Smith 285536db0b34SBarry Smith Input Parameters: 285636db0b34SBarry Smith + comm - must be an MPI communicator of size 1 285736db0b34SBarry Smith . m - number of rows 285836db0b34SBarry Smith . n - number of columns 285936db0b34SBarry Smith . i - row indices 286036db0b34SBarry Smith . j - column indices 286136db0b34SBarry Smith - a - matrix values 286236db0b34SBarry Smith 286336db0b34SBarry Smith Output Parameter: 286436db0b34SBarry Smith . mat - the matrix 286536db0b34SBarry Smith 286636db0b34SBarry Smith Level: intermediate 286736db0b34SBarry Smith 286836db0b34SBarry Smith Notes: 28690551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 287036db0b34SBarry Smith once the matrix is destroyed 287136db0b34SBarry Smith 287236db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 287336db0b34SBarry Smith 287436db0b34SBarry Smith The i and j indices can be either 0- or 1 based 287536db0b34SBarry Smith 287636db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ() 287736db0b34SBarry Smith 287836db0b34SBarry Smith @*/ 287987828ca2SBarry Smith int MatCreateSeqAIJWithArrays(MPI_Comm comm,int m,int n,int* i,int*j,PetscScalar *a,Mat *mat) 288036db0b34SBarry Smith { 288136db0b34SBarry Smith int ierr,ii; 288236db0b34SBarry Smith Mat_SeqAIJ *aij; 288336db0b34SBarry Smith 288436db0b34SBarry Smith PetscFunctionBegin; 288536db0b34SBarry Smith ierr = MatCreateSeqAIJ(comm,m,n,0,0,mat);CHKERRQ(ierr); 288636db0b34SBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 288736db0b34SBarry Smith ierr = PetscFree(aij->a);CHKERRQ(ierr); 288836db0b34SBarry Smith 288936db0b34SBarry Smith if (i[0] == 1) { 289036db0b34SBarry Smith aij->indexshift = -1; 289136db0b34SBarry Smith } else if (i[0]) { 289229bbc08cSBarry Smith SETERRQ(1,"i (row indices) do not start with 0 or 1"); 289336db0b34SBarry Smith } 289436db0b34SBarry Smith aij->i = i; 289536db0b34SBarry Smith aij->j = j; 289636db0b34SBarry Smith aij->a = a; 289736db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 289836db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 289936db0b34SBarry Smith aij->freedata = PETSC_FALSE; 290036db0b34SBarry Smith 290136db0b34SBarry Smith for (ii=0; ii<m; ii++) { 290236db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 29039860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g) 290429bbc08cSBarry Smith if (i[ii+1] - i[ii] < 0) SETERRQ2(1,"Negative row length in i (row indices) row = %d length = %d",ii,i[ii+1] - i[ii]); 290536db0b34SBarry Smith #endif 290636db0b34SBarry Smith } 29079860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g) 290836db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 290929bbc08cSBarry Smith if (j[ii] < -aij->indexshift) SETERRQ2(1,"Negative column index at location = %d index = %d",ii,j[ii]); 291029bbc08cSBarry Smith if (j[ii] > n - 1 -aij->indexshift) SETERRQ2(1,"Column index to large at location = %d index = %d",ii,j[ii]); 291136db0b34SBarry Smith } 291236db0b34SBarry Smith #endif 291336db0b34SBarry Smith 2914b65db4caSBarry Smith /* changes indices to start at 0 */ 2915b65db4caSBarry Smith if (i[0]) { 2916b65db4caSBarry Smith aij->indexshift = 0; 2917b65db4caSBarry Smith for (ii=0; ii<m; ii++) { 2918b65db4caSBarry Smith i[ii]--; 2919b65db4caSBarry Smith } 2920b65db4caSBarry Smith for (ii=0; ii<i[m]; ii++) { 2921b65db4caSBarry Smith j[ii]--; 2922b65db4caSBarry Smith } 2923b65db4caSBarry Smith } 2924b65db4caSBarry Smith 2925b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2926b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 292736db0b34SBarry Smith PetscFunctionReturn(0); 292836db0b34SBarry Smith } 292936db0b34SBarry Smith 2930cc8ba8e1SBarry Smith #undef __FUNCT__ 2931ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ" 2932ee4f033dSBarry Smith int MatSetColoring_SeqAIJ(Mat A,ISColoring coloring) 2933cc8ba8e1SBarry Smith { 2934cc8ba8e1SBarry Smith int ierr; 2935cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 293636db0b34SBarry Smith 2937cc8ba8e1SBarry Smith PetscFunctionBegin; 2938cc8ba8e1SBarry Smith ierr = ISColoringReference(coloring);CHKERRQ(ierr); 2939cc8ba8e1SBarry Smith a->coloring = coloring; 2940cc8ba8e1SBarry Smith PetscFunctionReturn(0); 2941cc8ba8e1SBarry Smith } 2942cc8ba8e1SBarry Smith 294387828ca2SBarry Smith #if defined(PETSC_HAVE_ADIC) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) 2944ee4f033dSBarry Smith EXTERN_C_BEGIN 2945cc8ba8e1SBarry Smith #include "adic_utils.h" 2946ee4f033dSBarry Smith EXTERN_C_END 2947cc8ba8e1SBarry Smith 2948cc8ba8e1SBarry Smith #undef __FUNCT__ 2949ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ" 2950ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues) 2951cc8ba8e1SBarry Smith { 2952cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2953ee4f033dSBarry Smith int m = A->m,*ii = a->i,*jj = a->j,nz,i,*color,j,nlen; 295487828ca2SBarry Smith PetscScalar*v = a->a,*values; 2955ee4f033dSBarry Smith char *cadvalues = (char *)advalues; 2956cc8ba8e1SBarry Smith 2957cc8ba8e1SBarry Smith PetscFunctionBegin; 2958cc8ba8e1SBarry Smith if (!a->coloring) SETERRQ(1,"Coloring not set for matrix"); 2959ee4f033dSBarry Smith nlen = my_AD_GetDerivTypeSize(); 2960cc8ba8e1SBarry Smith color = a->coloring->colors; 2961cc8ba8e1SBarry Smith /* loop over rows */ 2962cc8ba8e1SBarry Smith for (i=0; i<m; i++) { 2963cc8ba8e1SBarry Smith nz = ii[i+1] - ii[i]; 2964cc8ba8e1SBarry Smith /* loop over columns putting computed value into matrix */ 2965ee4f033dSBarry Smith values = my_AD_GetGradArray(cadvalues); 2966cc8ba8e1SBarry Smith for (j=0; j<nz; j++) { 2967cc8ba8e1SBarry Smith *v++ = values[color[*jj++]]; 2968cc8ba8e1SBarry Smith } 2969ee4f033dSBarry Smith cadvalues += nlen; /* jump to next row of derivatives */ 2970ee4f033dSBarry Smith } 2971ee4f033dSBarry Smith PetscFunctionReturn(0); 2972ee4f033dSBarry Smith } 2973ee4f033dSBarry Smith 2974ee4f033dSBarry Smith #else 2975ee4f033dSBarry Smith 2976ee4f033dSBarry Smith #undef __FUNCT__ 2977ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ" 2978ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues) 2979ee4f033dSBarry Smith { 2980ee4f033dSBarry Smith PetscFunctionBegin; 2981ee4f033dSBarry Smith SETERRQ(1,"PETSc installed without ADIC"); 2982ee4f033dSBarry Smith } 2983ee4f033dSBarry Smith 2984ee4f033dSBarry Smith #endif 2985ee4f033dSBarry Smith 2986ee4f033dSBarry Smith #undef __FUNCT__ 2987ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ" 2988ee4f033dSBarry Smith int MatSetValuesAdifor_SeqAIJ(Mat A,int nl,void *advalues) 2989ee4f033dSBarry Smith { 2990ee4f033dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2991ee4f033dSBarry Smith int m = A->m,*ii = a->i,*jj = a->j,nz,i,*color,j; 299287828ca2SBarry Smith PetscScalar *v = a->a,*values = (PetscScalar *)advalues; 2993ee4f033dSBarry Smith 2994ee4f033dSBarry Smith PetscFunctionBegin; 2995ee4f033dSBarry Smith if (!a->coloring) SETERRQ(1,"Coloring not set for matrix"); 2996ee4f033dSBarry Smith color = a->coloring->colors; 2997ee4f033dSBarry Smith /* loop over rows */ 2998ee4f033dSBarry Smith for (i=0; i<m; i++) { 2999ee4f033dSBarry Smith nz = ii[i+1] - ii[i]; 3000ee4f033dSBarry Smith /* loop over columns putting computed value into matrix */ 3001ee4f033dSBarry Smith for (j=0; j<nz; j++) { 3002ee4f033dSBarry Smith *v++ = values[color[*jj++]]; 3003ee4f033dSBarry Smith } 3004ee4f033dSBarry Smith values += nl; /* jump to next row of derivatives */ 3005cc8ba8e1SBarry Smith } 3006cc8ba8e1SBarry Smith PetscFunctionReturn(0); 3007cc8ba8e1SBarry Smith } 300836db0b34SBarry Smith 3009