1*bc4b532fSSatish Balay /*$Id: aij.c,v 1.343 2000/05/04 16:25:26 bsmith Exp balay $*/ 2d5d45c9bSBarry Smith /* 33369ce9aSBarry Smith Defines the basic matrix operations for the AIJ (compressed row) 4d5d45c9bSBarry Smith matrix storage format. 5d5d45c9bSBarry Smith */ 63369ce9aSBarry Smith 73369ce9aSBarry Smith #include "sys.h" 870f55243SBarry Smith #include "src/mat/impls/aij/seq/aij.h" 9f5eb4b81SSatish Balay #include "src/vec/vecimpl.h" 10f5eb4b81SSatish Balay #include "src/inline/spops.h" 118d195f9aSBarry Smith #include "src/inline/dot.h" 12eeb667a2SSatish Balay #include "bitarray.h" 1317ab2063SBarry Smith 14a2ce50c7SBarry Smith 15bcd2baecSBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**); 1617ab2063SBarry Smith 175615d1e5SSatish Balay #undef __FUNC__ 18b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetRowIJ_SeqAIJ" 1936db0b34SBarry Smith int MatGetRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *m,int **ia,int **ja,PetscTruth *done) 2017ab2063SBarry Smith { 21416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 226945ee14SBarry Smith int ierr,i,ishift; 2317ab2063SBarry Smith 243a40ed3dSBarry Smith PetscFunctionBegin; 2531625ec5SSatish Balay *m = A->m; 263a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 276945ee14SBarry Smith ishift = a->indexshift; 286945ee14SBarry Smith if (symmetric) { 2931625ec5SSatish Balay ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr); 306945ee14SBarry Smith } else if (oshift == 0 && ishift == -1) { 3131625ec5SSatish Balay int nz = a->i[a->m]; 323b2fbd54SBarry Smith /* malloc space and subtract 1 from i and j indices */ 3331625ec5SSatish Balay *ia = (int*)PetscMalloc((a->m+1)*sizeof(int));CHKPTRQ(*ia); 343b2fbd54SBarry Smith *ja = (int*)PetscMalloc((nz+1)*sizeof(int));CHKPTRQ(*ja); 353b2fbd54SBarry Smith for (i=0; i<nz; i++) (*ja)[i] = a->j[i] - 1; 3631625ec5SSatish Balay for (i=0; i<a->m+1; i++) (*ia)[i] = a->i[i] - 1; 376945ee14SBarry Smith } else if (oshift == 1 && ishift == 0) { 3831625ec5SSatish Balay int nz = a->i[a->m] + 1; 393b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 4031625ec5SSatish Balay *ia = (int*)PetscMalloc((a->m+1)*sizeof(int));CHKPTRQ(*ia); 413b2fbd54SBarry Smith *ja = (int*)PetscMalloc((nz+1)*sizeof(int));CHKPTRQ(*ja); 423b2fbd54SBarry Smith for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1; 4331625ec5SSatish Balay for (i=0; i<a->m+1; i++) (*ia)[i] = a->i[i] + 1; 446945ee14SBarry Smith } else { 456945ee14SBarry Smith *ia = a->i; *ja = a->j; 46a2ce50c7SBarry Smith } 473a40ed3dSBarry Smith PetscFunctionReturn(0); 48a2744918SBarry Smith } 49a2744918SBarry Smith 505615d1e5SSatish Balay #undef __FUNC__ 51b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatRestoreRowIJ_SeqAIJ" 5236db0b34SBarry Smith int MatRestoreRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja,PetscTruth *done) 536945ee14SBarry Smith { 546945ee14SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 55606d414cSSatish Balay int ishift = a->indexshift,ierr; 566945ee14SBarry Smith 573a40ed3dSBarry Smith PetscFunctionBegin; 583a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 593b2fbd54SBarry Smith if (symmetric || (oshift == 0 && ishift == -1) || (oshift == 1 && ishift == 0)) { 60606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 61606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 62bcd2baecSBarry Smith } 633a40ed3dSBarry Smith PetscFunctionReturn(0); 6417ab2063SBarry Smith } 6517ab2063SBarry Smith 665615d1e5SSatish Balay #undef __FUNC__ 67b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetColumnIJ_SeqAIJ" 6836db0b34SBarry Smith int MatGetColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done) 693b2fbd54SBarry Smith { 703b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 71a93ec695SBarry Smith int ierr,i,ishift = a->indexshift,*collengths,*cia,*cja,n = A->n,m = A->m; 72a93ec695SBarry Smith int nz = a->i[m]+ishift,row,*jj,mr,col; 733b2fbd54SBarry Smith 743a40ed3dSBarry Smith PetscFunctionBegin; 753b2fbd54SBarry Smith *nn = A->n; 763a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 773b2fbd54SBarry Smith if (symmetric) { 78179192dfSSatish Balay ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr); 793b2fbd54SBarry Smith } else { 8061d2ded1SBarry Smith collengths = (int*)PetscMalloc((n+1)*sizeof(int));CHKPTRQ(collengths); 81549d3d68SSatish Balay ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr); 823b2fbd54SBarry Smith cia = (int*)PetscMalloc((n+1)*sizeof(int));CHKPTRQ(cia); 83a93ec695SBarry Smith cja = (int*)PetscMalloc((nz+1)*sizeof(int));CHKPTRQ(cja); 843b2fbd54SBarry Smith jj = a->j; 853b2fbd54SBarry Smith for (i=0; i<nz; i++) { 863b2fbd54SBarry Smith collengths[jj[i] + ishift]++; 873b2fbd54SBarry Smith } 883b2fbd54SBarry Smith cia[0] = oshift; 893b2fbd54SBarry Smith for (i=0; i<n; i++) { 903b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 913b2fbd54SBarry Smith } 92549d3d68SSatish Balay ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr); 933b2fbd54SBarry Smith jj = a->j; 94a93ec695SBarry Smith for (row=0; row<m; row++) { 95a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 96a93ec695SBarry Smith for (i=0; i<mr; i++) { 973b2fbd54SBarry Smith col = *jj++ + ishift; 983b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 993b2fbd54SBarry Smith } 1003b2fbd54SBarry Smith } 101606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 1023b2fbd54SBarry Smith *ia = cia; *ja = cja; 1033b2fbd54SBarry Smith } 1043a40ed3dSBarry Smith PetscFunctionReturn(0); 1053b2fbd54SBarry Smith } 1063b2fbd54SBarry Smith 1075615d1e5SSatish Balay #undef __FUNC__ 108b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatRestoreColumnIJ_SeqAIJ" 10936db0b34SBarry Smith int MatRestoreColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja,PetscTruth *done) 1103b2fbd54SBarry Smith { 111606d414cSSatish Balay int ierr; 112606d414cSSatish Balay 1133a40ed3dSBarry Smith PetscFunctionBegin; 1143a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 1153b2fbd54SBarry Smith 116606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 117606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 1183b2fbd54SBarry Smith 1193a40ed3dSBarry Smith PetscFunctionReturn(0); 1203b2fbd54SBarry Smith } 1213b2fbd54SBarry Smith 122227d817aSBarry Smith #define CHUNKSIZE 15 12317ab2063SBarry Smith 1245615d1e5SSatish Balay #undef __FUNC__ 125b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatSetValues_SeqAIJ" 12661d2ded1SBarry Smith int MatSetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 12717ab2063SBarry Smith { 128416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 129416022c9SBarry Smith int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted = a->sorted; 1304b0e389bSBarry Smith int *imax = a->imax,*ai = a->i,*ailen = a->ilen,roworiented = a->roworiented; 131549d3d68SSatish Balay int *aj = a->j,nonew = a->nonew,shift = a->indexshift,ierr; 132416022c9SBarry Smith Scalar *ap,value,*aa = a->a; 13336db0b34SBarry Smith PetscTruth ignorezeroentries = ((a->ignorezeroentries && is == ADD_VALUES) ? PETSC_TRUE:PETSC_FALSE); 13417ab2063SBarry Smith 1353a40ed3dSBarry Smith PetscFunctionBegin; 13617ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 137416022c9SBarry Smith row = im[k]; 1385ef9f2a5SBarry Smith if (row < 0) continue; 139aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 14032e87ba3SBarry Smith if (row >= a->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large: row %d max %d",row,a->m); 1413b2fbd54SBarry Smith #endif 14217ab2063SBarry Smith rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 14317ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 144416022c9SBarry Smith low = 0; 14517ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 1465ef9f2a5SBarry Smith if (in[l] < 0) continue; 147aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 14832e87ba3SBarry Smith if (in[l] >= a->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large: col %d max %d",in[l],a->n); 1493b2fbd54SBarry Smith #endif 1504b0e389bSBarry Smith col = in[l] - shift; 1514b0e389bSBarry Smith if (roworiented) { 1525ef9f2a5SBarry Smith value = v[l + k*n]; 153bef8e0ddSBarry Smith } else { 1544b0e389bSBarry Smith value = v[k + l*m]; 1554b0e389bSBarry Smith } 15636db0b34SBarry Smith if (value == 0.0 && ignorezeroentries) continue; 15736db0b34SBarry Smith 158416022c9SBarry Smith if (!sorted) low = 0; high = nrow; 159416022c9SBarry Smith while (high-low > 5) { 160416022c9SBarry Smith t = (low+high)/2; 161416022c9SBarry Smith if (rp[t] > col) high = t; 162416022c9SBarry Smith else low = t; 16317ab2063SBarry Smith } 164416022c9SBarry Smith for (i=low; i<high; i++) { 16517ab2063SBarry Smith if (rp[i] > col) break; 16617ab2063SBarry Smith if (rp[i] == col) { 167416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 16817ab2063SBarry Smith else ap[i] = value; 16917ab2063SBarry Smith goto noinsert; 17017ab2063SBarry Smith } 17117ab2063SBarry Smith } 172c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 173a8c6a408SBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 17417ab2063SBarry Smith if (nrow >= rmax) { 17517ab2063SBarry Smith /* there is no extra room in row, therefore enlarge */ 176416022c9SBarry Smith int new_nz = ai[a->m] + CHUNKSIZE,len,*new_i,*new_j; 17717ab2063SBarry Smith Scalar *new_a; 17817ab2063SBarry Smith 179a8c6a408SBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 18096854ed6SLois Curfman McInnes 18117ab2063SBarry Smith /* malloc new storage space */ 182416022c9SBarry Smith len = new_nz*(sizeof(int)+sizeof(Scalar))+(a->m+1)*sizeof(int); 1830452661fSBarry Smith new_a = (Scalar*)PetscMalloc(len);CHKPTRQ(new_a); 18417ab2063SBarry Smith new_j = (int*)(new_a + new_nz); 18517ab2063SBarry Smith new_i = new_j + new_nz; 18617ab2063SBarry Smith 18717ab2063SBarry Smith /* copy over old data into new slots */ 18817ab2063SBarry Smith for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];} 189416022c9SBarry Smith for (ii=row+1; ii<a->m+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;} 190549d3d68SSatish Balay ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow+shift)*sizeof(int));CHKERRQ(ierr); 191416022c9SBarry Smith len = (new_nz - CHUNKSIZE - ai[row] - nrow - shift); 192549d3d68SSatish Balay ierr = PetscMemcpy(new_j+ai[row]+shift+nrow+CHUNKSIZE,aj+ai[row]+shift+nrow,len*sizeof(int));CHKERRQ(ierr); 193549d3d68SSatish Balay ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow+shift)*sizeof(Scalar));CHKERRQ(ierr); 194549d3d68SSatish Balay ierr = PetscMemcpy(new_a+ai[row]+shift+nrow+CHUNKSIZE,aa+ai[row]+shift+nrow,len*sizeof(Scalar));CHKERRQ(ierr); 19517ab2063SBarry Smith /* free up old matrix storage */ 196606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 197606d414cSSatish Balay if (!a->singlemalloc) { 198606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 199606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 200606d414cSSatish Balay } 201416022c9SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 202f1e2ffcdSBarry Smith a->singlemalloc = PETSC_TRUE; 20317ab2063SBarry Smith 20417ab2063SBarry Smith rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 205416022c9SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 206416022c9SBarry Smith PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + sizeof(Scalar))); 207416022c9SBarry Smith a->maxnz += CHUNKSIZE; 208b810aeb4SBarry Smith a->reallocs++; 20917ab2063SBarry Smith } 210416022c9SBarry Smith N = nrow++ - 1; a->nz++; 211416022c9SBarry Smith /* shift up all the later entries in this row */ 212416022c9SBarry Smith for (ii=N; ii>=i; ii--) { 21317ab2063SBarry Smith rp[ii+1] = rp[ii]; 21417ab2063SBarry Smith ap[ii+1] = ap[ii]; 21517ab2063SBarry Smith } 21617ab2063SBarry Smith rp[i] = col; 21717ab2063SBarry Smith ap[i] = value; 21817ab2063SBarry Smith noinsert:; 219416022c9SBarry Smith low = i + 1; 22017ab2063SBarry Smith } 22117ab2063SBarry Smith ailen[row] = nrow; 22217ab2063SBarry Smith } 2233a40ed3dSBarry Smith PetscFunctionReturn(0); 22417ab2063SBarry Smith } 22517ab2063SBarry Smith 2265615d1e5SSatish Balay #undef __FUNC__ 227b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetValues_SeqAIJ" 2288f6be9afSLois Curfman McInnes int MatGetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v) 2297eb43aa7SLois Curfman McInnes { 2307eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 231b49de8d1SLois Curfman McInnes int *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 2327eb43aa7SLois Curfman McInnes int *ai = a->i,*ailen = a->ilen,shift = a->indexshift; 2337eb43aa7SLois Curfman McInnes Scalar *ap,*aa = a->a,zero = 0.0; 2347eb43aa7SLois Curfman McInnes 2353a40ed3dSBarry Smith PetscFunctionBegin; 2367eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 2377eb43aa7SLois Curfman McInnes row = im[k]; 238a8c6a408SBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 239a8c6a408SBarry Smith if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 2407eb43aa7SLois Curfman McInnes rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 2417eb43aa7SLois Curfman McInnes nrow = ailen[row]; 2427eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 243a8c6a408SBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 244a8c6a408SBarry Smith if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 2457eb43aa7SLois Curfman McInnes col = in[l] - shift; 2467eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 2477eb43aa7SLois Curfman McInnes while (high-low > 5) { 2487eb43aa7SLois Curfman McInnes t = (low+high)/2; 2497eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 2507eb43aa7SLois Curfman McInnes else low = t; 2517eb43aa7SLois Curfman McInnes } 2527eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 2537eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 2547eb43aa7SLois Curfman McInnes if (rp[i] == col) { 255b49de8d1SLois Curfman McInnes *v++ = ap[i]; 2567eb43aa7SLois Curfman McInnes goto finished; 2577eb43aa7SLois Curfman McInnes } 2587eb43aa7SLois Curfman McInnes } 259b49de8d1SLois Curfman McInnes *v++ = zero; 2607eb43aa7SLois Curfman McInnes finished:; 2617eb43aa7SLois Curfman McInnes } 2627eb43aa7SLois Curfman McInnes } 2633a40ed3dSBarry Smith PetscFunctionReturn(0); 2647eb43aa7SLois Curfman McInnes } 2657eb43aa7SLois Curfman McInnes 26617ab2063SBarry Smith 2675615d1e5SSatish Balay #undef __FUNC__ 268b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatView_SeqAIJ_Binary" 269480ef9eaSBarry Smith int MatView_SeqAIJ_Binary(Mat A,Viewer viewer) 27017ab2063SBarry Smith { 271416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 272416022c9SBarry Smith int i,fd,*col_lens,ierr; 27317ab2063SBarry Smith 2743a40ed3dSBarry Smith PetscFunctionBegin; 27590ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 2760452661fSBarry Smith col_lens = (int*)PetscMalloc((4+a->m)*sizeof(int));CHKPTRQ(col_lens); 277416022c9SBarry Smith col_lens[0] = MAT_COOKIE; 278416022c9SBarry Smith col_lens[1] = a->m; 279416022c9SBarry Smith col_lens[2] = a->n; 280416022c9SBarry Smith col_lens[3] = a->nz; 281416022c9SBarry Smith 282416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 283416022c9SBarry Smith for (i=0; i<a->m; i++) { 284416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 28517ab2063SBarry Smith } 2860752156aSBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1);CHKERRQ(ierr); 287606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 288416022c9SBarry Smith 289416022c9SBarry Smith /* store column indices (zero start index) */ 290416022c9SBarry Smith if (a->indexshift) { 291416022c9SBarry Smith for (i=0; i<a->nz; i++) a->j[i]--; 29217ab2063SBarry Smith } 2930752156aSBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,0);CHKERRQ(ierr); 294416022c9SBarry Smith if (a->indexshift) { 295416022c9SBarry Smith for (i=0; i<a->nz; i++) a->j[i]++; 29617ab2063SBarry Smith } 297416022c9SBarry Smith 298416022c9SBarry Smith /* store nonzero values */ 2990752156aSBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,0);CHKERRQ(ierr); 3003a40ed3dSBarry Smith PetscFunctionReturn(0); 30117ab2063SBarry Smith } 302416022c9SBarry Smith 3035615d1e5SSatish Balay #undef __FUNC__ 304b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatView_SeqAIJ_ASCII" 305480ef9eaSBarry Smith int MatView_SeqAIJ_ASCII(Mat A,Viewer viewer) 306416022c9SBarry Smith { 307416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3086831982aSBarry Smith int ierr,i,j,m = a->m,shift = a->indexshift,format; 30917ab2063SBarry Smith char *outputname; 31017ab2063SBarry Smith 3113a40ed3dSBarry Smith PetscFunctionBegin; 312fb4b0f7fSBarry Smith ierr = ViewerGetOutputname(viewer,&outputname);CHKERRQ(ierr); 313888f2ed8SSatish Balay ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr); 3146831982aSBarry Smith if (format == VIEWER_FORMAT_ASCII_INFO_LONG || format == VIEWER_FORMAT_ASCII_INFO) { 3156831982aSBarry Smith if (a->inode.size) { 3166831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"using I-node routines: found %d nodes, limit used is %d\n",a->inode.node_count,a->inode.limit);CHKERRQ(ierr); 3176831982aSBarry Smith } else { 3186831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"not using I-node routines\n");CHKERRQ(ierr); 3196831982aSBarry Smith } 3203a40ed3dSBarry Smith } else if (format == VIEWER_FORMAT_ASCII_MATLAB) { 321d00d2cf4SBarry Smith int nofinalvalue = 0; 322d00d2cf4SBarry Smith if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != a->n-!shift)) { 323d00d2cf4SBarry Smith nofinalvalue = 1; 324d00d2cf4SBarry Smith } 3256831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 3266831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"%% Size = %d %d \n",m,a->n);CHKERRQ(ierr); 3276831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"%% Nonzeros = %d \n",a->nz);CHKERRQ(ierr); 3286831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"zzz = zeros(%d,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 3296831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 33017ab2063SBarry Smith 33117ab2063SBarry Smith for (i=0; i<m; i++) { 332416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 333aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 33436db0b34SBarry Smith ierr = ViewerASCIIPrintf(viewer,"%d %d %18.16e + %18.16ei \n",i+1,a->j[j]+!shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 33517ab2063SBarry Smith #else 3366831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"%d %d %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr); 33717ab2063SBarry Smith #endif 33817ab2063SBarry Smith } 33917ab2063SBarry Smith } 340d00d2cf4SBarry Smith if (nofinalvalue) { 3416831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"%d %d %18.16e\n",m,a->n,0.0);CHKERRQ(ierr); 342d00d2cf4SBarry Smith } 3436831982aSBarry Smith if (outputname) {ierr = ViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",outputname);CHKERRQ(ierr);} 3446831982aSBarry Smith else {ierr = ViewerASCIIPrintf(viewer,"];\n M = spconvert(zzz);\n");CHKERRQ(ierr);} 3456831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 3463a40ed3dSBarry Smith } else if (format == VIEWER_FORMAT_ASCII_COMMON) { 3476831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 34844cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 3496831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr); 35044cd7ae7SLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 351aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 35236db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 35336db0b34SBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 35436db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 35536db0b34SBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 35636db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 35736db0b34SBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 3586831982aSBarry Smith } 35944cd7ae7SLois Curfman McInnes #else 3606831982aSBarry Smith if (a->a[j] != 0.0) {ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);} 36144cd7ae7SLois Curfman McInnes #endif 36244cd7ae7SLois Curfman McInnes } 3636831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 36444cd7ae7SLois Curfman McInnes } 3656831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 36602594712SBarry Smith } else if (format == VIEWER_FORMAT_ASCII_SYMMODU) { 367496be53dSLois Curfman McInnes int nzd=0,fshift=1,*sptr; 3686831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 3692e44a96cSLois Curfman McInnes sptr = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(sptr); 370496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 371496be53dSLois Curfman McInnes sptr[i] = nzd+1; 372496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 373496be53dSLois Curfman McInnes if (a->j[j] >= i) { 374aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 37536db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 376496be53dSLois Curfman McInnes #else 377496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 378496be53dSLois Curfman McInnes #endif 379496be53dSLois Curfman McInnes } 380496be53dSLois Curfman McInnes } 381496be53dSLois Curfman McInnes } 3822e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 3836831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %d\n\n",m,nzd);CHKERRQ(ierr); 3842e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 3856831982aSBarry Smith if (i+4<m) {ierr = ViewerASCIIPrintf(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);} 3866831982aSBarry Smith else if (i+3<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4]);CHKERRQ(ierr);} 3876831982aSBarry Smith else if (i+2<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);} 3886831982aSBarry Smith else if (i+1<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);} 3896831982aSBarry Smith else if (i<m) {ierr = ViewerASCIIPrintf(viewer," %d %d\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);} 3906831982aSBarry Smith else {ierr = ViewerASCIIPrintf(viewer," %d\n",sptr[i]);CHKERRQ(ierr);} 391496be53dSLois Curfman McInnes } 3926831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 393606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 394496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 395496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 3966831982aSBarry Smith if (a->j[j] >= i) {ierr = ViewerASCIIPrintf(viewer," %d ",a->j[j]+fshift);CHKERRQ(ierr);} 397496be53dSLois Curfman McInnes } 3986831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 399496be53dSLois Curfman McInnes } 4006831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 401496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 402496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 403496be53dSLois Curfman McInnes if (a->j[j] >= i) { 404aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 40536db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 40636db0b34SBarry Smith ierr = ViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 4076831982aSBarry Smith } 408496be53dSLois Curfman McInnes #else 4096831982aSBarry Smith if (a->a[j] != 0.0) {ierr = ViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);} 410496be53dSLois Curfman McInnes #endif 411496be53dSLois Curfman McInnes } 412496be53dSLois Curfman McInnes } 4136831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 414496be53dSLois Curfman McInnes } 4156831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 41602594712SBarry Smith } else if (format == VIEWER_FORMAT_ASCII_DENSE) { 41702594712SBarry Smith int cnt = 0,jcnt; 41802594712SBarry Smith Scalar value; 41902594712SBarry Smith 4206831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 42102594712SBarry Smith for (i=0; i<m; i++) { 42202594712SBarry Smith jcnt = 0; 42302594712SBarry Smith for (j=0; j<a->n; j++) { 424e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 42502594712SBarry Smith value = a->a[cnt++]; 426e24b481bSBarry Smith jcnt++; 42702594712SBarry Smith } else { 42802594712SBarry Smith value = 0.0; 42902594712SBarry Smith } 430aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 43136db0b34SBarry Smith ierr = ViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr); 43202594712SBarry Smith #else 4336831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr); 43402594712SBarry Smith #endif 43502594712SBarry Smith } 4366831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 43702594712SBarry Smith } 4386831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 4393a40ed3dSBarry Smith } else { 4406831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 44117ab2063SBarry Smith for (i=0; i<m; i++) { 4426831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr); 443416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 444aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 44536db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 44636db0b34SBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 44736db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 44836db0b34SBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 4493a40ed3dSBarry Smith } else { 45036db0b34SBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 45117ab2063SBarry Smith } 45217ab2063SBarry Smith #else 4536831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 45417ab2063SBarry Smith #endif 45517ab2063SBarry Smith } 4566831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 45717ab2063SBarry Smith } 4586831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 45917ab2063SBarry Smith } 4606831982aSBarry Smith ierr = ViewerFlush(viewer);CHKERRQ(ierr); 4613a40ed3dSBarry Smith PetscFunctionReturn(0); 462416022c9SBarry Smith } 463416022c9SBarry Smith 4645615d1e5SSatish Balay #undef __FUNC__ 465b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatView_SeqAIJ_Draw_Zoom" 466480ef9eaSBarry Smith int MatView_SeqAIJ_Draw_Zoom(Draw draw,void *Aa) 467416022c9SBarry Smith { 468480ef9eaSBarry Smith Mat A = (Mat) Aa; 469416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 47077ed5343SBarry Smith int ierr,i,j,m = a->m,shift = a->indexshift,color,rank; 4710513a670SBarry Smith int format; 47236db0b34SBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0; 473480ef9eaSBarry Smith Viewer viewer; 47477ed5343SBarry Smith MPI_Comm comm; 475cddf8d76SBarry Smith 4763a40ed3dSBarry Smith PetscFunctionBegin; 47777ed5343SBarry Smith /* 47877ed5343SBarry Smith This is nasty. If this is called from an originally parallel matrix 47977ed5343SBarry Smith then all processes call this,but only the first has the matrix so the 48077ed5343SBarry Smith rest should return immediately. 48177ed5343SBarry Smith */ 48277ed5343SBarry Smith ierr = PetscObjectGetComm((PetscObject)draw,&comm);CHKERRQ(ierr); 483d132466eSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 48477ed5343SBarry Smith if (rank) PetscFunctionReturn(0); 48577ed5343SBarry Smith 486480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 4870513a670SBarry Smith ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr); 48819bcc07fSBarry Smith 489480ef9eaSBarry Smith ierr = DrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 490416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 4910513a670SBarry Smith 4920513a670SBarry Smith if (format != VIEWER_FORMAT_DRAW_CONTOUR) { 4930513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 494cddf8d76SBarry Smith color = DRAW_BLUE; 495416022c9SBarry Smith for (i=0; i<m; i++) { 496cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 497416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 498cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 499aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 50036db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 501cddf8d76SBarry Smith #else 502cddf8d76SBarry Smith if (a->a[j] >= 0.) continue; 503cddf8d76SBarry Smith #endif 504480ef9eaSBarry Smith ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 505cddf8d76SBarry Smith } 506cddf8d76SBarry Smith } 507cddf8d76SBarry Smith color = DRAW_CYAN; 508cddf8d76SBarry Smith for (i=0; i<m; i++) { 509cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 510cddf8d76SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 511cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 512cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 513480ef9eaSBarry Smith ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 514cddf8d76SBarry Smith } 515cddf8d76SBarry Smith } 516cddf8d76SBarry Smith color = DRAW_RED; 517cddf8d76SBarry Smith for (i=0; i<m; i++) { 518cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 519cddf8d76SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 520cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 521aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 52236db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 523cddf8d76SBarry Smith #else 524cddf8d76SBarry Smith if (a->a[j] <= 0.) continue; 525cddf8d76SBarry Smith #endif 526480ef9eaSBarry Smith ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 527416022c9SBarry Smith } 528416022c9SBarry Smith } 5290513a670SBarry Smith } else { 5300513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 5310513a670SBarry Smith /* first determine max of all nonzero values */ 5320513a670SBarry Smith int nz = a->nz,count; 5330513a670SBarry Smith Draw popup; 53436db0b34SBarry Smith PetscReal scale; 5350513a670SBarry Smith 5360513a670SBarry Smith for (i=0; i<nz; i++) { 5370513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 5380513a670SBarry Smith } 539480ef9eaSBarry Smith scale = (245.0 - DRAW_BASIC_COLORS)/maxv; 540522c5e43SBarry Smith ierr = DrawGetPopup(draw,&popup);CHKERRQ(ierr); 541f1e2ffcdSBarry Smith if (popup) {ierr = DrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);} 5420513a670SBarry Smith count = 0; 5430513a670SBarry Smith for (i=0; i<m; i++) { 5440513a670SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 5450513a670SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 5460513a670SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 5476d6b6c30SSatish Balay color = DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(a->a[count])); 548480ef9eaSBarry Smith ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 5490513a670SBarry Smith count++; 5500513a670SBarry Smith } 5510513a670SBarry Smith } 5520513a670SBarry Smith } 553480ef9eaSBarry Smith PetscFunctionReturn(0); 554480ef9eaSBarry Smith } 555cddf8d76SBarry Smith 556480ef9eaSBarry Smith #undef __FUNC__ 557b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatView_SeqAIJ_Draw" 558480ef9eaSBarry Smith int MatView_SeqAIJ_Draw(Mat A,Viewer viewer) 559480ef9eaSBarry Smith { 560480ef9eaSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 561480ef9eaSBarry Smith int ierr; 562480ef9eaSBarry Smith Draw draw; 56336db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 564480ef9eaSBarry Smith PetscTruth isnull; 565480ef9eaSBarry Smith 566480ef9eaSBarry Smith PetscFunctionBegin; 56777ed5343SBarry Smith ierr = ViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 568480ef9eaSBarry Smith ierr = DrawIsNull(draw,&isnull);CHKERRQ(ierr); 569480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 570480ef9eaSBarry Smith 571480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 572480ef9eaSBarry Smith xr = a->n; yr = a->m; h = yr/10.0; w = xr/10.0; 573480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 574cddf8d76SBarry Smith ierr = DrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 575480ef9eaSBarry Smith ierr = DrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 576480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 5773a40ed3dSBarry Smith PetscFunctionReturn(0); 578416022c9SBarry Smith } 579416022c9SBarry Smith 5805615d1e5SSatish Balay #undef __FUNC__ 581b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatView_SeqAIJ" 582e1311b90SBarry Smith int MatView_SeqAIJ(Mat A,Viewer viewer) 583416022c9SBarry Smith { 584416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 585bcd2baecSBarry Smith int ierr; 5866831982aSBarry Smith PetscTruth issocket,isascii,isbinary,isdraw; 587416022c9SBarry Smith 5883a40ed3dSBarry Smith PetscFunctionBegin; 5896831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,SOCKET_VIEWER,&issocket);CHKERRQ(ierr); 5906831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,ASCII_VIEWER,&isascii);CHKERRQ(ierr); 5916831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,BINARY_VIEWER,&isbinary);CHKERRQ(ierr); 5926831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,DRAW_VIEWER,&isdraw);CHKERRQ(ierr); 5930f5bd95cSBarry Smith if (issocket) { 5947b2a1423SBarry Smith ierr = ViewerSocketPutSparse_Private(viewer,a->m,a->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr); 5950f5bd95cSBarry Smith } else if (isascii) { 5963a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 5970f5bd95cSBarry Smith } else if (isbinary) { 5983a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 5990f5bd95cSBarry Smith } else if (isdraw) { 6003a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 6015cd90555SBarry Smith } else { 6020f5bd95cSBarry Smith SETERRQ1(1,1,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name); 60317ab2063SBarry Smith } 6043a40ed3dSBarry Smith PetscFunctionReturn(0); 60517ab2063SBarry Smith } 60619bcc07fSBarry Smith 607c456f294SBarry Smith extern int Mat_AIJ_CheckInode(Mat); 6085615d1e5SSatish Balay #undef __FUNC__ 609b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatAssemblyEnd_SeqAIJ" 6108f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 61117ab2063SBarry Smith { 612416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 61341c01911SSatish Balay int fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax,ierr; 61443ee02c3SBarry Smith int m = a->m,*ip,N,*ailen = a->ilen,shift = a->indexshift,rmax = 0; 615416022c9SBarry Smith Scalar *aa = a->a,*ap; 61617ab2063SBarry Smith 6173a40ed3dSBarry Smith PetscFunctionBegin; 6183a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 61917ab2063SBarry Smith 62043ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 62117ab2063SBarry Smith for (i=1; i<m; i++) { 622416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 62317ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 62494a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 62517ab2063SBarry Smith if (fshift) { 6260f5bd95cSBarry Smith ip = aj + ai[i] + shift; 6270f5bd95cSBarry Smith ap = aa + ai[i] + shift; 62817ab2063SBarry Smith N = ailen[i]; 62917ab2063SBarry Smith for (j=0; j<N; j++) { 63017ab2063SBarry Smith ip[j-fshift] = ip[j]; 63117ab2063SBarry Smith ap[j-fshift] = ap[j]; 63217ab2063SBarry Smith } 63317ab2063SBarry Smith } 63417ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 63517ab2063SBarry Smith } 63617ab2063SBarry Smith if (m) { 63717ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 63817ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 63917ab2063SBarry Smith } 64017ab2063SBarry Smith /* reset ilen and imax for each row */ 64117ab2063SBarry Smith for (i=0; i<m; i++) { 64217ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 64317ab2063SBarry Smith } 644416022c9SBarry Smith a->nz = ai[m] + shift; 64517ab2063SBarry Smith 64617ab2063SBarry Smith /* diagonals may have moved, so kill the diagonal pointers */ 647416022c9SBarry Smith if (fshift && a->diag) { 648606d414cSSatish Balay ierr = PetscFree(a->diag);CHKERRQ(ierr); 649416022c9SBarry Smith PLogObjectMemory(A,-(m+1)*sizeof(int)); 650416022c9SBarry Smith a->diag = 0; 65117ab2063SBarry Smith } 652c38d4ed2SBarry Smith PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded,%d used\n",m,a->n,fshift,a->nz); 653c38d4ed2SBarry Smith PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues() is %d\n",a->reallocs); 65494a9d846SBarry Smith PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Most nonzeros in any row is %d\n",rmax); 655dd5f02e7SSatish Balay a->reallocs = 0; 6564e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift; 65736db0b34SBarry Smith a->rmax = rmax; 6584e220ebcSLois Curfman McInnes 65976dd722bSSatish Balay /* check out for identical nodes. If found, use inode functions */ 66041c01911SSatish Balay ierr = Mat_AIJ_CheckInode(A);CHKERRQ(ierr); 6613a40ed3dSBarry Smith PetscFunctionReturn(0); 66217ab2063SBarry Smith } 66317ab2063SBarry Smith 6645615d1e5SSatish Balay #undef __FUNC__ 665b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatZeroEntries_SeqAIJ" 6668f6be9afSLois Curfman McInnes int MatZeroEntries_SeqAIJ(Mat A) 66717ab2063SBarry Smith { 668416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 669549d3d68SSatish Balay int ierr; 6703a40ed3dSBarry Smith 6713a40ed3dSBarry Smith PetscFunctionBegin; 672549d3d68SSatish Balay ierr = PetscMemzero(a->a,(a->i[a->m]+a->indexshift)*sizeof(Scalar));CHKERRQ(ierr); 6733a40ed3dSBarry Smith PetscFunctionReturn(0); 67417ab2063SBarry Smith } 675416022c9SBarry Smith 6765615d1e5SSatish Balay #undef __FUNC__ 677b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatDestroy_SeqAIJ" 678e1311b90SBarry Smith int MatDestroy_SeqAIJ(Mat A) 67917ab2063SBarry Smith { 680416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 68182bf6240SBarry Smith int ierr; 682d5d45c9bSBarry Smith 6833a40ed3dSBarry Smith PetscFunctionBegin; 68494d884c6SBarry Smith 68594d884c6SBarry Smith if (A->mapping) { 68694d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(A->mapping);CHKERRQ(ierr); 68794d884c6SBarry Smith } 68894d884c6SBarry Smith if (A->bmapping) { 68994d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(A->bmapping);CHKERRQ(ierr); 69094d884c6SBarry Smith } 69161b13de0SBarry Smith if (A->rmap) { 69261b13de0SBarry Smith ierr = MapDestroy(A->rmap);CHKERRQ(ierr); 69361b13de0SBarry Smith } 69461b13de0SBarry Smith if (A->cmap) { 69561b13de0SBarry Smith ierr = MapDestroy(A->cmap);CHKERRQ(ierr); 69661b13de0SBarry Smith } 697606d414cSSatish Balay if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);} 698aa482453SBarry Smith #if defined(PETSC_USE_LOG) 699e1311b90SBarry Smith PLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz); 70017ab2063SBarry Smith #endif 70136db0b34SBarry Smith if (a->freedata) { 702606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 703606d414cSSatish Balay if (!a->singlemalloc) { 704606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 705606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 706606d414cSSatish Balay } 70736db0b34SBarry Smith } 708c38d4ed2SBarry Smith if (a->row) { 709c38d4ed2SBarry Smith ierr = ISDestroy(a->row);CHKERRQ(ierr); 710c38d4ed2SBarry Smith } 711c38d4ed2SBarry Smith if (a->col) { 712c38d4ed2SBarry Smith ierr = ISDestroy(a->col);CHKERRQ(ierr); 713c38d4ed2SBarry Smith } 714606d414cSSatish Balay if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);} 715606d414cSSatish Balay if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);} 716606d414cSSatish Balay if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);} 717606d414cSSatish Balay if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);} 718606d414cSSatish Balay if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);} 71982bf6240SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 720606d414cSSatish Balay if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);} 721606d414cSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 722eed86810SBarry Smith 723f2655603SLois Curfman McInnes PLogObjectDestroy(A); 724f2655603SLois Curfman McInnes PetscHeaderDestroy(A); 7253a40ed3dSBarry Smith PetscFunctionReturn(0); 72617ab2063SBarry Smith } 72717ab2063SBarry Smith 7285615d1e5SSatish Balay #undef __FUNC__ 729b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatCompress_SeqAIJ" 7308f6be9afSLois Curfman McInnes int MatCompress_SeqAIJ(Mat A) 73117ab2063SBarry Smith { 7323a40ed3dSBarry Smith PetscFunctionBegin; 7333a40ed3dSBarry Smith PetscFunctionReturn(0); 73417ab2063SBarry Smith } 73517ab2063SBarry Smith 7365615d1e5SSatish Balay #undef __FUNC__ 737b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatSetOption_SeqAIJ" 7388f6be9afSLois Curfman McInnes int MatSetOption_SeqAIJ(Mat A,MatOption op) 73917ab2063SBarry Smith { 740416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 7413a40ed3dSBarry Smith 7423a40ed3dSBarry Smith PetscFunctionBegin; 743f1e2ffcdSBarry Smith if (op == MAT_ROW_ORIENTED) a->roworiented = PETSC_TRUE; 744f1e2ffcdSBarry Smith else if (op == MAT_KEEP_ZEROED_ROWS) a->keepzeroedrows = PETSC_TRUE; 745f1e2ffcdSBarry Smith else if (op == MAT_COLUMN_ORIENTED) a->roworiented = PETSC_FALSE; 746f1e2ffcdSBarry Smith else if (op == MAT_COLUMNS_SORTED) a->sorted = PETSC_TRUE; 747f1e2ffcdSBarry Smith else if (op == MAT_COLUMNS_UNSORTED) a->sorted = PETSC_FALSE; 7486d4a8577SBarry Smith else if (op == MAT_NO_NEW_NONZERO_LOCATIONS) a->nonew = 1; 7494787f768SSatish Balay else if (op == MAT_NEW_NONZERO_LOCATION_ERR) a->nonew = -1; 7504787f768SSatish Balay else if (op == MAT_NEW_NONZERO_ALLOCATION_ERR) a->nonew = -2; 7516d4a8577SBarry Smith else if (op == MAT_YES_NEW_NONZERO_LOCATIONS) a->nonew = 0; 75236db0b34SBarry Smith else if (op == MAT_IGNORE_ZERO_ENTRIES) a->ignorezeroentries = PETSC_TRUE; 753b65db4caSBarry Smith else if (op == MAT_USE_INODES) a->inode.use = PETSC_TRUE; 754b65db4caSBarry Smith else if (op == MAT_DO_NOT_USE_INODES) a->inode.use = PETSC_FALSE; 7556d4a8577SBarry Smith else if (op == MAT_ROWS_SORTED || 756219d9a1aSLois Curfman McInnes op == MAT_ROWS_UNSORTED || 7576d4a8577SBarry Smith op == MAT_SYMMETRIC || 7586d4a8577SBarry Smith op == MAT_STRUCTURALLY_SYMMETRIC || 75990f02eecSBarry Smith op == MAT_YES_NEW_DIAGONALS || 760b51ba29fSSatish Balay op == MAT_IGNORE_OFF_PROC_ENTRIES|| 761b51ba29fSSatish Balay op == MAT_USE_HASH_TABLE) 762981c4779SBarry Smith PLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n"); 7633a40ed3dSBarry Smith else if (op == MAT_NO_NEW_DIAGONALS) { 7643a40ed3dSBarry Smith SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS"); 7653a40ed3dSBarry Smith } else if (op == MAT_INODE_LIMIT_1) a->inode.limit = 1; 7666d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_2) a->inode.limit = 2; 7676d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_3) a->inode.limit = 3; 7686d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_4) a->inode.limit = 4; 7696d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_5) a->inode.limit = 5; 7703a40ed3dSBarry Smith else SETERRQ(PETSC_ERR_SUP,0,"unknown option"); 7713a40ed3dSBarry Smith PetscFunctionReturn(0); 77217ab2063SBarry Smith } 77317ab2063SBarry Smith 7745615d1e5SSatish Balay #undef __FUNC__ 775b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetDiagonal_SeqAIJ" 7768f6be9afSLois Curfman McInnes int MatGetDiagonal_SeqAIJ(Mat A,Vec v) 77717ab2063SBarry Smith { 778416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 7793a40ed3dSBarry Smith int i,j,n,shift = a->indexshift,ierr; 78017ab2063SBarry Smith Scalar *x,zero = 0.0; 78117ab2063SBarry Smith 7823a40ed3dSBarry Smith PetscFunctionBegin; 7833a40ed3dSBarry Smith ierr = VecSet(&zero,v);CHKERRQ(ierr); 78436db0b34SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 78536db0b34SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 786a8c6a408SBarry Smith if (n != a->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Nonconforming matrix and vector"); 787416022c9SBarry Smith for (i=0; i<a->m; i++) { 788416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 789416022c9SBarry Smith if (a->j[j]+shift == i) { 790416022c9SBarry Smith x[i] = a->a[j]; 79117ab2063SBarry Smith break; 79217ab2063SBarry Smith } 79317ab2063SBarry Smith } 79417ab2063SBarry Smith } 79536db0b34SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 7963a40ed3dSBarry Smith PetscFunctionReturn(0); 79717ab2063SBarry Smith } 79817ab2063SBarry Smith 79917ab2063SBarry Smith /* -------------------------------------------------------*/ 80017ab2063SBarry Smith /* Should check that shapes of vectors and matrices match */ 80117ab2063SBarry Smith /* -------------------------------------------------------*/ 8025615d1e5SSatish Balay #undef __FUNC__ 803b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatMultTranspose_SeqAIJ" 8047c922b88SBarry Smith int MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 80517ab2063SBarry Smith { 806416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 807f1af5d2fSBarry Smith Scalar *x,*y,*v,alpha,zero = 0.0; 808e1311b90SBarry Smith int ierr,m = a->m,n,i,*idx,shift = a->indexshift; 80917ab2063SBarry Smith 8103a40ed3dSBarry Smith PetscFunctionBegin; 811f1af5d2fSBarry Smith ierr = VecSet(&zero,yy);CHKERRQ(ierr); 812e1311b90SBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 813e1311b90SBarry Smith ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 81417ab2063SBarry Smith y = y + shift; /* shift for Fortran start by 1 indexing */ 81517ab2063SBarry Smith for (i=0; i<m; i++) { 816416022c9SBarry Smith idx = a->j + a->i[i] + shift; 817416022c9SBarry Smith v = a->a + a->i[i] + shift; 818416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 81917ab2063SBarry Smith alpha = x[i]; 82017ab2063SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 82117ab2063SBarry Smith } 822416022c9SBarry Smith PLogFlops(2*a->nz - a->n); 823e1311b90SBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 824e1311b90SBarry Smith ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 8253a40ed3dSBarry Smith PetscFunctionReturn(0); 82617ab2063SBarry Smith } 827d5d45c9bSBarry Smith 8285615d1e5SSatish Balay #undef __FUNC__ 829b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatMultTransposeAdd_SeqAIJ" 8307c922b88SBarry Smith int MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 83117ab2063SBarry Smith { 832416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 83317ab2063SBarry Smith Scalar *x,*y,*v,alpha; 834e1311b90SBarry Smith int ierr,m = a->m,n,i,*idx,shift = a->indexshift; 83517ab2063SBarry Smith 8363a40ed3dSBarry Smith PetscFunctionBegin; 8372e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 838e1311b90SBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 839e1311b90SBarry Smith ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 84017ab2063SBarry Smith y = y + shift; /* shift for Fortran start by 1 indexing */ 84117ab2063SBarry Smith for (i=0; i<m; i++) { 842416022c9SBarry Smith idx = a->j + a->i[i] + shift; 843416022c9SBarry Smith v = a->a + a->i[i] + shift; 844416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 84517ab2063SBarry Smith alpha = x[i]; 84617ab2063SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 84717ab2063SBarry Smith } 84890f02eecSBarry Smith PLogFlops(2*a->nz); 849e1311b90SBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 850e1311b90SBarry Smith ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 8513a40ed3dSBarry Smith PetscFunctionReturn(0); 85217ab2063SBarry Smith } 85317ab2063SBarry Smith 8545615d1e5SSatish Balay #undef __FUNC__ 855b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatMult_SeqAIJ" 85644cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 85717ab2063SBarry Smith { 858416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 85917ab2063SBarry Smith Scalar *x,*y,*v,sum; 860e1311b90SBarry Smith int ierr,m = a->m,*idx,shift = a->indexshift,*ii; 861aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 862e36a17ebSSatish Balay int n,i,jrow,j; 863e36a17ebSSatish Balay #endif 86417ab2063SBarry Smith 865aa482453SBarry Smith #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 866fee21e36SBarry Smith #pragma disjoint(*x,*y,*v) 867fee21e36SBarry Smith #endif 868fee21e36SBarry Smith 8693a40ed3dSBarry Smith PetscFunctionBegin; 870e1311b90SBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 871e1311b90SBarry Smith ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 87217ab2063SBarry Smith x = x + shift; /* shift for Fortran start by 1 indexing */ 873416022c9SBarry Smith idx = a->j; 874d64ed03dSBarry Smith v = a->a; 875416022c9SBarry Smith ii = a->i; 876aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 87729b5ca8aSSatish Balay fortranmultaij_(&m,x,ii,idx+shift,v+shift,y); 8788d195f9aSBarry Smith #else 879d64ed03dSBarry Smith v += shift; /* shift for Fortran start by 1 indexing */ 880d64ed03dSBarry Smith idx += shift; 88117ab2063SBarry Smith for (i=0; i<m; i++) { 8829ea0dfa2SSatish Balay jrow = ii[i]; 8839ea0dfa2SSatish Balay n = ii[i+1] - jrow; 88417ab2063SBarry Smith sum = 0.0; 8859ea0dfa2SSatish Balay for (j=0; j<n; j++) { 8869ea0dfa2SSatish Balay sum += v[jrow]*x[idx[jrow]]; jrow++; 8879ea0dfa2SSatish Balay } 88817ab2063SBarry Smith y[i] = sum; 88917ab2063SBarry Smith } 8908d195f9aSBarry Smith #endif 891416022c9SBarry Smith PLogFlops(2*a->nz - m); 892e1311b90SBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 893e1311b90SBarry Smith ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 8943a40ed3dSBarry Smith PetscFunctionReturn(0); 89517ab2063SBarry Smith } 89617ab2063SBarry Smith 8975615d1e5SSatish Balay #undef __FUNC__ 898b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatMultAdd_SeqAIJ" 89944cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 90017ab2063SBarry Smith { 901416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 90217ab2063SBarry Smith Scalar *x,*y,*z,*v,sum; 903e1311b90SBarry Smith int ierr,m = a->m,*idx,shift = a->indexshift,*ii; 904aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 905e36a17ebSSatish Balay int n,i,jrow,j; 906e36a17ebSSatish Balay #endif 9079ea0dfa2SSatish Balay 9083a40ed3dSBarry Smith PetscFunctionBegin; 909e1311b90SBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 910e1311b90SBarry Smith ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 9112e8a6d31SBarry Smith if (zz != yy) { 912e1311b90SBarry Smith ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 9132e8a6d31SBarry Smith } else { 9142e8a6d31SBarry Smith z = y; 9152e8a6d31SBarry Smith } 91617ab2063SBarry Smith x = x + shift; /* shift for Fortran start by 1 indexing */ 917cddf8d76SBarry Smith idx = a->j; 918d64ed03dSBarry Smith v = a->a; 919cddf8d76SBarry Smith ii = a->i; 920aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 92129b5ca8aSSatish Balay fortranmultaddaij_(&m,x,ii,idx+shift,v+shift,y,z); 92202ab625aSSatish Balay #else 923d64ed03dSBarry Smith v += shift; /* shift for Fortran start by 1 indexing */ 924d64ed03dSBarry Smith idx += shift; 92517ab2063SBarry Smith for (i=0; i<m; i++) { 9269ea0dfa2SSatish Balay jrow = ii[i]; 9279ea0dfa2SSatish Balay n = ii[i+1] - jrow; 92817ab2063SBarry Smith sum = y[i]; 9299ea0dfa2SSatish Balay for (j=0; j<n; j++) { 9309ea0dfa2SSatish Balay sum += v[jrow]*x[idx[jrow]]; jrow++; 9319ea0dfa2SSatish Balay } 93217ab2063SBarry Smith z[i] = sum; 93317ab2063SBarry Smith } 93402ab625aSSatish Balay #endif 935416022c9SBarry Smith PLogFlops(2*a->nz); 936e1311b90SBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 937e1311b90SBarry Smith ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 9382e8a6d31SBarry Smith if (zz != yy) { 939e1311b90SBarry Smith ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 9402e8a6d31SBarry Smith } 9413a40ed3dSBarry Smith PetscFunctionReturn(0); 94217ab2063SBarry Smith } 94317ab2063SBarry Smith 94417ab2063SBarry Smith /* 94517ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 94617ab2063SBarry Smith */ 9475615d1e5SSatish Balay #undef __FUNC__ 948b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatMarkDiagonal_SeqAIJ" 949f1e2ffcdSBarry Smith int MatMarkDiagonal_SeqAIJ(Mat A) 95017ab2063SBarry Smith { 951416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 952416022c9SBarry Smith int i,j,*diag,m = a->m,shift = a->indexshift; 95317ab2063SBarry Smith 9543a40ed3dSBarry Smith PetscFunctionBegin; 955f1e2ffcdSBarry Smith if (a->diag) PetscFunctionReturn(0); 956f1e2ffcdSBarry Smith 9570452661fSBarry Smith diag = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(diag); 958416022c9SBarry Smith PLogObjectMemory(A,(m+1)*sizeof(int)); 959416022c9SBarry Smith for (i=0; i<a->m; i++) { 96035b0346bSBarry Smith diag[i] = a->i[i+1]; 961416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 962416022c9SBarry Smith if (a->j[j]+shift == i) { 96317ab2063SBarry Smith diag[i] = j - shift; 96417ab2063SBarry Smith break; 96517ab2063SBarry Smith } 96617ab2063SBarry Smith } 96717ab2063SBarry Smith } 968416022c9SBarry Smith a->diag = diag; 9693a40ed3dSBarry Smith PetscFunctionReturn(0); 97017ab2063SBarry Smith } 97117ab2063SBarry Smith 972be5855fcSBarry Smith /* 973be5855fcSBarry Smith Checks for missing diagonals 974be5855fcSBarry Smith */ 975be5855fcSBarry Smith #undef __FUNC__ 976b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatMissingDiagonal_SeqAIJ" 977f1e2ffcdSBarry Smith int MatMissingDiagonal_SeqAIJ(Mat A) 978be5855fcSBarry Smith { 979be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 980f1e2ffcdSBarry Smith int *diag,*jj = a->j,i,shift = a->indexshift,ierr; 981be5855fcSBarry Smith 982be5855fcSBarry Smith PetscFunctionBegin; 983f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 984f1e2ffcdSBarry Smith diag = a->diag; 985be5855fcSBarry Smith for (i=0; i<a->m; i++) { 986be5855fcSBarry Smith if (jj[diag[i]+shift] != i-shift) { 987be5855fcSBarry Smith SETERRQ1(1,1,"Matrix is missing diagonal number %d",i); 988be5855fcSBarry Smith } 989be5855fcSBarry Smith } 990be5855fcSBarry Smith PetscFunctionReturn(0); 991be5855fcSBarry Smith } 992be5855fcSBarry Smith 9935615d1e5SSatish Balay #undef __FUNC__ 994b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatRelax_SeqAIJ" 99536db0b34SBarry Smith int MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,int its,Vec xx) 99617ab2063SBarry Smith { 997416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 998d6ed3216SSatish Balay Scalar *x,*b,*bs, d,*xs,sum,*v = a->a,*t=0,scale,*ts,*xb,*idiag=0; 999d5d45c9bSBarry Smith int ierr,*idx,*diag,n = a->n,m = a->m,i,shift = a->indexshift; 100017ab2063SBarry Smith 10013a40ed3dSBarry Smith PetscFunctionBegin; 1002e1311b90SBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 1003fb2e594dSBarry Smith if (xx != bb) { 1004e1311b90SBarry Smith ierr = VecGetArray(bb,&b);CHKERRQ(ierr); 1005fb2e594dSBarry Smith } else { 1006fb2e594dSBarry Smith b = x; 1007fb2e594dSBarry Smith } 1008fb2e594dSBarry Smith 1009f1e2ffcdSBarry Smith if (!a->diag) {ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);} 1010416022c9SBarry Smith diag = a->diag; 1011416022c9SBarry Smith xs = x + shift; /* shifted by one for index start of a or a->j*/ 101217ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 101317ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 101417ab2063SBarry Smith bs = b + shift; 101517ab2063SBarry Smith for (i=0; i<m; i++) { 1016416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 1017416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1018488ecbafSBarry Smith PLogFlops(2*n-1); 1019416022c9SBarry Smith idx = a->j + diag[i] + (!shift); 1020416022c9SBarry Smith v = a->a + diag[i] + (!shift); 102117ab2063SBarry Smith sum = b[i]*d/omega; 102217ab2063SBarry Smith SPARSEDENSEDOT(sum,bs,v,idx,n); 102317ab2063SBarry Smith x[i] = sum; 102417ab2063SBarry Smith } 1025cb5b572fSBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 1026fb2e594dSBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 10273a40ed3dSBarry Smith PetscFunctionReturn(0); 102817ab2063SBarry Smith } 1029c783ea89SBarry Smith 1030c783ea89SBarry Smith /* setup workspace for Eisenstat */ 1031c783ea89SBarry Smith if (flag & SOR_EISENSTAT) { 1032c783ea89SBarry Smith if (!a->idiag) { 1033c783ea89SBarry Smith a->idiag = (Scalar*)PetscMalloc(2*m*sizeof(Scalar));CHKPTRQ(a->idiag); 1034c783ea89SBarry Smith a->ssor = a->idiag + m; 1035c783ea89SBarry Smith v = a->a; 1036c783ea89SBarry Smith for (i=0; i<m; i++) { a->idiag[i] = 1.0/v[diag[i]];} 1037c783ea89SBarry Smith } 1038c783ea89SBarry Smith t = a->ssor; 1039c783ea89SBarry Smith idiag = a->idiag; 1040c783ea89SBarry Smith } 1041fc3d8934SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1042fc3d8934SBarry Smith U is upper triangular, E is diagonal; This routine applies 1043fc3d8934SBarry Smith 1044fc3d8934SBarry Smith (L + E)^{-1} A (U + E)^{-1} 1045fc3d8934SBarry Smith 1046fc3d8934SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 1047fc3d8934SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 104848af12d7SBarry Smith is the relaxation factor. 1049fc3d8934SBarry Smith */ 1050fc3d8934SBarry Smith 105148af12d7SBarry Smith if (flag == SOR_APPLY_LOWER) { 105248af12d7SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"SOR_APPLY_LOWER is not done"); 105348af12d7SBarry Smith } else if ((flag & SOR_EISENSTAT) && omega == 1.0 && shift == 0 && fshift == 0.0) { 105448af12d7SBarry Smith /* special case for omega = 1.0 saves flops and some integer ops */ 1055733d66baSBarry Smith Scalar *v2; 105648af12d7SBarry Smith 1057733d66baSBarry Smith v2 = a->a; 1058fc3d8934SBarry Smith /* x = (E + U)^{-1} b */ 1059fc3d8934SBarry Smith for (i=m-1; i>=0; i--) { 1060fc3d8934SBarry Smith n = a->i[i+1] - diag[i] - 1; 1061fc3d8934SBarry Smith idx = a->j + diag[i] + 1; 1062fc3d8934SBarry Smith v = a->a + diag[i] + 1; 1063fc3d8934SBarry Smith sum = b[i]; 1064fc3d8934SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1065b4632166SBarry Smith x[i] = sum*idiag[i]; 1066fc3d8934SBarry Smith 1067fc3d8934SBarry Smith /* t = b - (2*E - D)x */ 1068733d66baSBarry Smith t[i] = b[i] - (v2[diag[i]])*x[i]; 1069733d66baSBarry Smith } 1070fc3d8934SBarry Smith 1071fc3d8934SBarry Smith /* t = (E + L)^{-1}t */ 1072fc3d8934SBarry Smith diag = a->diag; 1073fc3d8934SBarry Smith for (i=0; i<m; i++) { 1074fc3d8934SBarry Smith n = diag[i] - a->i[i]; 1075fc3d8934SBarry Smith idx = a->j + a->i[i]; 1076fc3d8934SBarry Smith v = a->a + a->i[i]; 1077fc3d8934SBarry Smith sum = t[i]; 1078fc3d8934SBarry Smith SPARSEDENSEMDOT(sum,t,v,idx,n); 1079b4632166SBarry Smith t[i] = sum*idiag[i]; 1080fc3d8934SBarry Smith 1081fc3d8934SBarry Smith /* x = x + t */ 1082733d66baSBarry Smith x[i] += t[i]; 1083733d66baSBarry Smith } 1084733d66baSBarry Smith 1085a4d9cbf6SBarry Smith PLogFlops(3*m-1 + 2*a->nz); 1086fc3d8934SBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 1087fc3d8934SBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 1088fc3d8934SBarry Smith PetscFunctionReturn(0); 10893a40ed3dSBarry Smith } else if (flag & SOR_EISENSTAT) { 109017ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 109117ab2063SBarry Smith U is upper triangular, E is diagonal; This routine applies 109217ab2063SBarry Smith 109317ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 109417ab2063SBarry Smith 109517ab2063SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 109617ab2063SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 109717ab2063SBarry Smith is the relaxation factor. 109817ab2063SBarry Smith */ 109917ab2063SBarry Smith scale = (2.0/omega) - 1.0; 110017ab2063SBarry Smith 110117ab2063SBarry Smith /* x = (E + U)^{-1} b */ 110217ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1103416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 1104416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1105416022c9SBarry Smith idx = a->j + diag[i] + (!shift); 1106416022c9SBarry Smith v = a->a + diag[i] + (!shift); 110717ab2063SBarry Smith sum = b[i]; 110817ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 110917ab2063SBarry Smith x[i] = omega*(sum/d); 111017ab2063SBarry Smith } 111117ab2063SBarry Smith 111217ab2063SBarry Smith /* t = b - (2*E - D)x */ 1113416022c9SBarry Smith v = a->a; 111417ab2063SBarry Smith for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++ + shift])*x[i]; } 111517ab2063SBarry Smith 111617ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1117416022c9SBarry Smith ts = t + shift; /* shifted by one for index start of a or a->j*/ 1118416022c9SBarry Smith diag = a->diag; 111917ab2063SBarry Smith for (i=0; i<m; i++) { 1120416022c9SBarry Smith d = fshift + a->a[diag[i]+shift]; 1121416022c9SBarry Smith n = diag[i] - a->i[i]; 1122416022c9SBarry Smith idx = a->j + a->i[i] + shift; 1123416022c9SBarry Smith v = a->a + a->i[i] + shift; 112417ab2063SBarry Smith sum = t[i]; 112517ab2063SBarry Smith SPARSEDENSEMDOT(sum,ts,v,idx,n); 112617ab2063SBarry Smith t[i] = omega*(sum/d); 1127733d66baSBarry Smith /* x = x + t */ 1128733d66baSBarry Smith x[i] += t[i]; 112917ab2063SBarry Smith } 113017ab2063SBarry Smith 1131c783ea89SBarry Smith PLogFlops(6*m-1 + 2*a->nz); 1132cb5b572fSBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 1133fb2e594dSBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 11343a40ed3dSBarry Smith PetscFunctionReturn(0); 113517ab2063SBarry Smith } 113617ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 113717ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 113817ab2063SBarry Smith for (i=0; i<m; i++) { 1139416022c9SBarry Smith d = fshift + a->a[diag[i]+shift]; 1140416022c9SBarry Smith n = diag[i] - a->i[i]; 1141488ecbafSBarry Smith PLogFlops(2*n-1); 1142416022c9SBarry Smith idx = a->j + a->i[i] + shift; 1143416022c9SBarry Smith v = a->a + a->i[i] + shift; 114417ab2063SBarry Smith sum = b[i]; 114517ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 114617ab2063SBarry Smith x[i] = omega*(sum/d); 114717ab2063SBarry Smith } 114817ab2063SBarry Smith xb = x; 11493a40ed3dSBarry Smith } else xb = b; 115017ab2063SBarry Smith if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) && 115117ab2063SBarry Smith (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) { 115217ab2063SBarry Smith for (i=0; i<m; i++) { 1153416022c9SBarry Smith x[i] *= a->a[diag[i]+shift]; 115417ab2063SBarry Smith } 1155488ecbafSBarry Smith PLogFlops(m); 115617ab2063SBarry Smith } 115717ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 115817ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1159416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 1160416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1161488ecbafSBarry Smith PLogFlops(2*n-1); 1162416022c9SBarry Smith idx = a->j + diag[i] + (!shift); 1163416022c9SBarry Smith v = a->a + diag[i] + (!shift); 116417ab2063SBarry Smith sum = xb[i]; 116517ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 116617ab2063SBarry Smith x[i] = omega*(sum/d); 116717ab2063SBarry Smith } 116817ab2063SBarry Smith } 116917ab2063SBarry Smith its--; 117017ab2063SBarry Smith } 117117ab2063SBarry Smith while (its--) { 117217ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 117317ab2063SBarry Smith for (i=0; i<m; i++) { 1174416022c9SBarry Smith d = fshift + a->a[diag[i]+shift]; 1175416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1176488ecbafSBarry Smith PLogFlops(2*n-1); 1177416022c9SBarry Smith idx = a->j + a->i[i] + shift; 1178416022c9SBarry Smith v = a->a + a->i[i] + shift; 117917ab2063SBarry Smith sum = b[i]; 118017ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 11817e33a6baSBarry Smith x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d; 118217ab2063SBarry Smith } 118317ab2063SBarry Smith } 118417ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 118517ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1186416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 1187416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1188488ecbafSBarry Smith PLogFlops(2*n-1); 1189416022c9SBarry Smith idx = a->j + a->i[i] + shift; 1190416022c9SBarry Smith v = a->a + a->i[i] + shift; 119117ab2063SBarry Smith sum = b[i]; 119217ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 11937e33a6baSBarry Smith x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d; 119417ab2063SBarry Smith } 119517ab2063SBarry Smith } 119617ab2063SBarry Smith } 1197cb5b572fSBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 1198fb2e594dSBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 11993a40ed3dSBarry Smith PetscFunctionReturn(0); 120017ab2063SBarry Smith } 120117ab2063SBarry Smith 12025615d1e5SSatish Balay #undef __FUNC__ 1203b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetInfo_SeqAIJ" 12048f6be9afSLois Curfman McInnes int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 120517ab2063SBarry Smith { 1206416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 12074e220ebcSLois Curfman McInnes 12083a40ed3dSBarry Smith PetscFunctionBegin; 12094e220ebcSLois Curfman McInnes info->rows_global = (double)a->m; 12104e220ebcSLois Curfman McInnes info->columns_global = (double)a->n; 12114e220ebcSLois Curfman McInnes info->rows_local = (double)a->m; 12124e220ebcSLois Curfman McInnes info->columns_local = (double)a->n; 12134e220ebcSLois Curfman McInnes info->block_size = 1.0; 12144e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 12154e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 12164e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 12174e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 12184e220ebcSLois Curfman McInnes info->mallocs = (double)a->reallocs; 12194e220ebcSLois Curfman McInnes info->memory = A->mem; 12204e220ebcSLois Curfman McInnes if (A->factor) { 12214e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 12224e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 12234e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 12244e220ebcSLois Curfman McInnes } else { 12254e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 12264e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 12274e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 12284e220ebcSLois Curfman McInnes } 12293a40ed3dSBarry Smith PetscFunctionReturn(0); 123017ab2063SBarry Smith } 123117ab2063SBarry Smith 123236db0b34SBarry Smith extern int MatLUFactorSymbolic_SeqAIJ(Mat,IS,IS,PetscReal,Mat*); 123317ab2063SBarry Smith extern int MatLUFactorNumeric_SeqAIJ(Mat,Mat*); 123436db0b34SBarry Smith extern int MatLUFactor_SeqAIJ(Mat,IS,IS,PetscReal); 123517ab2063SBarry Smith extern int MatSolve_SeqAIJ(Mat,Vec,Vec); 123617ab2063SBarry Smith extern int MatSolveAdd_SeqAIJ(Mat,Vec,Vec,Vec); 12377c922b88SBarry Smith extern int MatSolveTranspose_SeqAIJ(Mat,Vec,Vec); 12387c922b88SBarry Smith extern int MatSolveTransposeAdd_SeqAIJ(Mat,Vec,Vec,Vec); 123917ab2063SBarry Smith 12405615d1e5SSatish Balay #undef __FUNC__ 1241e7592fafSBarry Smith #define __FUNC__ /*<a name="MatZeroRows_SeqAIJ"></a>*/"MatZeroRows_SeqAIJ" 12428f6be9afSLois Curfman McInnes int MatZeroRows_SeqAIJ(Mat A,IS is,Scalar *diag) 124317ab2063SBarry Smith { 1244416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1245416022c9SBarry Smith int i,ierr,N,*rows,m = a->m - 1,shift = a->indexshift; 124617ab2063SBarry Smith 12473a40ed3dSBarry Smith PetscFunctionBegin; 124877c4ece6SBarry Smith ierr = ISGetSize(is,&N);CHKERRQ(ierr); 124917ab2063SBarry Smith ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 1250f1e2ffcdSBarry Smith if (a->keepzeroedrows) { 1251f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1252f1e2ffcdSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range"); 1253f1e2ffcdSBarry Smith ierr = PetscMemzero(&a->a[a->i[rows[i]]+shift],a->ilen[rows[i]]*sizeof(Scalar));CHKERRQ(ierr); 1254f1e2ffcdSBarry Smith } 1255f1e2ffcdSBarry Smith if (diag) { 1256f1e2ffcdSBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1257f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1258f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1259f1e2ffcdSBarry Smith a->a[a->diag[rows[i]]] = *diag; 1260f1e2ffcdSBarry Smith } 1261f1e2ffcdSBarry Smith } 1262f1e2ffcdSBarry Smith } else { 126317ab2063SBarry Smith if (diag) { 126417ab2063SBarry Smith for (i=0; i<N; i++) { 1265a8c6a408SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range"); 12667ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1267416022c9SBarry Smith a->ilen[rows[i]] = 1; 1268416022c9SBarry Smith a->a[a->i[rows[i]]+shift] = *diag; 1269416022c9SBarry Smith a->j[a->i[rows[i]]+shift] = rows[i]+shift; 12707ae801bdSBarry Smith } else { /* in case row was completely empty */ 1271d64ed03dSBarry Smith ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr); 127217ab2063SBarry Smith } 127317ab2063SBarry Smith } 12743a40ed3dSBarry Smith } else { 127517ab2063SBarry Smith for (i=0; i<N; i++) { 1276a8c6a408SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range"); 1277416022c9SBarry Smith a->ilen[rows[i]] = 0; 127817ab2063SBarry Smith } 127917ab2063SBarry Smith } 1280f1e2ffcdSBarry Smith } 12817ae801bdSBarry Smith ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 128243a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 12833a40ed3dSBarry Smith PetscFunctionReturn(0); 128417ab2063SBarry Smith } 128517ab2063SBarry Smith 12865615d1e5SSatish Balay #undef __FUNC__ 1287b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetSize_SeqAIJ" 12888f6be9afSLois Curfman McInnes int MatGetSize_SeqAIJ(Mat A,int *m,int *n) 128917ab2063SBarry Smith { 1290416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 12913a40ed3dSBarry Smith 12923a40ed3dSBarry Smith PetscFunctionBegin; 12930752156aSBarry Smith if (m) *m = a->m; 12940752156aSBarry Smith if (n) *n = a->n; 12953a40ed3dSBarry Smith PetscFunctionReturn(0); 129617ab2063SBarry Smith } 129717ab2063SBarry Smith 12985615d1e5SSatish Balay #undef __FUNC__ 1299b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetOwnershipRange_SeqAIJ" 13008f6be9afSLois Curfman McInnes int MatGetOwnershipRange_SeqAIJ(Mat A,int *m,int *n) 130117ab2063SBarry Smith { 1302416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 13033a40ed3dSBarry Smith 13043a40ed3dSBarry Smith PetscFunctionBegin; 13054c49b128SBarry Smith if (m) *m = 0; 13064c49b128SBarry Smith if (n) *n = a->m; 13073a40ed3dSBarry Smith PetscFunctionReturn(0); 130817ab2063SBarry Smith } 1309026e39d0SSatish Balay 13105615d1e5SSatish Balay #undef __FUNC__ 1311b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetRow_SeqAIJ" 13124e093b46SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 131317ab2063SBarry Smith { 1314416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1315c456f294SBarry Smith int *itmp,i,shift = a->indexshift; 131617ab2063SBarry Smith 13173a40ed3dSBarry Smith PetscFunctionBegin; 1318a8c6a408SBarry Smith if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range"); 131917ab2063SBarry Smith 1320416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1321416022c9SBarry Smith if (v) *v = a->a + a->i[row] + shift; 132217ab2063SBarry Smith if (idx) { 1323416022c9SBarry Smith itmp = a->j + a->i[row] + shift; 13244e093b46SBarry Smith if (*nz && shift) { 13250452661fSBarry Smith *idx = (int*)PetscMalloc((*nz)*sizeof(int));CHKPTRQ(*idx); 132617ab2063SBarry Smith for (i=0; i<(*nz); i++) {(*idx)[i] = itmp[i] + shift;} 13274e093b46SBarry Smith } else if (*nz) { 13284e093b46SBarry Smith *idx = itmp; 132917ab2063SBarry Smith } 133017ab2063SBarry Smith else *idx = 0; 133117ab2063SBarry Smith } 13323a40ed3dSBarry Smith PetscFunctionReturn(0); 133317ab2063SBarry Smith } 133417ab2063SBarry Smith 13355615d1e5SSatish Balay #undef __FUNC__ 1336b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatRestoreRow_SeqAIJ" 13374e093b46SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 133817ab2063SBarry Smith { 13394e093b46SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1340606d414cSSatish Balay int ierr; 13413a40ed3dSBarry Smith 13423a40ed3dSBarry Smith PetscFunctionBegin; 1343606d414cSSatish Balay if (idx) {if (*idx && a->indexshift) {ierr = PetscFree(*idx);CHKERRQ(ierr);}} 13443a40ed3dSBarry Smith PetscFunctionReturn(0); 134517ab2063SBarry Smith } 134617ab2063SBarry Smith 13475615d1e5SSatish Balay #undef __FUNC__ 1348b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatNorm_SeqAIJ" 134936db0b34SBarry Smith int MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *norm) 135017ab2063SBarry Smith { 1351416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1352416022c9SBarry Smith Scalar *v = a->a; 135336db0b34SBarry Smith PetscReal sum = 0.0; 1354549d3d68SSatish Balay int i,j,shift = a->indexshift,ierr; 135517ab2063SBarry Smith 13563a40ed3dSBarry Smith PetscFunctionBegin; 135717ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1358416022c9SBarry Smith for (i=0; i<a->nz; i++) { 1359aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 136036db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 136117ab2063SBarry Smith #else 136217ab2063SBarry Smith sum += (*v)*(*v); v++; 136317ab2063SBarry Smith #endif 136417ab2063SBarry Smith } 136517ab2063SBarry Smith *norm = sqrt(sum); 13663a40ed3dSBarry Smith } else if (type == NORM_1) { 136736db0b34SBarry Smith PetscReal *tmp; 1368416022c9SBarry Smith int *jj = a->j; 136936db0b34SBarry Smith tmp = (PetscReal*)PetscMalloc((a->n+1)*sizeof(PetscReal));CHKPTRQ(tmp); 137036db0b34SBarry Smith ierr = PetscMemzero(tmp,a->n*sizeof(PetscReal));CHKERRQ(ierr); 137117ab2063SBarry Smith *norm = 0.0; 1372416022c9SBarry Smith for (j=0; j<a->nz; j++) { 1373a2744918SBarry Smith tmp[*jj++ + shift] += PetscAbsScalar(*v); v++; 137417ab2063SBarry Smith } 1375416022c9SBarry Smith for (j=0; j<a->n; j++) { 137617ab2063SBarry Smith if (tmp[j] > *norm) *norm = tmp[j]; 137717ab2063SBarry Smith } 1378606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 13793a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 138017ab2063SBarry Smith *norm = 0.0; 1381416022c9SBarry Smith for (j=0; j<a->m; j++) { 1382416022c9SBarry Smith v = a->a + a->i[j] + shift; 138317ab2063SBarry Smith sum = 0.0; 1384416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 1385cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 138617ab2063SBarry Smith } 138717ab2063SBarry Smith if (sum > *norm) *norm = sum; 138817ab2063SBarry Smith } 13893a40ed3dSBarry Smith } else { 1390a8c6a408SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"No support for two norm"); 139117ab2063SBarry Smith } 13923a40ed3dSBarry Smith PetscFunctionReturn(0); 139317ab2063SBarry Smith } 139417ab2063SBarry Smith 13955615d1e5SSatish Balay #undef __FUNC__ 1396b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatTranspose_SeqAIJ" 13978f6be9afSLois Curfman McInnes int MatTranspose_SeqAIJ(Mat A,Mat *B) 139817ab2063SBarry Smith { 1399416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1400416022c9SBarry Smith Mat C; 1401416022c9SBarry Smith int i,ierr,*aj = a->j,*ai = a->i,m = a->m,len,*col; 140236db0b34SBarry Smith int shift = a->indexshift,refct; 1403d5d45c9bSBarry Smith Scalar *array = a->a; 140417ab2063SBarry Smith 14053a40ed3dSBarry Smith PetscFunctionBegin; 1406f1e2ffcdSBarry Smith if (!B && m != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Square matrix only for in-place"); 14070452661fSBarry Smith col = (int*)PetscMalloc((1+a->n)*sizeof(int));CHKPTRQ(col); 1408549d3d68SSatish Balay ierr = PetscMemzero(col,(1+a->n)*sizeof(int));CHKERRQ(ierr); 140917ab2063SBarry Smith if (shift) { 141017ab2063SBarry Smith for (i=0; i<ai[m]-1; i++) aj[i] -= 1; 141117ab2063SBarry Smith } 141217ab2063SBarry Smith for (i=0; i<ai[m]+shift; i++) col[aj[i]] += 1; 1413416022c9SBarry Smith ierr = MatCreateSeqAIJ(A->comm,a->n,m,0,col,&C);CHKERRQ(ierr); 1414606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 141517ab2063SBarry Smith for (i=0; i<m; i++) { 141617ab2063SBarry Smith len = ai[i+1]-ai[i]; 1417416022c9SBarry Smith ierr = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 141817ab2063SBarry Smith array += len; aj += len; 141917ab2063SBarry Smith } 142017ab2063SBarry Smith if (shift) { 142117ab2063SBarry Smith for (i=0; i<ai[m]-1; i++) aj[i] += 1; 142217ab2063SBarry Smith } 142317ab2063SBarry Smith 14246d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14256d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 142617ab2063SBarry Smith 1427f1e2ffcdSBarry Smith if (B) { 1428416022c9SBarry Smith *B = C; 142917ab2063SBarry Smith } else { 1430f830108cSBarry Smith PetscOps *Abops; 14310a6ffc59SBarry Smith MatOps Aops; 1432f830108cSBarry Smith 1433416022c9SBarry Smith /* This isn't really an in-place transpose */ 1434606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 1435606d414cSSatish Balay if (!a->singlemalloc) { 1436606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 1437606d414cSSatish Balay ierr = PetscFree(a->j); 1438606d414cSSatish Balay } 1439606d414cSSatish Balay if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);} 1440606d414cSSatish Balay if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);} 1441606d414cSSatish Balay if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);} 1442606d414cSSatish Balay if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);} 1443606d414cSSatish Balay if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);} 1444606d414cSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 1445f830108cSBarry Smith 1446488ecbafSBarry Smith 1447488ecbafSBarry Smith ierr = MapDestroy(A->rmap);CHKERRQ(ierr); 1448488ecbafSBarry Smith ierr = MapDestroy(A->cmap);CHKERRQ(ierr); 1449488ecbafSBarry Smith 1450f830108cSBarry Smith /* 1451f830108cSBarry Smith This is horrible, horrible code. We need to keep the 14528f0f457cSSatish Balay the bops and ops Structures, copy everything from C 14538f0f457cSSatish Balay including the function pointers.. 1454f830108cSBarry Smith */ 1455549d3d68SSatish Balay ierr = PetscMemcpy(A->ops,C->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 1456549d3d68SSatish Balay ierr = PetscMemcpy(A->bops,C->bops,sizeof(PetscOps));CHKERRQ(ierr); 1457f830108cSBarry Smith Abops = A->bops; 1458f830108cSBarry Smith Aops = A->ops; 145936db0b34SBarry Smith refct = A->refct; 1460549d3d68SSatish Balay ierr = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr); 1461f830108cSBarry Smith A->bops = Abops; 1462f830108cSBarry Smith A->ops = Aops; 146327a8da17SBarry Smith A->qlist = 0; 146436db0b34SBarry Smith A->refct = refct; 146536db0b34SBarry Smith /* copy over the type_name and name */ 146636db0b34SBarry Smith ierr = PetscStrallocpy(C->type_name,&A->type_name);CHKERRQ(ierr); 146736db0b34SBarry Smith ierr = PetscStrallocpy(C->name,&A->name);CHKERRQ(ierr); 1468f830108cSBarry Smith 14690452661fSBarry Smith PetscHeaderDestroy(C); 147017ab2063SBarry Smith } 14713a40ed3dSBarry Smith PetscFunctionReturn(0); 147217ab2063SBarry Smith } 147317ab2063SBarry Smith 14745615d1e5SSatish Balay #undef __FUNC__ 1475b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatDiagonalScale_SeqAIJ" 14768f6be9afSLois Curfman McInnes int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 147717ab2063SBarry Smith { 1478416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 147917ab2063SBarry Smith Scalar *l,*r,x,*v; 1480e1311b90SBarry Smith int ierr,i,j,m = a->m,n = a->n,M,nz = a->nz,*jj,shift = a->indexshift; 148117ab2063SBarry Smith 14823a40ed3dSBarry Smith PetscFunctionBegin; 148317ab2063SBarry Smith if (ll) { 14843ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 14853ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 1486e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 1487a8c6a408SBarry Smith if (m != a->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Left scaling vector wrong length"); 1488e1311b90SBarry Smith ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 1489416022c9SBarry Smith v = a->a; 149017ab2063SBarry Smith for (i=0; i<m; i++) { 149117ab2063SBarry Smith x = l[i]; 1492416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 149317ab2063SBarry Smith for (j=0; j<M; j++) { (*v++) *= x;} 149417ab2063SBarry Smith } 1495e1311b90SBarry Smith ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 149644cd7ae7SLois Curfman McInnes PLogFlops(nz); 149717ab2063SBarry Smith } 149817ab2063SBarry Smith if (rr) { 1499e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 1500a8c6a408SBarry Smith if (n != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Right scaling vector wrong length"); 1501e1311b90SBarry Smith ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 1502416022c9SBarry Smith v = a->a; jj = a->j; 150317ab2063SBarry Smith for (i=0; i<nz; i++) { 150417ab2063SBarry Smith (*v++) *= r[*jj++ + shift]; 150517ab2063SBarry Smith } 1506e1311b90SBarry Smith ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 150744cd7ae7SLois Curfman McInnes PLogFlops(nz); 150817ab2063SBarry Smith } 15093a40ed3dSBarry Smith PetscFunctionReturn(0); 151017ab2063SBarry Smith } 151117ab2063SBarry Smith 15125615d1e5SSatish Balay #undef __FUNC__ 1513b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetSubMatrix_SeqAIJ" 15147b2a1423SBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatReuse scall,Mat *B) 151517ab2063SBarry Smith { 1516db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 1517d5db1b72SBarry Smith int *smap,i,k,kstart,kend,ierr,oldcols = a->n,*lens; 151836db0b34SBarry Smith int row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 151999141d43SSatish Balay int *irow,*icol,nrows,ncols,shift = a->indexshift,*ssmap; 152099141d43SSatish Balay int *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 152199141d43SSatish Balay Scalar *a_new,*mat_a; 1522416022c9SBarry Smith Mat C; 1523fee21e36SBarry Smith PetscTruth stride; 152417ab2063SBarry Smith 15253a40ed3dSBarry Smith PetscFunctionBegin; 1526d64ed03dSBarry Smith ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr); 1527a8c6a408SBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"ISrow is not sorted"); 1528d64ed03dSBarry Smith ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr); 1529a8c6a408SBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"IScol is not sorted"); 153099141d43SSatish Balay 153117ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 153217ab2063SBarry Smith ierr = ISGetSize(isrow,&nrows);CHKERRQ(ierr); 153317ab2063SBarry Smith ierr = ISGetSize(iscol,&ncols);CHKERRQ(ierr); 153417ab2063SBarry Smith 1535fee21e36SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 1536fee21e36SBarry Smith ierr = ISStride(iscol,&stride);CHKERRQ(ierr); 1537fee21e36SBarry Smith if (stride && step == 1) { 153802834360SBarry Smith /* special case of contiguous rows */ 153957faeb66SBarry Smith lens = (int*)PetscMalloc((ncols+nrows+1)*sizeof(int));CHKPTRQ(lens); 154002834360SBarry Smith starts = lens + ncols; 154102834360SBarry Smith /* loop over new rows determining lens and starting points */ 154202834360SBarry Smith for (i=0; i<nrows; i++) { 1543a2744918SBarry Smith kstart = ai[irow[i]]+shift; 1544a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 154502834360SBarry Smith for (k=kstart; k<kend; k++) { 1546d8ced48eSBarry Smith if (aj[k]+shift >= first) { 154702834360SBarry Smith starts[i] = k; 154802834360SBarry Smith break; 154902834360SBarry Smith } 155002834360SBarry Smith } 1551a2744918SBarry Smith sum = 0; 155202834360SBarry Smith while (k < kend) { 1553d8ced48eSBarry Smith if (aj[k++]+shift >= first+ncols) break; 1554a2744918SBarry Smith sum++; 155502834360SBarry Smith } 1556a2744918SBarry Smith lens[i] = sum; 155702834360SBarry Smith } 155802834360SBarry Smith /* create submatrix */ 1559cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 156008480c60SBarry Smith int n_cols,n_rows; 156108480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 1562a8c6a408SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Reused submatrix wrong size"); 1563d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 156408480c60SBarry Smith C = *B; 15653a40ed3dSBarry Smith } else { 156602834360SBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 156708480c60SBarry Smith } 1568db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 1569db02288aSLois Curfman McInnes 157002834360SBarry Smith /* loop over rows inserting into submatrix */ 1571db02288aSLois Curfman McInnes a_new = c->a; 1572db02288aSLois Curfman McInnes j_new = c->j; 1573db02288aSLois Curfman McInnes i_new = c->i; 1574db02288aSLois Curfman McInnes i_new[0] = -shift; 157502834360SBarry Smith for (i=0; i<nrows; i++) { 1576a2744918SBarry Smith ii = starts[i]; 1577a2744918SBarry Smith lensi = lens[i]; 1578a2744918SBarry Smith for (k=0; k<lensi; k++) { 1579a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 158002834360SBarry Smith } 1581549d3d68SSatish Balay ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(Scalar));CHKERRQ(ierr); 1582a2744918SBarry Smith a_new += lensi; 1583a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 1584a2744918SBarry Smith c->ilen[i] = lensi; 158502834360SBarry Smith } 1586606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 15873a40ed3dSBarry Smith } else { 158802834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 15890452661fSBarry Smith smap = (int*)PetscMalloc((1+oldcols)*sizeof(int));CHKPTRQ(smap); 159002834360SBarry Smith ssmap = smap + shift; 159199141d43SSatish Balay lens = (int*)PetscMalloc((1+nrows)*sizeof(int));CHKPTRQ(lens); 1592549d3d68SSatish Balay ierr = PetscMemzero(smap,oldcols*sizeof(int));CHKERRQ(ierr); 159317ab2063SBarry Smith for (i=0; i<ncols; i++) smap[icol[i]] = i+1; 159402834360SBarry Smith /* determine lens of each row */ 159502834360SBarry Smith for (i=0; i<nrows; i++) { 1596d8ced48eSBarry Smith kstart = ai[irow[i]]+shift; 159702834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 159802834360SBarry Smith lens[i] = 0; 159902834360SBarry Smith for (k=kstart; k<kend; k++) { 1600d8ced48eSBarry Smith if (ssmap[aj[k]]) { 160102834360SBarry Smith lens[i]++; 160202834360SBarry Smith } 160302834360SBarry Smith } 160402834360SBarry Smith } 160517ab2063SBarry Smith /* Create and fill new matrix */ 1606a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 16070f5bd95cSBarry Smith PetscTruth equal; 16080f5bd95cSBarry Smith 160999141d43SSatish Balay c = (Mat_SeqAIJ *)((*B)->data); 1610a8c6a408SBarry Smith if (c->m != nrows || c->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong size"); 16110f5bd95cSBarry Smith ierr = PetscMemcmp(c->ilen,lens,c->m*sizeof(int),&equal);CHKERRQ(ierr); 16120f5bd95cSBarry Smith if (!equal) { 1613a8c6a408SBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong no of nonzeros"); 161499141d43SSatish Balay } 1615549d3d68SSatish Balay ierr = PetscMemzero(c->ilen,c->m*sizeof(int));CHKERRQ(ierr); 161608480c60SBarry Smith C = *B; 16173a40ed3dSBarry Smith } else { 161802834360SBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 161908480c60SBarry Smith } 162099141d43SSatish Balay c = (Mat_SeqAIJ *)(C->data); 162117ab2063SBarry Smith for (i=0; i<nrows; i++) { 162299141d43SSatish Balay row = irow[i]; 162399141d43SSatish Balay kstart = ai[row]+shift; 162499141d43SSatish Balay kend = kstart + a->ilen[row]; 162599141d43SSatish Balay mat_i = c->i[i]+shift; 162699141d43SSatish Balay mat_j = c->j + mat_i; 162799141d43SSatish Balay mat_a = c->a + mat_i; 162899141d43SSatish Balay mat_ilen = c->ilen + i; 162917ab2063SBarry Smith for (k=kstart; k<kend; k++) { 163099141d43SSatish Balay if ((tcol=ssmap[a->j[k]])) { 163199141d43SSatish Balay *mat_j++ = tcol - (!shift); 163299141d43SSatish Balay *mat_a++ = a->a[k]; 163399141d43SSatish Balay (*mat_ilen)++; 163499141d43SSatish Balay 163517ab2063SBarry Smith } 163617ab2063SBarry Smith } 163717ab2063SBarry Smith } 163802834360SBarry Smith /* Free work space */ 163902834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 1640606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 1641606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 164202834360SBarry Smith } 16436d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16446d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 164517ab2063SBarry Smith 164617ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 1647416022c9SBarry Smith *B = C; 16483a40ed3dSBarry Smith PetscFunctionReturn(0); 164917ab2063SBarry Smith } 165017ab2063SBarry Smith 1651a871dcd8SBarry Smith /* 1652a871dcd8SBarry Smith */ 16535615d1e5SSatish Balay #undef __FUNC__ 1654b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatILUFactor_SeqAIJ" 16555ef9f2a5SBarry Smith int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatILUInfo *info) 1656a871dcd8SBarry Smith { 165763b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 165808480c60SBarry Smith int ierr; 165963b91edcSBarry Smith Mat outA; 1660b8a78c4aSBarry Smith PetscTruth row_identity,col_identity; 166163b91edcSBarry Smith 16623a40ed3dSBarry Smith PetscFunctionBegin; 1663b8a78c4aSBarry Smith if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,0,"Only levels=0 supported for in-place ilu"); 1664b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 1665b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 1666b8a78c4aSBarry Smith if (!row_identity || !col_identity) { 1667b8a78c4aSBarry Smith SETERRQ(1,1,"Row and column permutations must be identity for in-place ILU"); 1668b8a78c4aSBarry Smith } 1669a871dcd8SBarry Smith 167063b91edcSBarry Smith outA = inA; 167163b91edcSBarry Smith inA->factor = FACTOR_LU; 167263b91edcSBarry Smith a->row = row; 167363b91edcSBarry Smith a->col = col; 1674c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1675c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 167663b91edcSBarry Smith 167736db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 1678c38d4ed2SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* if this came from a previous factored; need to remove old one */ 16794c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 16801e4dd532SSatish Balay PLogObjectParent(inA,a->icol); 1681f0ec6fceSSatish Balay 168294a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 16830452661fSBarry Smith a->solve_work = (Scalar*)PetscMalloc((a->m+1)*sizeof(Scalar));CHKPTRQ(a->solve_work); 168494a9d846SBarry Smith } 168563b91edcSBarry Smith 168608480c60SBarry Smith if (!a->diag) { 1687f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 168863b91edcSBarry Smith } 168963b91edcSBarry Smith ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA);CHKERRQ(ierr); 16903a40ed3dSBarry Smith PetscFunctionReturn(0); 1691a871dcd8SBarry Smith } 1692a871dcd8SBarry Smith 169374cdf0dfSBarry Smith #include "pinclude/blaslapack.h" 16945615d1e5SSatish Balay #undef __FUNC__ 1695b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatScale_SeqAIJ" 16968f6be9afSLois Curfman McInnes int MatScale_SeqAIJ(Scalar *alpha,Mat inA) 1697f0b747eeSBarry Smith { 1698f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 1699f0b747eeSBarry Smith int one = 1; 17003a40ed3dSBarry Smith 17013a40ed3dSBarry Smith PetscFunctionBegin; 1702f0b747eeSBarry Smith BLscal_(&a->nz,alpha,a->a,&one); 1703f0b747eeSBarry Smith PLogFlops(a->nz); 17043a40ed3dSBarry Smith PetscFunctionReturn(0); 1705f0b747eeSBarry Smith } 1706f0b747eeSBarry Smith 17075615d1e5SSatish Balay #undef __FUNC__ 1708b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetSubMatrices_SeqAIJ" 17097b2a1423SBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n,IS *irow,IS *icol,MatReuse scall,Mat **B) 1710cddf8d76SBarry Smith { 1711cddf8d76SBarry Smith int ierr,i; 1712cddf8d76SBarry Smith 17133a40ed3dSBarry Smith PetscFunctionBegin; 1714cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 17150452661fSBarry Smith *B = (Mat*)PetscMalloc((n+1)*sizeof(Mat));CHKPTRQ(*B); 1716cddf8d76SBarry Smith } 1717cddf8d76SBarry Smith 1718cddf8d76SBarry Smith for (i=0; i<n; i++) { 17196a6a5d1dSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 1720cddf8d76SBarry Smith } 17213a40ed3dSBarry Smith PetscFunctionReturn(0); 1722cddf8d76SBarry Smith } 1723cddf8d76SBarry Smith 17245615d1e5SSatish Balay #undef __FUNC__ 1725b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetBlockSize_SeqAIJ" 17268f6be9afSLois Curfman McInnes int MatGetBlockSize_SeqAIJ(Mat A,int *bs) 17275a838052SSatish Balay { 1728f830108cSBarry Smith PetscFunctionBegin; 17295a838052SSatish Balay *bs = 1; 17303a40ed3dSBarry Smith PetscFunctionReturn(0); 17315a838052SSatish Balay } 17325a838052SSatish Balay 17335615d1e5SSatish Balay #undef __FUNC__ 1734b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatIncreaseOverlap_SeqAIJ" 17358f6be9afSLois Curfman McInnes int MatIncreaseOverlap_SeqAIJ(Mat A,int is_max,IS *is,int ov) 17364dcbc457SBarry Smith { 1737e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 173806763907SSatish Balay int shift,row,i,j,k,l,m,n,*idx,ierr,*nidx,isz,val; 17398a047759SSatish Balay int start,end,*ai,*aj; 1740f1af5d2fSBarry Smith PetscBT table; 1741bbd702dbSSatish Balay 17423a40ed3dSBarry Smith PetscFunctionBegin; 17438a047759SSatish Balay shift = a->indexshift; 1744e4d965acSSatish Balay m = a->m; 1745e4d965acSSatish Balay ai = a->i; 17468a047759SSatish Balay aj = a->j+shift; 17478a047759SSatish Balay 1748a8c6a408SBarry Smith if (ov < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"illegal overlap value used"); 174906763907SSatish Balay 175006763907SSatish Balay nidx = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(nidx); 17516831982aSBarry Smith ierr = PetscBTCreate(m,table);CHKERRQ(ierr); 175206763907SSatish Balay 1753e4d965acSSatish Balay for (i=0; i<is_max; i++) { 1754b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 1755e4d965acSSatish Balay isz = 0; 17566831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 1757e4d965acSSatish Balay 1758e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 17594dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 176077c4ece6SBarry Smith ierr = ISGetSize(is[i],&n);CHKERRQ(ierr); 1761e4d965acSSatish Balay 1762dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 1763e4d965acSSatish Balay for (j=0; j<n ; ++j){ 1764f1af5d2fSBarry Smith if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];} 17654dcbc457SBarry Smith } 176606763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 176706763907SSatish Balay ierr = ISDestroy(is[i]);CHKERRQ(ierr); 1768e4d965acSSatish Balay 176904a348a9SBarry Smith k = 0; 177004a348a9SBarry Smith for (j=0; j<ov; j++){ /* for each overlap */ 177104a348a9SBarry Smith n = isz; 177206763907SSatish Balay for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */ 1773e4d965acSSatish Balay row = nidx[k]; 1774e4d965acSSatish Balay start = ai[row]; 1775e4d965acSSatish Balay end = ai[row+1]; 177604a348a9SBarry Smith for (l = start; l<end ; l++){ 17778a047759SSatish Balay val = aj[l] + shift; 1778f1af5d2fSBarry Smith if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;} 1779e4d965acSSatish Balay } 1780e4d965acSSatish Balay } 1781e4d965acSSatish Balay } 1782029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr); 1783e4d965acSSatish Balay } 17846831982aSBarry Smith ierr = PetscBTDestroy(table);CHKERRQ(ierr); 1785606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 17863a40ed3dSBarry Smith PetscFunctionReturn(0); 17874dcbc457SBarry Smith } 178817ab2063SBarry Smith 17890513a670SBarry Smith /* -------------------------------------------------------------- */ 17900513a670SBarry Smith #undef __FUNC__ 1791b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatPermute_SeqAIJ" 17920513a670SBarry Smith int MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 17930513a670SBarry Smith { 17940513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17950513a670SBarry Smith Scalar *vwork; 17960513a670SBarry Smith int i,ierr,nz,m = a->m,n = a->n,*cwork; 17970513a670SBarry Smith int *row,*col,*cnew,j,*lens; 179856cd22aeSBarry Smith IS icolp,irowp; 17990513a670SBarry Smith 18003a40ed3dSBarry Smith PetscFunctionBegin; 18014c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 180256cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 18034c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 180456cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 18050513a670SBarry Smith 18060513a670SBarry Smith /* determine lengths of permuted rows */ 18070513a670SBarry Smith lens = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(lens); 18080513a670SBarry Smith for (i=0; i<m; i++) { 18090513a670SBarry Smith lens[row[i]] = a->i[i+1] - a->i[i]; 18100513a670SBarry Smith } 18110513a670SBarry Smith ierr = MatCreateSeqAIJ(A->comm,m,n,0,lens,B);CHKERRQ(ierr); 1812606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 18130513a670SBarry Smith 18140513a670SBarry Smith cnew = (int*)PetscMalloc(n*sizeof(int));CHKPTRQ(cnew); 18150513a670SBarry Smith for (i=0; i<m; i++) { 18160513a670SBarry Smith ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 18170513a670SBarry Smith for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];} 18180513a670SBarry Smith ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 18190513a670SBarry Smith ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 18200513a670SBarry Smith } 1821606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 18220513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18230513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 182456cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 182556cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 182656cd22aeSBarry Smith ierr = ISDestroy(irowp);CHKERRQ(ierr); 182756cd22aeSBarry Smith ierr = ISDestroy(icolp);CHKERRQ(ierr); 18283a40ed3dSBarry Smith PetscFunctionReturn(0); 18290513a670SBarry Smith } 18300513a670SBarry Smith 18315615d1e5SSatish Balay #undef __FUNC__ 1832b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatPrintHelp_SeqAIJ" 1833682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A) 1834682d7d0cSBarry Smith { 1835c38d4ed2SBarry Smith static PetscTruth called = PETSC_FALSE; 1836682d7d0cSBarry Smith MPI_Comm comm = A->comm; 1837d132466eSBarry Smith int ierr; 1838682d7d0cSBarry Smith 18393a40ed3dSBarry Smith PetscFunctionBegin; 1840c38d4ed2SBarry Smith if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE; 1841d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr); 1842d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr); 1843d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr); 1844d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_no_inode: Do not use inodes\n");CHKERRQ(ierr); 1845d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");CHKERRQ(ierr); 1846aa482453SBarry Smith #if defined(PETSC_HAVE_ESSL) 1847d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_essl: Use IBM sparse LU factorization and solve.\n");CHKERRQ(ierr); 1848682d7d0cSBarry Smith #endif 18493a40ed3dSBarry Smith PetscFunctionReturn(0); 1850682d7d0cSBarry Smith } 18518f6be9afSLois Curfman McInnes extern int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg); 1852a93ec695SBarry Smith extern int MatFDColoringCreate_SeqAIJ(Mat,ISColoring,MatFDColoring); 1853a93ec695SBarry Smith extern int MatColoringPatch_SeqAIJ(Mat,int,int *,ISColoring *); 185436db0b34SBarry Smith extern int MatILUDTFactor_SeqAIJ(Mat,MatILUInfo*,IS,IS,Mat*); 1855cb5b572fSBarry Smith #undef __FUNC__ 1856b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatCopy_SeqAIJ" 1857cb5b572fSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 1858cb5b572fSBarry Smith { 1859be6bf707SBarry Smith int ierr; 1860cb5b572fSBarry Smith 1861cb5b572fSBarry Smith PetscFunctionBegin; 1862be6bf707SBarry Smith if (str == SAME_NONZERO_PATTERN && B->type == MATSEQAIJ) { 1863be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1864be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 1865be6bf707SBarry Smith 1866be6bf707SBarry Smith if (a->i[a->m]+a->indexshift != b->i[b->m]+a->indexshift) { 1867be6bf707SBarry Smith SETERRQ(1,1,"Number of nonzeros in two matrices are different"); 1868cb5b572fSBarry Smith } 1869549d3d68SSatish Balay ierr = PetscMemcpy(b->a,a->a,(a->i[a->m]+a->indexshift)*sizeof(Scalar));CHKERRQ(ierr); 1870cb5b572fSBarry Smith } else { 1871cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1872cb5b572fSBarry Smith } 1873cb5b572fSBarry Smith PetscFunctionReturn(0); 1874cb5b572fSBarry Smith } 1875cb5b572fSBarry Smith 1876682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 18770a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ, 1878cb5b572fSBarry Smith MatGetRow_SeqAIJ, 1879cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 1880cb5b572fSBarry Smith MatMult_SeqAIJ, 1881cb5b572fSBarry Smith MatMultAdd_SeqAIJ, 18827c922b88SBarry Smith MatMultTranspose_SeqAIJ, 18837c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 1884cb5b572fSBarry Smith MatSolve_SeqAIJ, 1885cb5b572fSBarry Smith MatSolveAdd_SeqAIJ, 18867c922b88SBarry Smith MatSolveTranspose_SeqAIJ, 18877c922b88SBarry Smith MatSolveTransposeAdd_SeqAIJ, 1888cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 1889cb5b572fSBarry Smith 0, 189017ab2063SBarry Smith MatRelax_SeqAIJ, 189117ab2063SBarry Smith MatTranspose_SeqAIJ, 1892cb5b572fSBarry Smith MatGetInfo_SeqAIJ, 1893cb5b572fSBarry Smith MatEqual_SeqAIJ, 1894cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 1895cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 1896cb5b572fSBarry Smith MatNorm_SeqAIJ, 1897cb5b572fSBarry Smith 0, 1898cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 189917ab2063SBarry Smith MatCompress_SeqAIJ, 1900cb5b572fSBarry Smith MatSetOption_SeqAIJ, 1901cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 1902cb5b572fSBarry Smith MatZeroRows_SeqAIJ, 1903cb5b572fSBarry Smith MatLUFactorSymbolic_SeqAIJ, 1904cb5b572fSBarry Smith MatLUFactorNumeric_SeqAIJ, 1905cb5b572fSBarry Smith 0, 1906cb5b572fSBarry Smith 0, 1907cb5b572fSBarry Smith MatGetSize_SeqAIJ, 1908cb5b572fSBarry Smith MatGetSize_SeqAIJ, 1909cb5b572fSBarry Smith MatGetOwnershipRange_SeqAIJ, 1910cb5b572fSBarry Smith MatILUFactorSymbolic_SeqAIJ, 1911cb5b572fSBarry Smith 0, 1912cb5b572fSBarry Smith 0, 1913cb5b572fSBarry Smith 0, 1914be6bf707SBarry Smith MatDuplicate_SeqAIJ, 1915cb5b572fSBarry Smith 0, 1916cb5b572fSBarry Smith 0, 1917cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 1918cb5b572fSBarry Smith 0, 1919cb5b572fSBarry Smith 0, 1920cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 1921cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 1922cb5b572fSBarry Smith MatGetValues_SeqAIJ, 1923cb5b572fSBarry Smith MatCopy_SeqAIJ, 1924f0b747eeSBarry Smith MatPrintHelp_SeqAIJ, 1925cb5b572fSBarry Smith MatScale_SeqAIJ, 1926cb5b572fSBarry Smith 0, 1927cb5b572fSBarry Smith 0, 19286945ee14SBarry Smith MatILUDTFactor_SeqAIJ, 19296945ee14SBarry Smith MatGetBlockSize_SeqAIJ, 19303b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 19313b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 19323b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 1933a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 1934a93ec695SBarry Smith MatFDColoringCreate_SeqAIJ, 19350513a670SBarry Smith MatColoringPatch_SeqAIJ, 19360513a670SBarry Smith 0, 1937cda55fadSBarry Smith MatPermute_SeqAIJ, 1938cda55fadSBarry Smith 0, 1939cda55fadSBarry Smith 0, 1940cda55fadSBarry Smith 0, 1941cda55fadSBarry Smith 0, 1942cda55fadSBarry Smith MatGetMaps_Petsc}; 194317ab2063SBarry Smith 194417ab2063SBarry Smith extern int MatUseSuperLU_SeqAIJ(Mat); 194517ab2063SBarry Smith extern int MatUseEssl_SeqAIJ(Mat); 194617ab2063SBarry Smith extern int MatUseDXML_SeqAIJ(Mat); 194717ab2063SBarry Smith 1948fb2e594dSBarry Smith EXTERN_C_BEGIN 19495615d1e5SSatish Balay #undef __FUNC__ 1950b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatSeqAIJSetColumnIndices_SeqAIJ" 195115091d37SBarry Smith 1952bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices) 1953bef8e0ddSBarry Smith { 1954bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 1955bef8e0ddSBarry Smith int i,nz,n; 1956bef8e0ddSBarry Smith 1957bef8e0ddSBarry Smith PetscFunctionBegin; 1958bef8e0ddSBarry Smith if (aij->indexshift) SETERRQ(1,1,"No support with 1 based indexing"); 1959bef8e0ddSBarry Smith 1960bef8e0ddSBarry Smith nz = aij->maxnz; 1961bef8e0ddSBarry Smith n = aij->n; 1962bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 1963bef8e0ddSBarry Smith aij->j[i] = indices[i]; 1964bef8e0ddSBarry Smith } 1965bef8e0ddSBarry Smith aij->nz = nz; 1966bef8e0ddSBarry Smith for (i=0; i<n; i++) { 1967bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 1968bef8e0ddSBarry Smith } 1969bef8e0ddSBarry Smith 1970bef8e0ddSBarry Smith PetscFunctionReturn(0); 1971bef8e0ddSBarry Smith } 1972fb2e594dSBarry Smith EXTERN_C_END 1973bef8e0ddSBarry Smith 1974bef8e0ddSBarry Smith #undef __FUNC__ 1975b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatSeqAIJSetColumnIndices" 1976bef8e0ddSBarry Smith /*@ 1977bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 1978bef8e0ddSBarry Smith in the matrix. 1979bef8e0ddSBarry Smith 1980bef8e0ddSBarry Smith Input Parameters: 1981bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 1982bef8e0ddSBarry Smith - indices - the column indices 1983bef8e0ddSBarry Smith 198415091d37SBarry Smith Level: advanced 198515091d37SBarry Smith 1986bef8e0ddSBarry Smith Notes: 1987bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 1988bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 1989bef8e0ddSBarry Smith of the MatSetValues() operation. 1990bef8e0ddSBarry Smith 1991bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 1992bef8e0ddSBarry Smith MatCreateSeqAIJ(). 1993bef8e0ddSBarry Smith 1994bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 1995bef8e0ddSBarry Smith 1996bef8e0ddSBarry Smith @*/ 1997bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices) 1998bef8e0ddSBarry Smith { 1999bef8e0ddSBarry Smith int ierr,(*f)(Mat,int *); 2000bef8e0ddSBarry Smith 2001bef8e0ddSBarry Smith PetscFunctionBegin; 2002bef8e0ddSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 2003549d3d68SSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void **)&f);CHKERRQ(ierr); 2004bef8e0ddSBarry Smith if (f) { 2005bef8e0ddSBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 2006bef8e0ddSBarry Smith } else { 2007bef8e0ddSBarry Smith SETERRQ(1,1,"Wrong type of matrix to set column indices"); 2008bef8e0ddSBarry Smith } 2009bef8e0ddSBarry Smith PetscFunctionReturn(0); 2010bef8e0ddSBarry Smith } 2011bef8e0ddSBarry Smith 2012be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 2013be6bf707SBarry Smith 2014fb2e594dSBarry Smith EXTERN_C_BEGIN 2015be6bf707SBarry Smith #undef __FUNC__ 2016b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatStoreValues_SeqAIJ" 2017be6bf707SBarry Smith int MatStoreValues_SeqAIJ(Mat mat) 2018be6bf707SBarry Smith { 2019be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2020549d3d68SSatish Balay int nz = aij->i[aij->m]+aij->indexshift,ierr; 2021be6bf707SBarry Smith 2022be6bf707SBarry Smith PetscFunctionBegin; 2023be6bf707SBarry Smith if (aij->nonew != 1) { 2024be6bf707SBarry Smith SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2025be6bf707SBarry Smith } 2026be6bf707SBarry Smith 2027be6bf707SBarry Smith /* allocate space for values if not already there */ 2028be6bf707SBarry Smith if (!aij->saved_values) { 2029be6bf707SBarry Smith aij->saved_values = (Scalar*)PetscMalloc(nz*sizeof(Scalar));CHKPTRQ(aij->saved_values); 2030be6bf707SBarry Smith } 2031be6bf707SBarry Smith 2032be6bf707SBarry Smith /* copy values over */ 2033549d3d68SSatish Balay ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr); 2034be6bf707SBarry Smith PetscFunctionReturn(0); 2035be6bf707SBarry Smith } 2036fb2e594dSBarry Smith EXTERN_C_END 2037be6bf707SBarry Smith 2038be6bf707SBarry Smith #undef __FUNC__ 2039b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatStoreValues" 2040be6bf707SBarry Smith /*@ 2041be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 2042be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2043be6bf707SBarry Smith nonlinear portion. 2044be6bf707SBarry Smith 2045be6bf707SBarry Smith Collect on Mat 2046be6bf707SBarry Smith 2047be6bf707SBarry Smith Input Parameters: 2048be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2049be6bf707SBarry Smith 205015091d37SBarry Smith Level: advanced 205115091d37SBarry Smith 2052be6bf707SBarry Smith Common Usage, with SNESSolve(): 2053be6bf707SBarry Smith $ Create Jacobian matrix 2054be6bf707SBarry Smith $ Set linear terms into matrix 2055be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 2056be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 2057be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 2058be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2059be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2060be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 2061be6bf707SBarry Smith $ In your Jacobian routine 2062be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2063be6bf707SBarry Smith $ Set nonlinear terms in matrix 2064be6bf707SBarry Smith 2065be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 2066be6bf707SBarry Smith $ // build linear portion of Jacobian 2067be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2068be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2069be6bf707SBarry Smith $ loop over nonlinear iterations 2070be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2071be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 2072be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 2073be6bf707SBarry Smith $ Solve linear system with Jacobian 2074be6bf707SBarry Smith $ endloop 2075be6bf707SBarry Smith 2076be6bf707SBarry Smith Notes: 2077be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 2078be6bf707SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before 2079be6bf707SBarry Smith calling this routine. 2080be6bf707SBarry Smith 2081be6bf707SBarry Smith .seealso: MatRetrieveValues() 2082be6bf707SBarry Smith 2083be6bf707SBarry Smith @*/ 2084be6bf707SBarry Smith int MatStoreValues(Mat mat) 2085be6bf707SBarry Smith { 2086be6bf707SBarry Smith int ierr,(*f)(Mat); 2087be6bf707SBarry Smith 2088be6bf707SBarry Smith PetscFunctionBegin; 2089be6bf707SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 2090be6bf707SBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix"); 2091be6bf707SBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix"); 2092be6bf707SBarry Smith 2093c5d6004cSBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void **)&f);CHKERRQ(ierr); 2094be6bf707SBarry Smith if (f) { 2095be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2096be6bf707SBarry Smith } else { 2097be6bf707SBarry Smith SETERRQ(1,1,"Wrong type of matrix to store values"); 2098be6bf707SBarry Smith } 2099be6bf707SBarry Smith PetscFunctionReturn(0); 2100be6bf707SBarry Smith } 2101be6bf707SBarry Smith 2102fb2e594dSBarry Smith EXTERN_C_BEGIN 2103be6bf707SBarry Smith #undef __FUNC__ 2104b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatRetrieveValues_SeqAIJ" 2105be6bf707SBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat) 2106be6bf707SBarry Smith { 2107be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2108549d3d68SSatish Balay int nz = aij->i[aij->m]+aij->indexshift,ierr; 2109be6bf707SBarry Smith 2110be6bf707SBarry Smith PetscFunctionBegin; 2111be6bf707SBarry Smith if (aij->nonew != 1) { 2112be6bf707SBarry Smith SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2113be6bf707SBarry Smith } 2114be6bf707SBarry Smith if (!aij->saved_values) { 2115be6bf707SBarry Smith SETERRQ(1,1,"Must call MatStoreValues(A);first"); 2116be6bf707SBarry Smith } 2117be6bf707SBarry Smith 2118be6bf707SBarry Smith /* copy values over */ 2119549d3d68SSatish Balay ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr); 2120be6bf707SBarry Smith PetscFunctionReturn(0); 2121be6bf707SBarry Smith } 2122fb2e594dSBarry Smith EXTERN_C_END 2123be6bf707SBarry Smith 2124be6bf707SBarry Smith #undef __FUNC__ 2125b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatRetrieveValues" 2126be6bf707SBarry Smith /*@ 2127be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 2128be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2129be6bf707SBarry Smith nonlinear portion. 2130be6bf707SBarry Smith 2131be6bf707SBarry Smith Collect on Mat 2132be6bf707SBarry Smith 2133be6bf707SBarry Smith Input Parameters: 2134be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2135be6bf707SBarry Smith 213615091d37SBarry Smith Level: advanced 213715091d37SBarry Smith 2138be6bf707SBarry Smith .seealso: MatStoreValues() 2139be6bf707SBarry Smith 2140be6bf707SBarry Smith @*/ 2141be6bf707SBarry Smith int MatRetrieveValues(Mat mat) 2142be6bf707SBarry Smith { 2143be6bf707SBarry Smith int ierr,(*f)(Mat); 2144be6bf707SBarry Smith 2145be6bf707SBarry Smith PetscFunctionBegin; 2146be6bf707SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 2147be6bf707SBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix"); 2148be6bf707SBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix"); 2149be6bf707SBarry Smith 2150c5d6004cSBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void **)&f);CHKERRQ(ierr); 2151be6bf707SBarry Smith if (f) { 2152be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2153be6bf707SBarry Smith } else { 2154be6bf707SBarry Smith SETERRQ(1,1,"Wrong type of matrix to retrieve values"); 2155be6bf707SBarry Smith } 2156be6bf707SBarry Smith PetscFunctionReturn(0); 2157be6bf707SBarry Smith } 2158be6bf707SBarry Smith 2159be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 2160cb5b572fSBarry Smith 2161bef8e0ddSBarry Smith #undef __FUNC__ 2162b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatCreateSeqAIJ" 216317ab2063SBarry Smith /*@C 2164682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 21650d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 21666e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 216751c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 21682bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 216917ab2063SBarry Smith 2170db81eaa0SLois Curfman McInnes Collective on MPI_Comm 2171db81eaa0SLois Curfman McInnes 217217ab2063SBarry Smith Input Parameters: 2173db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 217417ab2063SBarry Smith . m - number of rows 217517ab2063SBarry Smith . n - number of columns 217617ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 217751c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 21782bd5e0b2SLois Curfman McInnes (possibly different for each row) or PETSC_NULL 217917ab2063SBarry Smith 218017ab2063SBarry Smith Output Parameter: 2181416022c9SBarry Smith . A - the matrix 218217ab2063SBarry Smith 2183b259b22eSLois Curfman McInnes Notes: 218417ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 218517ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 21860002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 218744cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 218817ab2063SBarry Smith 218917ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2190a40aa06bSLois Curfman McInnes Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 21913d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 21926da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 219317ab2063SBarry Smith 2194682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 21954fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 2196682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 21976c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 21986c7ebb05SLois Curfman McInnes 21996c7ebb05SLois Curfman McInnes Options Database Keys: 2200db81eaa0SLois Curfman McInnes + -mat_aij_no_inode - Do not use inodes 2201db81eaa0SLois Curfman McInnes . -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5) 2202db81eaa0SLois Curfman McInnes - -mat_aij_oneindex - Internally use indexing starting at 1 2203db81eaa0SLois Curfman McInnes rather than 0. Note that when calling MatSetValues(), 2204db81eaa0SLois Curfman McInnes the user still MUST index entries starting at 0! 220517ab2063SBarry Smith 2206027ccd11SLois Curfman McInnes Level: intermediate 2207027ccd11SLois Curfman McInnes 220836db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 220936db0b34SBarry Smith 221017ab2063SBarry Smith @*/ 2211416022c9SBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,int *nnz,Mat *A) 221217ab2063SBarry Smith { 2213416022c9SBarry Smith Mat B; 2214416022c9SBarry Smith Mat_SeqAIJ *b; 2215f1af5d2fSBarry Smith int i,len,ierr,size; 2216f1af5d2fSBarry Smith PetscTruth flg; 22176945ee14SBarry Smith 22183a40ed3dSBarry Smith PetscFunctionBegin; 2219d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 2220a8c6a408SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Comm must be of size 1"); 2221d5d45c9bSBarry Smith 2222b73539f3SBarry Smith if (nz < -2) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"nz cannot be less than -2: value %d",nz); 2223b73539f3SBarry Smith if (nnz) { 2224b73539f3SBarry Smith for (i=0; i<m; i++) { 2225b73539f3SBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 2226b73539f3SBarry Smith } 2227b73539f3SBarry Smith } 2228b73539f3SBarry Smith 2229416022c9SBarry Smith *A = 0; 22303f1db9ecSBarry Smith PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,"Mat",comm,MatDestroy,MatView); 2231416022c9SBarry Smith PLogObjectCreate(B); 22320452661fSBarry Smith B->data = (void*)(b = PetscNew(Mat_SeqAIJ));CHKPTRQ(b); 2233549d3d68SSatish Balay ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr); 2234549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 2235e1311b90SBarry Smith B->ops->destroy = MatDestroy_SeqAIJ; 2236e1311b90SBarry Smith B->ops->view = MatView_SeqAIJ; 2237416022c9SBarry Smith B->factor = 0; 2238416022c9SBarry Smith B->lupivotthreshold = 1.0; 223990f02eecSBarry Smith B->mapping = 0; 2240f1af5d2fSBarry Smith ierr = OptionsGetDouble(PETSC_NULL,"-mat_lu_pivotthreshold",&B->lupivotthreshold,PETSC_NULL);CHKERRQ(ierr); 2241f1af5d2fSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-pc_ilu_preserve_row_sums",&b->ilu_preserve_row_sums);CHKERRQ(ierr); 2242416022c9SBarry Smith b->row = 0; 2243416022c9SBarry Smith b->col = 0; 224482bf6240SBarry Smith b->icol = 0; 2245416022c9SBarry Smith b->indexshift = 0; 2246b810aeb4SBarry Smith b->reallocs = 0; 224769957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_oneindex",&flg);CHKERRQ(ierr); 224869957df2SSatish Balay if (flg) b->indexshift = -1; 224917ab2063SBarry Smith 225044cd7ae7SLois Curfman McInnes b->m = m; B->m = m; B->M = m; 225144cd7ae7SLois Curfman McInnes b->n = n; B->n = n; B->N = n; 2252a5ae1ecdSBarry Smith 22534d197716SBarry Smith ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr); 22544d197716SBarry Smith ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr); 2255a5ae1ecdSBarry Smith 22560452661fSBarry Smith b->imax = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(b->imax); 2257f1e2ffcdSBarry Smith if (!nnz) { 22587b8455f0SLois Curfman McInnes if (nz == PETSC_DEFAULT) nz = 10; 22597b8455f0SLois Curfman McInnes else if (nz <= 0) nz = 1; 2260416022c9SBarry Smith for (i=0; i<m; i++) b->imax[i] = nz; 226117ab2063SBarry Smith nz = nz*m; 22623a40ed3dSBarry Smith } else { 226317ab2063SBarry Smith nz = 0; 2264416022c9SBarry Smith for (i=0; i<m; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 226517ab2063SBarry Smith } 226617ab2063SBarry Smith 226717ab2063SBarry Smith /* allocate the matrix space */ 2268416022c9SBarry Smith len = nz*(sizeof(int) + sizeof(Scalar)) + (b->m+1)*sizeof(int); 22690452661fSBarry Smith b->a = (Scalar*)PetscMalloc(len);CHKPTRQ(b->a); 2270416022c9SBarry Smith b->j = (int*)(b->a + nz); 2271549d3d68SSatish Balay ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr); 2272416022c9SBarry Smith b->i = b->j + nz; 2273f1e2ffcdSBarry Smith b->singlemalloc = PETSC_TRUE; 227436db0b34SBarry Smith b->freedata = PETSC_TRUE; 227517ab2063SBarry Smith 2276416022c9SBarry Smith b->i[0] = -b->indexshift; 227717ab2063SBarry Smith for (i=1; i<m+1; i++) { 2278416022c9SBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 227917ab2063SBarry Smith } 228017ab2063SBarry Smith 2281416022c9SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 22820452661fSBarry Smith b->ilen = (int*)PetscMalloc((m+1)*sizeof(int)); 2283f09e8eb9SSatish Balay PLogObjectMemory(B,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2284416022c9SBarry Smith for (i=0; i<b->m; i++) { b->ilen[i] = 0;} 228517ab2063SBarry Smith 2286416022c9SBarry Smith b->nz = 0; 2287416022c9SBarry Smith b->maxnz = nz; 2288f1e2ffcdSBarry Smith b->sorted = PETSC_FALSE; 228936db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 2290f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 2291416022c9SBarry Smith b->nonew = 0; 2292416022c9SBarry Smith b->diag = 0; 2293416022c9SBarry Smith b->solve_work = 0; 229471bd300dSLois Curfman McInnes b->spptr = 0; 2295b65db4caSBarry Smith b->inode.use = PETSC_TRUE; 2296754ec7b1SSatish Balay b->inode.node_count = 0; 2297754ec7b1SSatish Balay b->inode.size = 0; 22986c7ebb05SLois Curfman McInnes b->inode.limit = 5; 22996c7ebb05SLois Curfman McInnes b->inode.max_limit = 5; 2300be6bf707SBarry Smith b->saved_values = 0; 23014e220ebcSLois Curfman McInnes B->info.nz_unneeded = (double)b->maxnz; 2302d7f994e1SBarry Smith b->idiag = 0; 2303d7f994e1SBarry Smith b->ssor = 0; 2304f1e2ffcdSBarry Smith b->keepzeroedrows = PETSC_FALSE; 230517ab2063SBarry Smith 2306416022c9SBarry Smith *A = B; 23074e220ebcSLois Curfman McInnes 23084b14c69eSBarry Smith /* SuperLU is not currently supported through PETSc */ 2309aa482453SBarry Smith #if defined(PETSC_HAVE_SUPERLU) 231069957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_superlu",&flg);CHKERRQ(ierr); 231169957df2SSatish Balay if (flg) { ierr = MatUseSuperLU_SeqAIJ(B);CHKERRQ(ierr); } 23124b14c69eSBarry Smith #endif 231369957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_essl",&flg);CHKERRQ(ierr); 231469957df2SSatish Balay if (flg) { ierr = MatUseEssl_SeqAIJ(B);CHKERRQ(ierr); } 231569957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_dxml",&flg);CHKERRQ(ierr); 231669957df2SSatish Balay if (flg) { 2317a8c6a408SBarry Smith if (!b->indexshift) SETERRQ(PETSC_ERR_LIB,0,"need -mat_aij_oneindex with -mat_aij_dxml"); 2318416022c9SBarry Smith ierr = MatUseDXML_SeqAIJ(B);CHKERRQ(ierr); 231917ab2063SBarry Smith } 232069957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr); 232169957df2SSatish Balay if (flg) {ierr = MatPrintHelp(B);CHKERRQ(ierr); } 2322bef8e0ddSBarry Smith 2323f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C", 2324bef8e0ddSBarry Smith "MatSeqAIJSetColumnIndices_SeqAIJ", 2325*bc4b532fSSatish Balay MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 2326f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 2327be6bf707SBarry Smith "MatStoreValues_SeqAIJ", 2328*bc4b532fSSatish Balay MatStoreValues_SeqAIJ);CHKERRQ(ierr); 2329f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 2330be6bf707SBarry Smith "MatRetrieveValues_SeqAIJ", 2331*bc4b532fSSatish Balay MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 23323a40ed3dSBarry Smith PetscFunctionReturn(0); 233317ab2063SBarry Smith } 233417ab2063SBarry Smith 23355615d1e5SSatish Balay #undef __FUNC__ 2336b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatDuplicate_SeqAIJ" 2337be6bf707SBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 233817ab2063SBarry Smith { 2339416022c9SBarry Smith Mat C; 2340416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 2341bef8e0ddSBarry Smith int i,len,m = a->m,shift = a->indexshift,ierr; 234217ab2063SBarry Smith 23433a40ed3dSBarry Smith PetscFunctionBegin; 23444043dd9cSLois Curfman McInnes *B = 0; 23453f1db9ecSBarry Smith PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,"Mat",A->comm,MatDestroy,MatView); 2346416022c9SBarry Smith PLogObjectCreate(C); 23470452661fSBarry Smith C->data = (void*)(c = PetscNew(Mat_SeqAIJ));CHKPTRQ(c); 2348549d3d68SSatish Balay ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 2349e1311b90SBarry Smith C->ops->destroy = MatDestroy_SeqAIJ; 2350e1311b90SBarry Smith C->ops->view = MatView_SeqAIJ; 2351416022c9SBarry Smith C->factor = A->factor; 2352416022c9SBarry Smith c->row = 0; 2353416022c9SBarry Smith c->col = 0; 235482bf6240SBarry Smith c->icol = 0; 2355416022c9SBarry Smith c->indexshift = shift; 2356f1e2ffcdSBarry Smith c->keepzeroedrows = a->keepzeroedrows; 2357c456f294SBarry Smith C->assembled = PETSC_TRUE; 235817ab2063SBarry Smith 235944cd7ae7SLois Curfman McInnes c->m = C->m = a->m; 236044cd7ae7SLois Curfman McInnes c->n = C->n = a->n; 236144cd7ae7SLois Curfman McInnes C->M = a->m; 236244cd7ae7SLois Curfman McInnes C->N = a->n; 236317ab2063SBarry Smith 23640452661fSBarry Smith c->imax = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->imax); 23650452661fSBarry Smith c->ilen = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->ilen); 236617ab2063SBarry Smith for (i=0; i<m; i++) { 2367416022c9SBarry Smith c->imax[i] = a->imax[i]; 2368416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 236917ab2063SBarry Smith } 237017ab2063SBarry Smith 237117ab2063SBarry Smith /* allocate the matrix space */ 2372f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 2373416022c9SBarry Smith len = (m+1)*sizeof(int)+(a->i[m])*(sizeof(Scalar)+sizeof(int)); 23740452661fSBarry Smith c->a = (Scalar*)PetscMalloc(len);CHKPTRQ(c->a); 2375416022c9SBarry Smith c->j = (int*)(c->a + a->i[m] + shift); 2376416022c9SBarry Smith c->i = c->j + a->i[m] + shift; 2377549d3d68SSatish Balay ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));CHKERRQ(ierr); 237817ab2063SBarry Smith if (m > 0) { 2379549d3d68SSatish Balay ierr = PetscMemcpy(c->j,a->j,(a->i[m]+shift)*sizeof(int));CHKERRQ(ierr); 2380be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 2381549d3d68SSatish Balay ierr = PetscMemcpy(c->a,a->a,(a->i[m]+shift)*sizeof(Scalar));CHKERRQ(ierr); 2382be6bf707SBarry Smith } else { 2383549d3d68SSatish Balay ierr = PetscMemzero(c->a,(a->i[m]+shift)*sizeof(Scalar));CHKERRQ(ierr); 238417ab2063SBarry Smith } 238508480c60SBarry Smith } 238617ab2063SBarry Smith 2387f09e8eb9SSatish Balay PLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2388416022c9SBarry Smith c->sorted = a->sorted; 2389416022c9SBarry Smith c->roworiented = a->roworiented; 2390416022c9SBarry Smith c->nonew = a->nonew; 23917a743949SBarry Smith c->ilu_preserve_row_sums = a->ilu_preserve_row_sums; 2392be6bf707SBarry Smith c->saved_values = 0; 2393d7f994e1SBarry Smith c->idiag = 0; 2394d7f994e1SBarry Smith c->ssor = 0; 239536db0b34SBarry Smith c->ignorezeroentries = a->ignorezeroentries; 239636db0b34SBarry Smith c->freedata = PETSC_TRUE; 239717ab2063SBarry Smith 2398416022c9SBarry Smith if (a->diag) { 23990452661fSBarry Smith c->diag = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->diag); 2400416022c9SBarry Smith PLogObjectMemory(C,(m+1)*sizeof(int)); 240117ab2063SBarry Smith for (i=0; i<m; i++) { 2402416022c9SBarry Smith c->diag[i] = a->diag[i]; 240317ab2063SBarry Smith } 24043a40ed3dSBarry Smith } else c->diag = 0; 2405b65db4caSBarry Smith c->inode.use = a->inode.use; 24066c7ebb05SLois Curfman McInnes c->inode.limit = a->inode.limit; 24076c7ebb05SLois Curfman McInnes c->inode.max_limit = a->inode.max_limit; 2408754ec7b1SSatish Balay if (a->inode.size){ 2409daed632aSSatish Balay c->inode.size = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->inode.size); 2410754ec7b1SSatish Balay c->inode.node_count = a->inode.node_count; 2411549d3d68SSatish Balay ierr = PetscMemcpy(c->inode.size,a->inode.size,(m+1)*sizeof(int));CHKERRQ(ierr); 2412754ec7b1SSatish Balay } else { 2413754ec7b1SSatish Balay c->inode.size = 0; 2414754ec7b1SSatish Balay c->inode.node_count = 0; 2415754ec7b1SSatish Balay } 2416416022c9SBarry Smith c->nz = a->nz; 2417416022c9SBarry Smith c->maxnz = a->maxnz; 2418416022c9SBarry Smith c->solve_work = 0; 241976dd722bSSatish Balay c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 2420754ec7b1SSatish Balay 2421416022c9SBarry Smith *B = C; 24227b2a1423SBarry Smith ierr = FListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 24233a40ed3dSBarry Smith PetscFunctionReturn(0); 242417ab2063SBarry Smith } 242517ab2063SBarry Smith 24265615d1e5SSatish Balay #undef __FUNC__ 2427b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatLoad_SeqAIJ" 242819bcc07fSBarry Smith int MatLoad_SeqAIJ(Viewer viewer,MatType type,Mat *A) 242917ab2063SBarry Smith { 2430416022c9SBarry Smith Mat_SeqAIJ *a; 2431416022c9SBarry Smith Mat B; 243217699dbbSLois Curfman McInnes int i,nz,ierr,fd,header[4],size,*rowlengths = 0,M,N,shift; 2433bcd2baecSBarry Smith MPI_Comm comm; 243417ab2063SBarry Smith 24353a40ed3dSBarry Smith PetscFunctionBegin; 2436e864ced6SBarry Smith ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 2437d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 2438a8c6a408SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,0,"view must have one processor"); 243990ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 24400752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 2441a8c6a408SBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not matrix object in file"); 244217ab2063SBarry Smith M = header[1]; N = header[2]; nz = header[3]; 244317ab2063SBarry Smith 2444d64ed03dSBarry Smith if (nz < 0) { 2445a8c6a408SBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 2446d64ed03dSBarry Smith } 2447d64ed03dSBarry Smith 244817ab2063SBarry Smith /* read in row lengths */ 24490452661fSBarry Smith rowlengths = (int*)PetscMalloc(M*sizeof(int));CHKPTRQ(rowlengths); 24500752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 245117ab2063SBarry Smith 245217ab2063SBarry Smith /* create our matrix */ 2453416022c9SBarry Smith ierr = MatCreateSeqAIJ(comm,M,N,0,rowlengths,A);CHKERRQ(ierr); 2454416022c9SBarry Smith B = *A; 2455416022c9SBarry Smith a = (Mat_SeqAIJ*)B->data; 2456416022c9SBarry Smith shift = a->indexshift; 245717ab2063SBarry Smith 245817ab2063SBarry Smith /* read in column indices and adjust for Fortran indexing*/ 24590752156aSBarry Smith ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 246017ab2063SBarry Smith if (shift) { 246117ab2063SBarry Smith for (i=0; i<nz; i++) { 2462416022c9SBarry Smith a->j[i] += 1; 246317ab2063SBarry Smith } 246417ab2063SBarry Smith } 246517ab2063SBarry Smith 246617ab2063SBarry Smith /* read in nonzero values */ 24670752156aSBarry Smith ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 246817ab2063SBarry Smith 246917ab2063SBarry Smith /* set matrix "i" values */ 2470416022c9SBarry Smith a->i[0] = -shift; 247117ab2063SBarry Smith for (i=1; i<= M; i++) { 2472416022c9SBarry Smith a->i[i] = a->i[i-1] + rowlengths[i-1]; 2473416022c9SBarry Smith a->ilen[i-1] = rowlengths[i-1]; 247417ab2063SBarry Smith } 2475606d414cSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 247617ab2063SBarry Smith 24776d4a8577SBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24786d4a8577SBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24793a40ed3dSBarry Smith PetscFunctionReturn(0); 248017ab2063SBarry Smith } 248117ab2063SBarry Smith 24825615d1e5SSatish Balay #undef __FUNC__ 2483b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatEqual_SeqAIJ" 24848f6be9afSLois Curfman McInnes int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg) 24857264ac53SSatish Balay { 24867264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data; 24870f5bd95cSBarry Smith int ierr; 24887264ac53SSatish Balay 24893a40ed3dSBarry Smith PetscFunctionBegin; 2490a8c6a408SBarry Smith if (B->type !=MATSEQAIJ)SETERRQ(PETSC_ERR_ARG_INCOMP,0,"Matrices must be same type"); 24917264ac53SSatish Balay 24927264ac53SSatish Balay /* If the matrix dimensions are not equal,or no of nonzeros or shift */ 24937264ac53SSatish Balay if ((a->m != b->m) || (a->n !=b->n) ||(a->nz != b->nz)|| 2494bcd2baecSBarry Smith (a->indexshift != b->indexshift)) { 24953a40ed3dSBarry Smith *flg = PETSC_FALSE; PetscFunctionReturn(0); 2496bcd2baecSBarry Smith } 24977264ac53SSatish Balay 24987264ac53SSatish Balay /* if the a->i are the same */ 24990f5bd95cSBarry Smith ierr = PetscMemcmp(a->i,b->i,(a->m+1)*sizeof(int),flg);CHKERRQ(ierr); 25000f5bd95cSBarry Smith if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 25017264ac53SSatish Balay 25027264ac53SSatish Balay /* if a->j are the same */ 25030f5bd95cSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(int),flg);CHKERRQ(ierr); 25040f5bd95cSBarry Smith if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 2505bcd2baecSBarry Smith 2506bcd2baecSBarry Smith /* if a->a are the same */ 25070f5bd95cSBarry Smith ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(Scalar),flg);CHKERRQ(ierr); 25080f5bd95cSBarry Smith 25093a40ed3dSBarry Smith PetscFunctionReturn(0); 25107264ac53SSatish Balay 25117264ac53SSatish Balay } 251236db0b34SBarry Smith 251336db0b34SBarry Smith #undef __FUNC__ 2514b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatCreateSeqAIJWithArrays" 251536db0b34SBarry Smith /*@C 251636db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 251736db0b34SBarry Smith provided by the user. 251836db0b34SBarry Smith 251936db0b34SBarry Smith Coolective on MPI_Comm 252036db0b34SBarry Smith 252136db0b34SBarry Smith Input Parameters: 252236db0b34SBarry Smith + comm - must be an MPI communicator of size 1 252336db0b34SBarry Smith . m - number of rows 252436db0b34SBarry Smith . n - number of columns 252536db0b34SBarry Smith . i - row indices 252636db0b34SBarry Smith . j - column indices 252736db0b34SBarry Smith - a - matrix values 252836db0b34SBarry Smith 252936db0b34SBarry Smith Output Parameter: 253036db0b34SBarry Smith . mat - the matrix 253136db0b34SBarry Smith 253236db0b34SBarry Smith Level: intermediate 253336db0b34SBarry Smith 253436db0b34SBarry Smith Notes: 25350551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 253636db0b34SBarry Smith once the matrix is destroyed 253736db0b34SBarry Smith 253836db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 253936db0b34SBarry Smith 254036db0b34SBarry Smith The i and j indices can be either 0- or 1 based 254136db0b34SBarry Smith 254236db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ() 254336db0b34SBarry Smith 254436db0b34SBarry Smith @*/ 254536db0b34SBarry Smith int MatCreateSeqAIJWithArrays(MPI_Comm comm,int m,int n,int* i,int*j,Scalar *a,Mat *mat) 254636db0b34SBarry Smith { 254736db0b34SBarry Smith int ierr,ii; 254836db0b34SBarry Smith Mat_SeqAIJ *aij; 254936db0b34SBarry Smith 255036db0b34SBarry Smith PetscFunctionBegin; 255136db0b34SBarry Smith ierr = MatCreateSeqAIJ(comm,m,n,0,0,mat);CHKERRQ(ierr); 255236db0b34SBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 255336db0b34SBarry Smith ierr = PetscFree(aij->a);CHKERRQ(ierr); 255436db0b34SBarry Smith 255536db0b34SBarry Smith if (i[0] == 1) { 255636db0b34SBarry Smith aij->indexshift = -1; 255736db0b34SBarry Smith } else if (i[0]) { 255836db0b34SBarry Smith SETERRQ(1,1,"i (row indices) do not start with 0 or 1"); 255936db0b34SBarry Smith } 256036db0b34SBarry Smith aij->i = i; 256136db0b34SBarry Smith aij->j = j; 256236db0b34SBarry Smith aij->a = a; 256336db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 256436db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 256536db0b34SBarry Smith aij->freedata = PETSC_FALSE; 256636db0b34SBarry Smith 256736db0b34SBarry Smith for (ii=0; ii<m; ii++) { 256836db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 256936db0b34SBarry Smith #if defined(PETSC_BOPT_g) 257036db0b34SBarry Smith if (i[ii+1] - i[i] < 0) SETERRQ2(1,1,"Negative row length in i (row indices) row = %d length = %d",ii,i[ii+1] - i[ii]); 257136db0b34SBarry Smith #endif 257236db0b34SBarry Smith } 257336db0b34SBarry Smith #if defined(PETSC_BOPT_g) 257436db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 257536db0b34SBarry Smith if (j[ii] < -aij->indexshift) SETERRQ2(1,1,"Negative column index at location = %d index = %d",ii,j[ii]); 257636db0b34SBarry Smith if (j[ii] > n - 1 -aij->indexshift) SETERRQ2(1,1,"Column index to large at location = %d index = %d",ii,j[ii]); 257736db0b34SBarry Smith } 257836db0b34SBarry Smith #endif 257936db0b34SBarry Smith 2580b65db4caSBarry Smith /* changes indices to start at 0 */ 2581b65db4caSBarry Smith if (i[0]) { 2582b65db4caSBarry Smith aij->indexshift = 0; 2583b65db4caSBarry Smith for (ii=0; ii<m; ii++) { 2584b65db4caSBarry Smith i[ii]--; 2585b65db4caSBarry Smith } 2586b65db4caSBarry Smith for (ii=0; ii<i[m]; ii++) { 2587b65db4caSBarry Smith j[ii]--; 2588b65db4caSBarry Smith } 2589b65db4caSBarry Smith } 2590b65db4caSBarry Smith 2591b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2592b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 259336db0b34SBarry Smith PetscFunctionReturn(0); 259436db0b34SBarry Smith } 259536db0b34SBarry Smith 259636db0b34SBarry Smith 259736db0b34SBarry Smith 2598