xref: /petsc/src/mat/impls/aij/seq/aij.c (revision ca44d042d6f86ecc01fa7a52a5213a5161f95f53)
1*ca44d042SBarry Smith /*$Id: aij.c,v 1.348 2000/05/09 03:22:41 bsmith Exp bsmith $*/
2d5d45c9bSBarry Smith /*
33369ce9aSBarry Smith     Defines the basic matrix operations for the AIJ (compressed row)
4d5d45c9bSBarry Smith   matrix storage format.
5d5d45c9bSBarry Smith */
63369ce9aSBarry Smith 
7e090d566SSatish Balay #include "petscsys.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"
120a835dfdSSatish Balay #include "petscbt.h"
1317ab2063SBarry Smith 
14a2ce50c7SBarry Smith 
15*ca44d042SBarry Smith EXTERN int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**);
1617ab2063SBarry Smith 
175615d1e5SSatish Balay #undef __FUNC__
18*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatGetRowIJ_SeqAIJ"></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__
51*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatRestoreRowIJ_SeqAIJ"></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__
67*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatGetColumnIJ_SeqAIJ"></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__
108*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatRestoreColumnIJ_SeqAIJ"></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__
125*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatSetValues_SeqAIJ"></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;
173*ca44d042SBarry Smith       else if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero at (%d,%d) in the matrix",row,col);
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 
179*ca44d042SBarry Smith         if (nonew == -2) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero at (%d,%d) in the matrix requiring new malloc()",row,col);
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__
227*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatGetValues_SeqAIJ"></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];
238*ca44d042SBarry Smith     if (row < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row: %d",row);
239*ca44d042SBarry Smith     if (row >= a->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large: %d",row);
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 */
243*ca44d042SBarry Smith       if (in[l] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column: %d",in[l]);
244*ca44d042SBarry Smith       if (in[l] >= a->n) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large: %d",in[l]);
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__
268*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatView_SeqAIJ_Binary"></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__
304*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatView_SeqAIJ_ASCII"></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__
465*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatView_SeqAIJ_Draw_Zoom"></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__
557*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatView_SeqAIJ_Draw"></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__
581*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatView_SeqAIJ"></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 
607*ca44d042SBarry Smith EXTERN int Mat_AIJ_CheckInode(Mat);
6085615d1e5SSatish Balay #undef __FUNC__
609*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatAssemblyEnd_SeqAIJ"></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__
665*ca44d042SBarry Smith #define __FUNC__ /*<a name="atZeroEntries_SeqAIJ"></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__
677*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatDestroy_SeqAIJ"></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__
729*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatCompress_SeqAIJ"></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__
737*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatSetOption_SeqAIJ"></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__
775*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatGetDiagonal_SeqAIJ"></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 
7995615d1e5SSatish Balay #undef __FUNC__
800*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatMultTranspose_SeqAIJ"></a>*/"MatMultTranspose_SeqAIJ"
8017c922b88SBarry Smith int MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
80217ab2063SBarry Smith {
803416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
804f1af5d2fSBarry Smith   Scalar     *x,*y,*v,alpha,zero = 0.0;
805e1311b90SBarry Smith   int        ierr,m = a->m,n,i,*idx,shift = a->indexshift;
80617ab2063SBarry Smith 
8073a40ed3dSBarry Smith   PetscFunctionBegin;
808f1af5d2fSBarry Smith   ierr = VecSet(&zero,yy);CHKERRQ(ierr);
809e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
810e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
81117ab2063SBarry Smith   y = y + shift; /* shift for Fortran start by 1 indexing */
81217ab2063SBarry Smith   for (i=0; i<m; i++) {
813416022c9SBarry Smith     idx   = a->j + a->i[i] + shift;
814416022c9SBarry Smith     v     = a->a + a->i[i] + shift;
815416022c9SBarry Smith     n     = a->i[i+1] - a->i[i];
81617ab2063SBarry Smith     alpha = x[i];
81717ab2063SBarry Smith     while (n-->0) {y[*idx++] += alpha * *v++;}
81817ab2063SBarry Smith   }
819416022c9SBarry Smith   PLogFlops(2*a->nz - a->n);
820e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
821e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8223a40ed3dSBarry Smith   PetscFunctionReturn(0);
82317ab2063SBarry Smith }
824d5d45c9bSBarry Smith 
8255615d1e5SSatish Balay #undef __FUNC__
826*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatMultTransposeAdd_SeqAIJ"></a>*/"MatMultTransposeAdd_SeqAIJ"
8277c922b88SBarry Smith int MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
82817ab2063SBarry Smith {
829416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
83017ab2063SBarry Smith   Scalar     *x,*y,*v,alpha;
831e1311b90SBarry Smith   int        ierr,m = a->m,n,i,*idx,shift = a->indexshift;
83217ab2063SBarry Smith 
8333a40ed3dSBarry Smith   PetscFunctionBegin;
8342e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
835e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
836e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
83717ab2063SBarry Smith   y = y + shift; /* shift for Fortran start by 1 indexing */
83817ab2063SBarry Smith   for (i=0; i<m; i++) {
839416022c9SBarry Smith     idx   = a->j + a->i[i] + shift;
840416022c9SBarry Smith     v     = a->a + a->i[i] + shift;
841416022c9SBarry Smith     n     = a->i[i+1] - a->i[i];
84217ab2063SBarry Smith     alpha = x[i];
84317ab2063SBarry Smith     while (n-->0) {y[*idx++] += alpha * *v++;}
84417ab2063SBarry Smith   }
84590f02eecSBarry Smith   PLogFlops(2*a->nz);
846e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
847e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8483a40ed3dSBarry Smith   PetscFunctionReturn(0);
84917ab2063SBarry Smith }
85017ab2063SBarry Smith 
8515615d1e5SSatish Balay #undef __FUNC__
852*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatMult_SeqAIJ"></a>*/"MatMult_SeqAIJ"
85344cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
85417ab2063SBarry Smith {
855416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
85617ab2063SBarry Smith   Scalar     *x,*y,*v,sum;
857e1311b90SBarry Smith   int        ierr,m = a->m,*idx,shift = a->indexshift,*ii;
858aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
859e36a17ebSSatish Balay   int        n,i,jrow,j;
860e36a17ebSSatish Balay #endif
86117ab2063SBarry Smith 
862aa482453SBarry Smith #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
863fee21e36SBarry Smith #pragma disjoint(*x,*y,*v)
864fee21e36SBarry Smith #endif
865fee21e36SBarry Smith 
8663a40ed3dSBarry Smith   PetscFunctionBegin;
867e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
868e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
86917ab2063SBarry Smith   x    = x + shift;    /* shift for Fortran start by 1 indexing */
870416022c9SBarry Smith   idx  = a->j;
871d64ed03dSBarry Smith   v    = a->a;
872416022c9SBarry Smith   ii   = a->i;
873aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
87429b5ca8aSSatish Balay   fortranmultaij_(&m,x,ii,idx+shift,v+shift,y);
8758d195f9aSBarry Smith #else
876d64ed03dSBarry Smith   v    += shift; /* shift for Fortran start by 1 indexing */
877d64ed03dSBarry Smith   idx  += shift;
87817ab2063SBarry Smith   for (i=0; i<m; i++) {
8799ea0dfa2SSatish Balay     jrow = ii[i];
8809ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
88117ab2063SBarry Smith     sum  = 0.0;
8829ea0dfa2SSatish Balay     for (j=0; j<n; j++) {
8839ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
8849ea0dfa2SSatish Balay      }
88517ab2063SBarry Smith     y[i] = sum;
88617ab2063SBarry Smith   }
8878d195f9aSBarry Smith #endif
888416022c9SBarry Smith   PLogFlops(2*a->nz - m);
889e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
890e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8913a40ed3dSBarry Smith   PetscFunctionReturn(0);
89217ab2063SBarry Smith }
89317ab2063SBarry Smith 
8945615d1e5SSatish Balay #undef __FUNC__
895*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatMultAdd_SeqAIJ"></a>*/"MatMultAdd_SeqAIJ"
89644cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
89717ab2063SBarry Smith {
898416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
89917ab2063SBarry Smith   Scalar     *x,*y,*z,*v,sum;
900e1311b90SBarry Smith   int        ierr,m = a->m,*idx,shift = a->indexshift,*ii;
901aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
902e36a17ebSSatish Balay   int        n,i,jrow,j;
903e36a17ebSSatish Balay #endif
9049ea0dfa2SSatish Balay 
9053a40ed3dSBarry Smith   PetscFunctionBegin;
906e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
907e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9082e8a6d31SBarry Smith   if (zz != yy) {
909e1311b90SBarry Smith     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
9102e8a6d31SBarry Smith   } else {
9112e8a6d31SBarry Smith     z = y;
9122e8a6d31SBarry Smith   }
91317ab2063SBarry Smith   x    = x + shift; /* shift for Fortran start by 1 indexing */
914cddf8d76SBarry Smith   idx  = a->j;
915d64ed03dSBarry Smith   v    = a->a;
916cddf8d76SBarry Smith   ii   = a->i;
917aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
91829b5ca8aSSatish Balay   fortranmultaddaij_(&m,x,ii,idx+shift,v+shift,y,z);
91902ab625aSSatish Balay #else
920d64ed03dSBarry Smith   v   += shift; /* shift for Fortran start by 1 indexing */
921d64ed03dSBarry Smith   idx += shift;
92217ab2063SBarry Smith   for (i=0; i<m; i++) {
9239ea0dfa2SSatish Balay     jrow = ii[i];
9249ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
92517ab2063SBarry Smith     sum  = y[i];
9269ea0dfa2SSatish Balay     for (j=0; j<n; j++) {
9279ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
9289ea0dfa2SSatish Balay      }
92917ab2063SBarry Smith     z[i] = sum;
93017ab2063SBarry Smith   }
93102ab625aSSatish Balay #endif
932416022c9SBarry Smith   PLogFlops(2*a->nz);
933e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
934e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9352e8a6d31SBarry Smith   if (zz != yy) {
936e1311b90SBarry Smith     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
9372e8a6d31SBarry Smith   }
9383a40ed3dSBarry Smith   PetscFunctionReturn(0);
93917ab2063SBarry Smith }
94017ab2063SBarry Smith 
94117ab2063SBarry Smith /*
94217ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
94317ab2063SBarry Smith */
9445615d1e5SSatish Balay #undef __FUNC__
945*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatMarkDiagonal_SeqAIJ"></a>*/"MatMarkDiagonal_SeqAIJ"
946f1e2ffcdSBarry Smith int MatMarkDiagonal_SeqAIJ(Mat A)
94717ab2063SBarry Smith {
948416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
949416022c9SBarry Smith   int        i,j,*diag,m = a->m,shift = a->indexshift;
95017ab2063SBarry Smith 
9513a40ed3dSBarry Smith   PetscFunctionBegin;
952f1e2ffcdSBarry Smith   if (a->diag) PetscFunctionReturn(0);
953f1e2ffcdSBarry Smith 
9540452661fSBarry Smith   diag = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(diag);
955416022c9SBarry Smith   PLogObjectMemory(A,(m+1)*sizeof(int));
956416022c9SBarry Smith   for (i=0; i<a->m; i++) {
95735b0346bSBarry Smith     diag[i] = a->i[i+1];
958416022c9SBarry Smith     for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
959416022c9SBarry Smith       if (a->j[j]+shift == i) {
96017ab2063SBarry Smith         diag[i] = j - shift;
96117ab2063SBarry Smith         break;
96217ab2063SBarry Smith       }
96317ab2063SBarry Smith     }
96417ab2063SBarry Smith   }
965416022c9SBarry Smith   a->diag = diag;
9663a40ed3dSBarry Smith   PetscFunctionReturn(0);
96717ab2063SBarry Smith }
96817ab2063SBarry Smith 
969be5855fcSBarry Smith /*
970be5855fcSBarry Smith      Checks for missing diagonals
971be5855fcSBarry Smith */
972be5855fcSBarry Smith #undef __FUNC__
973*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatMissingDiagonal_SeqAIJ"></a>*/"MatMissingDiagonal_SeqAIJ"
974f1e2ffcdSBarry Smith int MatMissingDiagonal_SeqAIJ(Mat A)
975be5855fcSBarry Smith {
976be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
977f1e2ffcdSBarry Smith   int        *diag,*jj = a->j,i,shift = a->indexshift,ierr;
978be5855fcSBarry Smith 
979be5855fcSBarry Smith   PetscFunctionBegin;
980f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
981f1e2ffcdSBarry Smith   diag = a->diag;
982be5855fcSBarry Smith   for (i=0; i<a->m; i++) {
983be5855fcSBarry Smith     if (jj[diag[i]+shift] != i-shift) {
984be5855fcSBarry Smith       SETERRQ1(1,1,"Matrix is missing diagonal number %d",i);
985be5855fcSBarry Smith     }
986be5855fcSBarry Smith   }
987be5855fcSBarry Smith   PetscFunctionReturn(0);
988be5855fcSBarry Smith }
989be5855fcSBarry Smith 
9905615d1e5SSatish Balay #undef __FUNC__
991*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatRelax_SeqAIJ"></a>*/"MatRelax_SeqAIJ"
99236db0b34SBarry Smith int MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,int its,Vec xx)
99317ab2063SBarry Smith {
994416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
995d6ed3216SSatish Balay   Scalar     *x,*b,*bs, d,*xs,sum,*v = a->a,*t=0,scale,*ts,*xb,*idiag=0;
996d5d45c9bSBarry Smith   int        ierr,*idx,*diag,n = a->n,m = a->m,i,shift = a->indexshift;
99717ab2063SBarry Smith 
9983a40ed3dSBarry Smith   PetscFunctionBegin;
999e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
1000fb2e594dSBarry Smith   if (xx != bb) {
1001e1311b90SBarry Smith     ierr = VecGetArray(bb,&b);CHKERRQ(ierr);
1002fb2e594dSBarry Smith   } else {
1003fb2e594dSBarry Smith     b = x;
1004fb2e594dSBarry Smith   }
1005fb2e594dSBarry Smith 
1006f1e2ffcdSBarry Smith   if (!a->diag) {ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);}
1007416022c9SBarry Smith   diag = a->diag;
1008416022c9SBarry Smith   xs   = x + shift; /* shifted by one for index start of a or a->j*/
100917ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
101017ab2063SBarry Smith    /* apply (U + D/omega) to the vector */
101117ab2063SBarry Smith     bs = b + shift;
101217ab2063SBarry Smith     for (i=0; i<m; i++) {
1013416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1014416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1015488ecbafSBarry Smith 	PLogFlops(2*n-1);
1016416022c9SBarry Smith         idx  = a->j + diag[i] + (!shift);
1017416022c9SBarry Smith         v    = a->a + diag[i] + (!shift);
101817ab2063SBarry Smith         sum  = b[i]*d/omega;
101917ab2063SBarry Smith         SPARSEDENSEDOT(sum,bs,v,idx,n);
102017ab2063SBarry Smith         x[i] = sum;
102117ab2063SBarry Smith     }
1022cb5b572fSBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1023fb2e594dSBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
10243a40ed3dSBarry Smith     PetscFunctionReturn(0);
102517ab2063SBarry Smith   }
1026c783ea89SBarry Smith 
1027c783ea89SBarry Smith   /* setup workspace for Eisenstat */
1028c783ea89SBarry Smith   if (flag & SOR_EISENSTAT) {
1029c783ea89SBarry Smith     if (!a->idiag) {
1030c783ea89SBarry Smith       a->idiag = (Scalar*)PetscMalloc(2*m*sizeof(Scalar));CHKPTRQ(a->idiag);
1031c783ea89SBarry Smith       a->ssor  = a->idiag + m;
1032c783ea89SBarry Smith       v        = a->a;
1033c783ea89SBarry Smith       for (i=0; i<m; i++) { a->idiag[i] = 1.0/v[diag[i]];}
1034c783ea89SBarry Smith     }
1035c783ea89SBarry Smith     t     = a->ssor;
1036c783ea89SBarry Smith     idiag = a->idiag;
1037c783ea89SBarry Smith   }
1038fc3d8934SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1039fc3d8934SBarry Smith     U is upper triangular, E is diagonal; This routine applies
1040fc3d8934SBarry Smith 
1041fc3d8934SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
1042fc3d8934SBarry Smith 
1043fc3d8934SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
1044fc3d8934SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
104548af12d7SBarry Smith     is the relaxation factor.
1046fc3d8934SBarry Smith     */
1047fc3d8934SBarry Smith 
104848af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
1049*ca44d042SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"SOR_APPLY_LOWER is not implemented");
105048af12d7SBarry Smith   } else if ((flag & SOR_EISENSTAT) && omega == 1.0 && shift == 0 && fshift == 0.0) {
105148af12d7SBarry Smith     /* special case for omega = 1.0 saves flops and some integer ops */
1052733d66baSBarry Smith     Scalar *v2;
105348af12d7SBarry Smith 
1054733d66baSBarry Smith     v2    = a->a;
1055fc3d8934SBarry Smith     /*  x = (E + U)^{-1} b */
1056fc3d8934SBarry Smith     for (i=m-1; i>=0; i--) {
1057fc3d8934SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1058fc3d8934SBarry Smith       idx  = a->j + diag[i] + 1;
1059fc3d8934SBarry Smith       v    = a->a + diag[i] + 1;
1060fc3d8934SBarry Smith       sum  = b[i];
1061fc3d8934SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
1062b4632166SBarry Smith       x[i] = sum*idiag[i];
1063fc3d8934SBarry Smith 
1064fc3d8934SBarry Smith       /*  t = b - (2*E - D)x */
1065733d66baSBarry Smith       t[i] = b[i] - (v2[diag[i]])*x[i];
1066733d66baSBarry Smith     }
1067fc3d8934SBarry Smith 
1068fc3d8934SBarry Smith     /*  t = (E + L)^{-1}t */
1069fc3d8934SBarry Smith     diag = a->diag;
1070fc3d8934SBarry Smith     for (i=0; i<m; i++) {
1071fc3d8934SBarry Smith       n    = diag[i] - a->i[i];
1072fc3d8934SBarry Smith       idx  = a->j + a->i[i];
1073fc3d8934SBarry Smith       v    = a->a + a->i[i];
1074fc3d8934SBarry Smith       sum  = t[i];
1075fc3d8934SBarry Smith       SPARSEDENSEMDOT(sum,t,v,idx,n);
1076b4632166SBarry Smith       t[i]  = sum*idiag[i];
1077fc3d8934SBarry Smith 
1078fc3d8934SBarry Smith       /*  x = x + t */
1079733d66baSBarry Smith       x[i] += t[i];
1080733d66baSBarry Smith     }
1081733d66baSBarry Smith 
1082a4d9cbf6SBarry Smith     PLogFlops(3*m-1 + 2*a->nz);
1083fc3d8934SBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1084fc3d8934SBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
1085fc3d8934SBarry Smith     PetscFunctionReturn(0);
10863a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
108717ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
108817ab2063SBarry Smith     U is upper triangular, E is diagonal; This routine applies
108917ab2063SBarry Smith 
109017ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
109117ab2063SBarry Smith 
109217ab2063SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
109317ab2063SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
109417ab2063SBarry Smith     is the relaxation factor.
109517ab2063SBarry Smith     */
109617ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
109717ab2063SBarry Smith 
109817ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
109917ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1100416022c9SBarry Smith       d    = fshift + a->a[diag[i] + shift];
1101416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1102416022c9SBarry Smith       idx  = a->j + diag[i] + (!shift);
1103416022c9SBarry Smith       v    = a->a + diag[i] + (!shift);
110417ab2063SBarry Smith       sum  = b[i];
110517ab2063SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
110617ab2063SBarry Smith       x[i] = omega*(sum/d);
110717ab2063SBarry Smith     }
110817ab2063SBarry Smith 
110917ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1110416022c9SBarry Smith     v = a->a;
111117ab2063SBarry Smith     for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++ + shift])*x[i]; }
111217ab2063SBarry Smith 
111317ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1114416022c9SBarry Smith     ts = t + shift; /* shifted by one for index start of a or a->j*/
1115416022c9SBarry Smith     diag = a->diag;
111617ab2063SBarry Smith     for (i=0; i<m; i++) {
1117416022c9SBarry Smith       d    = fshift + a->a[diag[i]+shift];
1118416022c9SBarry Smith       n    = diag[i] - a->i[i];
1119416022c9SBarry Smith       idx  = a->j + a->i[i] + shift;
1120416022c9SBarry Smith       v    = a->a + a->i[i] + shift;
112117ab2063SBarry Smith       sum  = t[i];
112217ab2063SBarry Smith       SPARSEDENSEMDOT(sum,ts,v,idx,n);
112317ab2063SBarry Smith       t[i] = omega*(sum/d);
1124733d66baSBarry Smith       /*  x = x + t */
1125733d66baSBarry Smith       x[i] += t[i];
112617ab2063SBarry Smith     }
112717ab2063SBarry Smith 
1128c783ea89SBarry Smith     PLogFlops(6*m-1 + 2*a->nz);
1129cb5b572fSBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1130fb2e594dSBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
11313a40ed3dSBarry Smith     PetscFunctionReturn(0);
113217ab2063SBarry Smith   }
113317ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
113417ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
113517ab2063SBarry Smith       for (i=0; i<m; i++) {
1136416022c9SBarry Smith         d    = fshift + a->a[diag[i]+shift];
1137416022c9SBarry Smith         n    = diag[i] - a->i[i];
1138488ecbafSBarry Smith 	PLogFlops(2*n-1);
1139416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1140416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
114117ab2063SBarry Smith         sum  = b[i];
114217ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
114317ab2063SBarry Smith         x[i] = omega*(sum/d);
114417ab2063SBarry Smith       }
114517ab2063SBarry Smith       xb = x;
11463a40ed3dSBarry Smith     } else xb = b;
114717ab2063SBarry Smith     if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) &&
114817ab2063SBarry Smith         (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) {
114917ab2063SBarry Smith       for (i=0; i<m; i++) {
1150416022c9SBarry Smith         x[i] *= a->a[diag[i]+shift];
115117ab2063SBarry Smith       }
1152488ecbafSBarry Smith       PLogFlops(m);
115317ab2063SBarry Smith     }
115417ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
115517ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1156416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1157416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1158488ecbafSBarry Smith 	PLogFlops(2*n-1);
1159416022c9SBarry Smith         idx  = a->j + diag[i] + (!shift);
1160416022c9SBarry Smith         v    = a->a + diag[i] + (!shift);
116117ab2063SBarry Smith         sum  = xb[i];
116217ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
116317ab2063SBarry Smith         x[i] = omega*(sum/d);
116417ab2063SBarry Smith       }
116517ab2063SBarry Smith     }
116617ab2063SBarry Smith     its--;
116717ab2063SBarry Smith   }
116817ab2063SBarry Smith   while (its--) {
116917ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
117017ab2063SBarry Smith       for (i=0; i<m; i++) {
1171416022c9SBarry Smith         d    = fshift + a->a[diag[i]+shift];
1172416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1173488ecbafSBarry Smith 	PLogFlops(2*n-1);
1174416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1175416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
117617ab2063SBarry Smith         sum  = b[i];
117717ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
11787e33a6baSBarry Smith         x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d;
117917ab2063SBarry Smith       }
118017ab2063SBarry Smith     }
118117ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
118217ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1183416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1184416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1185488ecbafSBarry Smith 	PLogFlops(2*n-1);
1186416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1187416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
118817ab2063SBarry Smith         sum  = b[i];
118917ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
11907e33a6baSBarry Smith         x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d;
119117ab2063SBarry Smith       }
119217ab2063SBarry Smith     }
119317ab2063SBarry Smith   }
1194cb5b572fSBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1195fb2e594dSBarry Smith   if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
11963a40ed3dSBarry Smith   PetscFunctionReturn(0);
119717ab2063SBarry Smith }
119817ab2063SBarry Smith 
11995615d1e5SSatish Balay #undef __FUNC__
1200*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatGetInfo_SeqAIJ"></a>*/"MatGetInfo_SeqAIJ"
12018f6be9afSLois Curfman McInnes int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
120217ab2063SBarry Smith {
1203416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
12044e220ebcSLois Curfman McInnes 
12053a40ed3dSBarry Smith   PetscFunctionBegin;
12064e220ebcSLois Curfman McInnes   info->rows_global    = (double)a->m;
12074e220ebcSLois Curfman McInnes   info->columns_global = (double)a->n;
12084e220ebcSLois Curfman McInnes   info->rows_local     = (double)a->m;
12094e220ebcSLois Curfman McInnes   info->columns_local  = (double)a->n;
12104e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
12114e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
12124e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
12134e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
12144e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
12154e220ebcSLois Curfman McInnes   info->mallocs        = (double)a->reallocs;
12164e220ebcSLois Curfman McInnes   info->memory         = A->mem;
12174e220ebcSLois Curfman McInnes   if (A->factor) {
12184e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
12194e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
12204e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
12214e220ebcSLois Curfman McInnes   } else {
12224e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
12234e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
12244e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
12254e220ebcSLois Curfman McInnes   }
12263a40ed3dSBarry Smith   PetscFunctionReturn(0);
122717ab2063SBarry Smith }
122817ab2063SBarry Smith 
1229*ca44d042SBarry Smith EXTERN int MatLUFactorSymbolic_SeqAIJ(Mat,IS,IS,PetscReal,Mat*);
1230*ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqAIJ(Mat,Mat*);
1231*ca44d042SBarry Smith EXTERN int MatLUFactor_SeqAIJ(Mat,IS,IS,PetscReal);
1232*ca44d042SBarry Smith EXTERN int MatSolve_SeqAIJ(Mat,Vec,Vec);
1233*ca44d042SBarry Smith EXTERN int MatSolveAdd_SeqAIJ(Mat,Vec,Vec,Vec);
1234*ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqAIJ(Mat,Vec,Vec);
1235*ca44d042SBarry Smith EXTERN int MatSolveTransposeAdd_SeqAIJ(Mat,Vec,Vec,Vec);
123617ab2063SBarry Smith 
12375615d1e5SSatish Balay #undef __FUNC__
1238e7592fafSBarry Smith #define __FUNC__ /*<a name="MatZeroRows_SeqAIJ"></a>*/"MatZeroRows_SeqAIJ"
12398f6be9afSLois Curfman McInnes int MatZeroRows_SeqAIJ(Mat A,IS is,Scalar *diag)
124017ab2063SBarry Smith {
1241416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1242416022c9SBarry Smith   int         i,ierr,N,*rows,m = a->m - 1,shift = a->indexshift;
124317ab2063SBarry Smith 
12443a40ed3dSBarry Smith   PetscFunctionBegin;
124577c4ece6SBarry Smith   ierr = ISGetSize(is,&N);CHKERRQ(ierr);
124617ab2063SBarry Smith   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
1247f1e2ffcdSBarry Smith   if (a->keepzeroedrows) {
1248f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1249f1e2ffcdSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range");
1250f1e2ffcdSBarry Smith       ierr = PetscMemzero(&a->a[a->i[rows[i]]+shift],a->ilen[rows[i]]*sizeof(Scalar));CHKERRQ(ierr);
1251f1e2ffcdSBarry Smith     }
1252f1e2ffcdSBarry Smith     if (diag) {
1253f1e2ffcdSBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1254f1e2ffcdSBarry Smith       ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1255f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1256f1e2ffcdSBarry Smith         a->a[a->diag[rows[i]]] = *diag;
1257f1e2ffcdSBarry Smith       }
1258f1e2ffcdSBarry Smith     }
1259f1e2ffcdSBarry Smith   } else {
126017ab2063SBarry Smith     if (diag) {
126117ab2063SBarry Smith       for (i=0; i<N; i++) {
1262a8c6a408SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range");
12637ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1264416022c9SBarry Smith           a->ilen[rows[i]]          = 1;
1265416022c9SBarry Smith           a->a[a->i[rows[i]]+shift] = *diag;
1266416022c9SBarry Smith           a->j[a->i[rows[i]]+shift] = rows[i]+shift;
12677ae801bdSBarry Smith         } else { /* in case row was completely empty */
1268d64ed03dSBarry Smith           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr);
126917ab2063SBarry Smith         }
127017ab2063SBarry Smith       }
12713a40ed3dSBarry Smith     } else {
127217ab2063SBarry Smith       for (i=0; i<N; i++) {
1273a8c6a408SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range");
1274416022c9SBarry Smith         a->ilen[rows[i]] = 0;
127517ab2063SBarry Smith       }
127617ab2063SBarry Smith     }
1277f1e2ffcdSBarry Smith   }
12787ae801bdSBarry Smith   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
127943a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
12803a40ed3dSBarry Smith   PetscFunctionReturn(0);
128117ab2063SBarry Smith }
128217ab2063SBarry Smith 
12835615d1e5SSatish Balay #undef __FUNC__
1284*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatGetSize_SeqAIJ"></a>*/"MatGetSize_SeqAIJ"
12858f6be9afSLois Curfman McInnes int MatGetSize_SeqAIJ(Mat A,int *m,int *n)
128617ab2063SBarry Smith {
1287416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
12883a40ed3dSBarry Smith 
12893a40ed3dSBarry Smith   PetscFunctionBegin;
12900752156aSBarry Smith   if (m) *m = a->m;
12910752156aSBarry Smith   if (n) *n = a->n;
12923a40ed3dSBarry Smith   PetscFunctionReturn(0);
129317ab2063SBarry Smith }
129417ab2063SBarry Smith 
12955615d1e5SSatish Balay #undef __FUNC__
1296*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatGetOwnershipRange_SeqAIJ"></a>*/"MatGetOwnershipRange_SeqAIJ"
12978f6be9afSLois Curfman McInnes int MatGetOwnershipRange_SeqAIJ(Mat A,int *m,int *n)
129817ab2063SBarry Smith {
1299416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
13003a40ed3dSBarry Smith 
13013a40ed3dSBarry Smith   PetscFunctionBegin;
13024c49b128SBarry Smith   if (m) *m = 0;
13034c49b128SBarry Smith   if (n) *n = a->m;
13043a40ed3dSBarry Smith   PetscFunctionReturn(0);
130517ab2063SBarry Smith }
1306026e39d0SSatish Balay 
13075615d1e5SSatish Balay #undef __FUNC__
1308*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatGetRow_SeqAIJ"></a>*/"MatGetRow_SeqAIJ"
13094e093b46SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
131017ab2063SBarry Smith {
1311416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1312c456f294SBarry Smith   int        *itmp,i,shift = a->indexshift;
131317ab2063SBarry Smith 
13143a40ed3dSBarry Smith   PetscFunctionBegin;
1315*ca44d042SBarry Smith   if (row < 0 || row >= a->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Row %d out of range",row);
131617ab2063SBarry Smith 
1317416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1318416022c9SBarry Smith   if (v) *v = a->a + a->i[row] + shift;
131917ab2063SBarry Smith   if (idx) {
1320416022c9SBarry Smith     itmp = a->j + a->i[row] + shift;
13214e093b46SBarry Smith     if (*nz && shift) {
13220452661fSBarry Smith       *idx = (int*)PetscMalloc((*nz)*sizeof(int));CHKPTRQ(*idx);
132317ab2063SBarry Smith       for (i=0; i<(*nz); i++) {(*idx)[i] = itmp[i] + shift;}
13244e093b46SBarry Smith     } else if (*nz) {
13254e093b46SBarry Smith       *idx = itmp;
132617ab2063SBarry Smith     }
132717ab2063SBarry Smith     else *idx = 0;
132817ab2063SBarry Smith   }
13293a40ed3dSBarry Smith   PetscFunctionReturn(0);
133017ab2063SBarry Smith }
133117ab2063SBarry Smith 
13325615d1e5SSatish Balay #undef __FUNC__
1333*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatRestoreRow_SeqAIJ"></a>*/"MatRestoreRow_SeqAIJ"
13344e093b46SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
133517ab2063SBarry Smith {
13364e093b46SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1337606d414cSSatish Balay   int ierr;
13383a40ed3dSBarry Smith 
13393a40ed3dSBarry Smith   PetscFunctionBegin;
1340606d414cSSatish Balay   if (idx) {if (*idx && a->indexshift) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
13413a40ed3dSBarry Smith   PetscFunctionReturn(0);
134217ab2063SBarry Smith }
134317ab2063SBarry Smith 
13445615d1e5SSatish Balay #undef __FUNC__
1345*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatNorm_SeqAIJ"></a>*/"MatNorm_SeqAIJ"
134636db0b34SBarry Smith int MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *norm)
134717ab2063SBarry Smith {
1348416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1349416022c9SBarry Smith   Scalar     *v = a->a;
135036db0b34SBarry Smith   PetscReal  sum = 0.0;
1351549d3d68SSatish Balay   int        i,j,shift = a->indexshift,ierr;
135217ab2063SBarry Smith 
13533a40ed3dSBarry Smith   PetscFunctionBegin;
135417ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1355416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
1356aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
135736db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
135817ab2063SBarry Smith #else
135917ab2063SBarry Smith       sum += (*v)*(*v); v++;
136017ab2063SBarry Smith #endif
136117ab2063SBarry Smith     }
136217ab2063SBarry Smith     *norm = sqrt(sum);
13633a40ed3dSBarry Smith   } else if (type == NORM_1) {
136436db0b34SBarry Smith     PetscReal *tmp;
1365416022c9SBarry Smith     int    *jj = a->j;
136636db0b34SBarry Smith     tmp = (PetscReal*)PetscMalloc((a->n+1)*sizeof(PetscReal));CHKPTRQ(tmp);
136736db0b34SBarry Smith     ierr = PetscMemzero(tmp,a->n*sizeof(PetscReal));CHKERRQ(ierr);
136817ab2063SBarry Smith     *norm = 0.0;
1369416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1370a2744918SBarry Smith         tmp[*jj++ + shift] += PetscAbsScalar(*v);  v++;
137117ab2063SBarry Smith     }
1372416022c9SBarry Smith     for (j=0; j<a->n; j++) {
137317ab2063SBarry Smith       if (tmp[j] > *norm) *norm = tmp[j];
137417ab2063SBarry Smith     }
1375606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
13763a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
137717ab2063SBarry Smith     *norm = 0.0;
1378416022c9SBarry Smith     for (j=0; j<a->m; j++) {
1379416022c9SBarry Smith       v = a->a + a->i[j] + shift;
138017ab2063SBarry Smith       sum = 0.0;
1381416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1382cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
138317ab2063SBarry Smith       }
138417ab2063SBarry Smith       if (sum > *norm) *norm = sum;
138517ab2063SBarry Smith     }
13863a40ed3dSBarry Smith   } else {
1387a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"No support for two norm");
138817ab2063SBarry Smith   }
13893a40ed3dSBarry Smith   PetscFunctionReturn(0);
139017ab2063SBarry Smith }
139117ab2063SBarry Smith 
13925615d1e5SSatish Balay #undef __FUNC__
1393*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatTranspose_SeqAIJ"></a>*/"MatTranspose_SeqAIJ"
13948f6be9afSLois Curfman McInnes int MatTranspose_SeqAIJ(Mat A,Mat *B)
139517ab2063SBarry Smith {
1396416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1397416022c9SBarry Smith   Mat        C;
1398416022c9SBarry Smith   int        i,ierr,*aj = a->j,*ai = a->i,m = a->m,len,*col;
139936db0b34SBarry Smith   int        shift = a->indexshift,refct;
1400d5d45c9bSBarry Smith   Scalar     *array = a->a;
140117ab2063SBarry Smith 
14023a40ed3dSBarry Smith   PetscFunctionBegin;
1403f1e2ffcdSBarry Smith   if (!B && m != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Square matrix only for in-place");
14040452661fSBarry Smith   col  = (int*)PetscMalloc((1+a->n)*sizeof(int));CHKPTRQ(col);
1405549d3d68SSatish Balay   ierr = PetscMemzero(col,(1+a->n)*sizeof(int));CHKERRQ(ierr);
140617ab2063SBarry Smith   if (shift) {
140717ab2063SBarry Smith     for (i=0; i<ai[m]-1; i++) aj[i] -= 1;
140817ab2063SBarry Smith   }
140917ab2063SBarry Smith   for (i=0; i<ai[m]+shift; i++) col[aj[i]] += 1;
1410416022c9SBarry Smith   ierr = MatCreateSeqAIJ(A->comm,a->n,m,0,col,&C);CHKERRQ(ierr);
1411606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
141217ab2063SBarry Smith   for (i=0; i<m; i++) {
141317ab2063SBarry Smith     len = ai[i+1]-ai[i];
1414416022c9SBarry Smith     ierr = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
141517ab2063SBarry Smith     array += len; aj += len;
141617ab2063SBarry Smith   }
141717ab2063SBarry Smith   if (shift) {
141817ab2063SBarry Smith     for (i=0; i<ai[m]-1; i++) aj[i] += 1;
141917ab2063SBarry Smith   }
142017ab2063SBarry Smith 
14216d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14226d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
142317ab2063SBarry Smith 
1424f1e2ffcdSBarry Smith   if (B) {
1425416022c9SBarry Smith     *B = C;
142617ab2063SBarry Smith   } else {
1427f830108cSBarry Smith     PetscOps *Abops;
14280a6ffc59SBarry Smith     MatOps   Aops;
1429f830108cSBarry Smith 
1430416022c9SBarry Smith     /* This isn't really an in-place transpose */
1431606d414cSSatish Balay     ierr = PetscFree(a->a);CHKERRQ(ierr);
1432606d414cSSatish Balay     if (!a->singlemalloc) {
1433606d414cSSatish Balay       ierr = PetscFree(a->i);CHKERRQ(ierr);
1434606d414cSSatish Balay       ierr = PetscFree(a->j);
1435606d414cSSatish Balay     }
1436606d414cSSatish Balay     if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
1437606d414cSSatish Balay     if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
1438606d414cSSatish Balay     if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
1439606d414cSSatish Balay     if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
1440606d414cSSatish Balay     if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);}
1441606d414cSSatish Balay     ierr = PetscFree(a);CHKERRQ(ierr);
1442f830108cSBarry Smith 
1443488ecbafSBarry Smith 
1444488ecbafSBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
1445488ecbafSBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
1446488ecbafSBarry Smith 
1447f830108cSBarry Smith     /*
1448f830108cSBarry Smith       This is horrible, horrible code. We need to keep the
14498f0f457cSSatish Balay       the bops and ops Structures, copy everything from C
14508f0f457cSSatish Balay       including the function pointers..
1451f830108cSBarry Smith     */
1452549d3d68SSatish Balay     ierr     = PetscMemcpy(A->ops,C->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
1453549d3d68SSatish Balay     ierr     = PetscMemcpy(A->bops,C->bops,sizeof(PetscOps));CHKERRQ(ierr);
1454f830108cSBarry Smith     Abops    = A->bops;
1455f830108cSBarry Smith     Aops     = A->ops;
145636db0b34SBarry Smith     refct    = A->refct;
1457549d3d68SSatish Balay     ierr     = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr);
1458f830108cSBarry Smith     A->bops  = Abops;
1459f830108cSBarry Smith     A->ops   = Aops;
146027a8da17SBarry Smith     A->qlist = 0;
146136db0b34SBarry Smith     A->refct = refct;
146236db0b34SBarry Smith     /* copy over the type_name and name */
146336db0b34SBarry Smith     ierr     = PetscStrallocpy(C->type_name,&A->type_name);CHKERRQ(ierr);
146436db0b34SBarry Smith     ierr     = PetscStrallocpy(C->name,&A->name);CHKERRQ(ierr);
1465f830108cSBarry Smith 
14660452661fSBarry Smith     PetscHeaderDestroy(C);
146717ab2063SBarry Smith   }
14683a40ed3dSBarry Smith   PetscFunctionReturn(0);
146917ab2063SBarry Smith }
147017ab2063SBarry Smith 
14715615d1e5SSatish Balay #undef __FUNC__
1472*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatDiagonalScale_SeqAIJ"></a>*/"MatDiagonalScale_SeqAIJ"
14738f6be9afSLois Curfman McInnes int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
147417ab2063SBarry Smith {
1475416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
147617ab2063SBarry Smith   Scalar     *l,*r,x,*v;
1477e1311b90SBarry Smith   int        ierr,i,j,m = a->m,n = a->n,M,nz = a->nz,*jj,shift = a->indexshift;
147817ab2063SBarry Smith 
14793a40ed3dSBarry Smith   PetscFunctionBegin;
148017ab2063SBarry Smith   if (ll) {
14813ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
14823ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
1483e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
1484a8c6a408SBarry Smith     if (m != a->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Left scaling vector wrong length");
1485e1311b90SBarry Smith     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
1486416022c9SBarry Smith     v = a->a;
148717ab2063SBarry Smith     for (i=0; i<m; i++) {
148817ab2063SBarry Smith       x = l[i];
1489416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
149017ab2063SBarry Smith       for (j=0; j<M; j++) { (*v++) *= x;}
149117ab2063SBarry Smith     }
1492e1311b90SBarry Smith     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
149344cd7ae7SLois Curfman McInnes     PLogFlops(nz);
149417ab2063SBarry Smith   }
149517ab2063SBarry Smith   if (rr) {
1496e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
1497a8c6a408SBarry Smith     if (n != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Right scaling vector wrong length");
1498e1311b90SBarry Smith     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
1499416022c9SBarry Smith     v = a->a; jj = a->j;
150017ab2063SBarry Smith     for (i=0; i<nz; i++) {
150117ab2063SBarry Smith       (*v++) *= r[*jj++ + shift];
150217ab2063SBarry Smith     }
1503e1311b90SBarry Smith     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
150444cd7ae7SLois Curfman McInnes     PLogFlops(nz);
150517ab2063SBarry Smith   }
15063a40ed3dSBarry Smith   PetscFunctionReturn(0);
150717ab2063SBarry Smith }
150817ab2063SBarry Smith 
15095615d1e5SSatish Balay #undef __FUNC__
1510*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatGetSubMatrix_SeqAIJ"></a>*/"MatGetSubMatrix_SeqAIJ"
15117b2a1423SBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatReuse scall,Mat *B)
151217ab2063SBarry Smith {
1513db02288aSLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data,*c;
1514d5db1b72SBarry Smith   int          *smap,i,k,kstart,kend,ierr,oldcols = a->n,*lens;
151536db0b34SBarry Smith   int          row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
151699141d43SSatish Balay   int          *irow,*icol,nrows,ncols,shift = a->indexshift,*ssmap;
151799141d43SSatish Balay   int          *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
151899141d43SSatish Balay   Scalar       *a_new,*mat_a;
1519416022c9SBarry Smith   Mat          C;
1520fee21e36SBarry Smith   PetscTruth   stride;
152117ab2063SBarry Smith 
15223a40ed3dSBarry Smith   PetscFunctionBegin;
1523d64ed03dSBarry Smith   ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr);
1524a8c6a408SBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"ISrow is not sorted");
1525d64ed03dSBarry Smith   ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr);
1526a8c6a408SBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"IScol is not sorted");
152799141d43SSatish Balay 
152817ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
152917ab2063SBarry Smith   ierr = ISGetSize(isrow,&nrows);CHKERRQ(ierr);
153017ab2063SBarry Smith   ierr = ISGetSize(iscol,&ncols);CHKERRQ(ierr);
153117ab2063SBarry Smith 
1532fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
1533fee21e36SBarry Smith   ierr = ISStride(iscol,&stride);CHKERRQ(ierr);
1534fee21e36SBarry Smith   if (stride && step == 1) {
153502834360SBarry Smith     /* special case of contiguous rows */
153657faeb66SBarry Smith     lens   = (int*)PetscMalloc((ncols+nrows+1)*sizeof(int));CHKPTRQ(lens);
153702834360SBarry Smith     starts = lens + ncols;
153802834360SBarry Smith     /* loop over new rows determining lens and starting points */
153902834360SBarry Smith     for (i=0; i<nrows; i++) {
1540a2744918SBarry Smith       kstart  = ai[irow[i]]+shift;
1541a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
154202834360SBarry Smith       for (k=kstart; k<kend; k++) {
1543d8ced48eSBarry Smith         if (aj[k]+shift >= first) {
154402834360SBarry Smith           starts[i] = k;
154502834360SBarry Smith           break;
154602834360SBarry Smith 	}
154702834360SBarry Smith       }
1548a2744918SBarry Smith       sum = 0;
154902834360SBarry Smith       while (k < kend) {
1550d8ced48eSBarry Smith         if (aj[k++]+shift >= first+ncols) break;
1551a2744918SBarry Smith         sum++;
155202834360SBarry Smith       }
1553a2744918SBarry Smith       lens[i] = sum;
155402834360SBarry Smith     }
155502834360SBarry Smith     /* create submatrix */
1556cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
155708480c60SBarry Smith       int n_cols,n_rows;
155808480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
1559a8c6a408SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Reused submatrix wrong size");
1560d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
156108480c60SBarry Smith       C = *B;
15623a40ed3dSBarry Smith     } else {
156302834360SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
156408480c60SBarry Smith     }
1565db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
1566db02288aSLois Curfman McInnes 
156702834360SBarry Smith     /* loop over rows inserting into submatrix */
1568db02288aSLois Curfman McInnes     a_new    = c->a;
1569db02288aSLois Curfman McInnes     j_new    = c->j;
1570db02288aSLois Curfman McInnes     i_new    = c->i;
1571db02288aSLois Curfman McInnes     i_new[0] = -shift;
157202834360SBarry Smith     for (i=0; i<nrows; i++) {
1573a2744918SBarry Smith       ii    = starts[i];
1574a2744918SBarry Smith       lensi = lens[i];
1575a2744918SBarry Smith       for (k=0; k<lensi; k++) {
1576a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
157702834360SBarry Smith       }
1578549d3d68SSatish Balay       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(Scalar));CHKERRQ(ierr);
1579a2744918SBarry Smith       a_new      += lensi;
1580a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
1581a2744918SBarry Smith       c->ilen[i]  = lensi;
158202834360SBarry Smith     }
1583606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
15843a40ed3dSBarry Smith   } else {
158502834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
15860452661fSBarry Smith     smap  = (int*)PetscMalloc((1+oldcols)*sizeof(int));CHKPTRQ(smap);
158702834360SBarry Smith     ssmap = smap + shift;
158899141d43SSatish Balay     lens  = (int*)PetscMalloc((1+nrows)*sizeof(int));CHKPTRQ(lens);
1589549d3d68SSatish Balay     ierr  = PetscMemzero(smap,oldcols*sizeof(int));CHKERRQ(ierr);
159017ab2063SBarry Smith     for (i=0; i<ncols; i++) smap[icol[i]] = i+1;
159102834360SBarry Smith     /* determine lens of each row */
159202834360SBarry Smith     for (i=0; i<nrows; i++) {
1593d8ced48eSBarry Smith       kstart  = ai[irow[i]]+shift;
159402834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
159502834360SBarry Smith       lens[i] = 0;
159602834360SBarry Smith       for (k=kstart; k<kend; k++) {
1597d8ced48eSBarry Smith         if (ssmap[aj[k]]) {
159802834360SBarry Smith           lens[i]++;
159902834360SBarry Smith         }
160002834360SBarry Smith       }
160102834360SBarry Smith     }
160217ab2063SBarry Smith     /* Create and fill new matrix */
1603a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
16040f5bd95cSBarry Smith       PetscTruth equal;
16050f5bd95cSBarry Smith 
160699141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
1607a8c6a408SBarry Smith       if (c->m  != nrows || c->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong size");
16080f5bd95cSBarry Smith       ierr = PetscMemcmp(c->ilen,lens,c->m*sizeof(int),&equal);CHKERRQ(ierr);
16090f5bd95cSBarry Smith       if (!equal) {
1610a8c6a408SBarry Smith         SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong no of nonzeros");
161199141d43SSatish Balay       }
1612549d3d68SSatish Balay       ierr = PetscMemzero(c->ilen,c->m*sizeof(int));CHKERRQ(ierr);
161308480c60SBarry Smith       C = *B;
16143a40ed3dSBarry Smith     } else {
161502834360SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
161608480c60SBarry Smith     }
161799141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
161817ab2063SBarry Smith     for (i=0; i<nrows; i++) {
161999141d43SSatish Balay       row    = irow[i];
162099141d43SSatish Balay       kstart = ai[row]+shift;
162199141d43SSatish Balay       kend   = kstart + a->ilen[row];
162299141d43SSatish Balay       mat_i  = c->i[i]+shift;
162399141d43SSatish Balay       mat_j  = c->j + mat_i;
162499141d43SSatish Balay       mat_a  = c->a + mat_i;
162599141d43SSatish Balay       mat_ilen = c->ilen + i;
162617ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
162799141d43SSatish Balay         if ((tcol=ssmap[a->j[k]])) {
162899141d43SSatish Balay           *mat_j++ = tcol - (!shift);
162999141d43SSatish Balay           *mat_a++ = a->a[k];
163099141d43SSatish Balay           (*mat_ilen)++;
163199141d43SSatish Balay 
163217ab2063SBarry Smith         }
163317ab2063SBarry Smith       }
163417ab2063SBarry Smith     }
163502834360SBarry Smith     /* Free work space */
163602834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1637606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
1638606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
163902834360SBarry Smith   }
16406d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16416d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
164217ab2063SBarry Smith 
164317ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
1644416022c9SBarry Smith   *B = C;
16453a40ed3dSBarry Smith   PetscFunctionReturn(0);
164617ab2063SBarry Smith }
164717ab2063SBarry Smith 
1648a871dcd8SBarry Smith /*
1649a871dcd8SBarry Smith */
16505615d1e5SSatish Balay #undef __FUNC__
1651*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatILUFactor_SeqAIJ"></a>*/"MatILUFactor_SeqAIJ"
16525ef9f2a5SBarry Smith int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatILUInfo *info)
1653a871dcd8SBarry Smith {
165463b91edcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data;
165508480c60SBarry Smith   int        ierr;
165663b91edcSBarry Smith   Mat        outA;
1657b8a78c4aSBarry Smith   PetscTruth row_identity,col_identity;
165863b91edcSBarry Smith 
16593a40ed3dSBarry Smith   PetscFunctionBegin;
1660b8a78c4aSBarry Smith   if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,0,"Only levels=0 supported for in-place ilu");
1661b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1662b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1663b8a78c4aSBarry Smith   if (!row_identity || !col_identity) {
1664b8a78c4aSBarry Smith     SETERRQ(1,1,"Row and column permutations must be identity for in-place ILU");
1665b8a78c4aSBarry Smith   }
1666a871dcd8SBarry Smith 
166763b91edcSBarry Smith   outA          = inA;
166863b91edcSBarry Smith   inA->factor   = FACTOR_LU;
166963b91edcSBarry Smith   a->row        = row;
167063b91edcSBarry Smith   a->col        = col;
1671c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1672c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
167363b91edcSBarry Smith 
167436db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
1675c38d4ed2SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* if this came from a previous factored; need to remove old one */
16764c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
16771e4dd532SSatish Balay   PLogObjectParent(inA,a->icol);
1678f0ec6fceSSatish Balay 
167994a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
16800452661fSBarry Smith     a->solve_work = (Scalar*)PetscMalloc((a->m+1)*sizeof(Scalar));CHKPTRQ(a->solve_work);
168194a9d846SBarry Smith   }
168263b91edcSBarry Smith 
168308480c60SBarry Smith   if (!a->diag) {
1684f1e2ffcdSBarry Smith     ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
168563b91edcSBarry Smith   }
168663b91edcSBarry Smith   ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA);CHKERRQ(ierr);
16873a40ed3dSBarry Smith   PetscFunctionReturn(0);
1688a871dcd8SBarry Smith }
1689a871dcd8SBarry Smith 
169074cdf0dfSBarry Smith #include "pinclude/blaslapack.h"
16915615d1e5SSatish Balay #undef __FUNC__
1692*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatScale_SeqAIJ"></a>*/"MatScale_SeqAIJ"
16938f6be9afSLois Curfman McInnes int MatScale_SeqAIJ(Scalar *alpha,Mat inA)
1694f0b747eeSBarry Smith {
1695f0b747eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data;
1696f0b747eeSBarry Smith   int        one = 1;
16973a40ed3dSBarry Smith 
16983a40ed3dSBarry Smith   PetscFunctionBegin;
1699f0b747eeSBarry Smith   BLscal_(&a->nz,alpha,a->a,&one);
1700f0b747eeSBarry Smith   PLogFlops(a->nz);
17013a40ed3dSBarry Smith   PetscFunctionReturn(0);
1702f0b747eeSBarry Smith }
1703f0b747eeSBarry Smith 
17045615d1e5SSatish Balay #undef __FUNC__
1705*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatGetSubMatrices_SeqAIJ"></a>*/"MatGetSubMatrices_SeqAIJ"
17067b2a1423SBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n,IS *irow,IS *icol,MatReuse scall,Mat **B)
1707cddf8d76SBarry Smith {
1708cddf8d76SBarry Smith   int ierr,i;
1709cddf8d76SBarry Smith 
17103a40ed3dSBarry Smith   PetscFunctionBegin;
1711cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
17120452661fSBarry Smith     *B = (Mat*)PetscMalloc((n+1)*sizeof(Mat));CHKPTRQ(*B);
1713cddf8d76SBarry Smith   }
1714cddf8d76SBarry Smith 
1715cddf8d76SBarry Smith   for (i=0; i<n; i++) {
17166a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1717cddf8d76SBarry Smith   }
17183a40ed3dSBarry Smith   PetscFunctionReturn(0);
1719cddf8d76SBarry Smith }
1720cddf8d76SBarry Smith 
17215615d1e5SSatish Balay #undef __FUNC__
1722*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatGetBlockSize_SeqAIJ"></a>*/"MatGetBlockSize_SeqAIJ"
17238f6be9afSLois Curfman McInnes int MatGetBlockSize_SeqAIJ(Mat A,int *bs)
17245a838052SSatish Balay {
1725f830108cSBarry Smith   PetscFunctionBegin;
17265a838052SSatish Balay   *bs = 1;
17273a40ed3dSBarry Smith   PetscFunctionReturn(0);
17285a838052SSatish Balay }
17295a838052SSatish Balay 
17305615d1e5SSatish Balay #undef __FUNC__
1731*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatIncreaseOverlap_SeqAIJ"></a>*/"MatIncreaseOverlap_SeqAIJ"
17328f6be9afSLois Curfman McInnes int MatIncreaseOverlap_SeqAIJ(Mat A,int is_max,IS *is,int ov)
17334dcbc457SBarry Smith {
1734e4d965acSSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
173506763907SSatish Balay   int        shift,row,i,j,k,l,m,n,*idx,ierr,*nidx,isz,val;
17368a047759SSatish Balay   int        start,end,*ai,*aj;
1737f1af5d2fSBarry Smith   PetscBT    table;
1738bbd702dbSSatish Balay 
17393a40ed3dSBarry Smith   PetscFunctionBegin;
17408a047759SSatish Balay   shift = a->indexshift;
1741e4d965acSSatish Balay   m     = a->m;
1742e4d965acSSatish Balay   ai    = a->i;
17438a047759SSatish Balay   aj    = a->j+shift;
17448a047759SSatish Balay 
1745a8c6a408SBarry Smith   if (ov < 0)  SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"illegal overlap value used");
174606763907SSatish Balay 
174706763907SSatish Balay   nidx  = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(nidx);
17486831982aSBarry Smith   ierr  = PetscBTCreate(m,table);CHKERRQ(ierr);
174906763907SSatish Balay 
1750e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
1751b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
1752e4d965acSSatish Balay     isz  = 0;
17536831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
1754e4d965acSSatish Balay 
1755e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
17564dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
175777c4ece6SBarry Smith     ierr = ISGetSize(is[i],&n);CHKERRQ(ierr);
1758e4d965acSSatish Balay 
1759dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
1760e4d965acSSatish Balay     for (j=0; j<n ; ++j){
1761f1af5d2fSBarry Smith       if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];}
17624dcbc457SBarry Smith     }
176306763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
176406763907SSatish Balay     ierr = ISDestroy(is[i]);CHKERRQ(ierr);
1765e4d965acSSatish Balay 
176604a348a9SBarry Smith     k = 0;
176704a348a9SBarry Smith     for (j=0; j<ov; j++){ /* for each overlap */
176804a348a9SBarry Smith       n = isz;
176906763907SSatish Balay       for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
1770e4d965acSSatish Balay         row   = nidx[k];
1771e4d965acSSatish Balay         start = ai[row];
1772e4d965acSSatish Balay         end   = ai[row+1];
177304a348a9SBarry Smith         for (l = start; l<end ; l++){
17748a047759SSatish Balay           val = aj[l] + shift;
1775f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
1776e4d965acSSatish Balay         }
1777e4d965acSSatish Balay       }
1778e4d965acSSatish Balay     }
1779029af93fSBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr);
1780e4d965acSSatish Balay   }
17816831982aSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
1782606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
17833a40ed3dSBarry Smith   PetscFunctionReturn(0);
17844dcbc457SBarry Smith }
178517ab2063SBarry Smith 
17860513a670SBarry Smith /* -------------------------------------------------------------- */
17870513a670SBarry Smith #undef __FUNC__
1788*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatPermute_SeqAIJ"></a>*/"MatPermute_SeqAIJ"
17890513a670SBarry Smith int MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
17900513a670SBarry Smith {
17910513a670SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
17920513a670SBarry Smith   Scalar     *vwork;
17930513a670SBarry Smith   int        i,ierr,nz,m = a->m,n = a->n,*cwork;
17940513a670SBarry Smith   int        *row,*col,*cnew,j,*lens;
179556cd22aeSBarry Smith   IS         icolp,irowp;
17960513a670SBarry Smith 
17973a40ed3dSBarry Smith   PetscFunctionBegin;
17984c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
179956cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
18004c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
180156cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
18020513a670SBarry Smith 
18030513a670SBarry Smith   /* determine lengths of permuted rows */
18040513a670SBarry Smith   lens = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(lens);
18050513a670SBarry Smith   for (i=0; i<m; i++) {
18060513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
18070513a670SBarry Smith   }
18080513a670SBarry Smith   ierr = MatCreateSeqAIJ(A->comm,m,n,0,lens,B);CHKERRQ(ierr);
1809606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
18100513a670SBarry Smith 
18110513a670SBarry Smith   cnew = (int*)PetscMalloc(n*sizeof(int));CHKPTRQ(cnew);
18120513a670SBarry Smith   for (i=0; i<m; i++) {
18130513a670SBarry Smith     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18140513a670SBarry Smith     for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];}
18150513a670SBarry Smith     ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
18160513a670SBarry Smith     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18170513a670SBarry Smith   }
1818606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
18190513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18200513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
182156cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
182256cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
182356cd22aeSBarry Smith   ierr = ISDestroy(irowp);CHKERRQ(ierr);
182456cd22aeSBarry Smith   ierr = ISDestroy(icolp);CHKERRQ(ierr);
18253a40ed3dSBarry Smith   PetscFunctionReturn(0);
18260513a670SBarry Smith }
18270513a670SBarry Smith 
18285615d1e5SSatish Balay #undef __FUNC__
1829*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatPrintHelp_SeqAIJ"></a>*/"MatPrintHelp_SeqAIJ"
1830682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A)
1831682d7d0cSBarry Smith {
1832c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1833682d7d0cSBarry Smith   MPI_Comm          comm = A->comm;
1834d132466eSBarry Smith   int               ierr;
1835682d7d0cSBarry Smith 
18363a40ed3dSBarry Smith   PetscFunctionBegin;
1837c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1838d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1839d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr);
1840d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr);
1841d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_no_inode: Do not use inodes\n");CHKERRQ(ierr);
1842d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");CHKERRQ(ierr);
1843aa482453SBarry Smith #if defined(PETSC_HAVE_ESSL)
1844d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_essl: Use IBM sparse LU factorization and solve.\n");CHKERRQ(ierr);
1845682d7d0cSBarry Smith #endif
1846*ca44d042SBarry Smith #if defined(PETSC_HAVE_MATLAB)
1847*ca44d042SBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_matlab: Use Matlab engine sparse LU factorization and solve.\n");CHKERRQ(ierr);
1848*ca44d042SBarry Smith #endif
18493a40ed3dSBarry Smith   PetscFunctionReturn(0);
1850682d7d0cSBarry Smith }
1851*ca44d042SBarry Smith EXTERN int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg);
1852*ca44d042SBarry Smith EXTERN int MatFDColoringCreate_SeqAIJ(Mat,ISColoring,MatFDColoring);
1853*ca44d042SBarry Smith EXTERN int MatColoringPatch_SeqAIJ(Mat,int,int *,ISColoring *);
1854*ca44d042SBarry Smith EXTERN int MatILUDTFactor_SeqAIJ(Mat,MatILUInfo*,IS,IS,Mat*);
1855cb5b572fSBarry Smith #undef __FUNC__
1856*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatCopy_SeqAIJ"></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 
1944*ca44d042SBarry Smith EXTERN int MatUseSuperLU_SeqAIJ(Mat);
1945*ca44d042SBarry Smith EXTERN int MatUseEssl_SeqAIJ(Mat);
1946*ca44d042SBarry Smith EXTERN int MatUseMatlab_SeqAIJ(Mat);
1947*ca44d042SBarry Smith EXTERN int MatUseDXML_SeqAIJ(Mat);
194817ab2063SBarry Smith 
1949fb2e594dSBarry Smith EXTERN_C_BEGIN
19505615d1e5SSatish Balay #undef __FUNC__
1951*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatSeqAIJSetColumnIndices_SeqAIJ"></a>*/"MatSeqAIJSetColumnIndices_SeqAIJ"
195215091d37SBarry Smith 
1953bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices)
1954bef8e0ddSBarry Smith {
1955bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
1956bef8e0ddSBarry Smith   int        i,nz,n;
1957bef8e0ddSBarry Smith 
1958bef8e0ddSBarry Smith   PetscFunctionBegin;
1959bef8e0ddSBarry Smith   if (aij->indexshift) SETERRQ(1,1,"No support with 1 based indexing");
1960bef8e0ddSBarry Smith 
1961bef8e0ddSBarry Smith   nz = aij->maxnz;
1962bef8e0ddSBarry Smith   n  = aij->n;
1963bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
1964bef8e0ddSBarry Smith     aij->j[i] = indices[i];
1965bef8e0ddSBarry Smith   }
1966bef8e0ddSBarry Smith   aij->nz = nz;
1967bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
1968bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
1969bef8e0ddSBarry Smith   }
1970bef8e0ddSBarry Smith 
1971bef8e0ddSBarry Smith   PetscFunctionReturn(0);
1972bef8e0ddSBarry Smith }
1973fb2e594dSBarry Smith EXTERN_C_END
1974bef8e0ddSBarry Smith 
1975bef8e0ddSBarry Smith #undef __FUNC__
1976*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatSeqAIJSetColumnIndices"></a>*/"MatSeqAIJSetColumnIndices"
1977bef8e0ddSBarry Smith /*@
1978bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
1979bef8e0ddSBarry Smith        in the matrix.
1980bef8e0ddSBarry Smith 
1981bef8e0ddSBarry Smith   Input Parameters:
1982bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
1983bef8e0ddSBarry Smith -  indices - the column indices
1984bef8e0ddSBarry Smith 
198515091d37SBarry Smith   Level: advanced
198615091d37SBarry Smith 
1987bef8e0ddSBarry Smith   Notes:
1988bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
1989bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
1990bef8e0ddSBarry Smith   of the MatSetValues() operation.
1991bef8e0ddSBarry Smith 
1992bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
1993bef8e0ddSBarry Smith   MatCreateSeqAIJ().
1994bef8e0ddSBarry Smith 
1995bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
1996bef8e0ddSBarry Smith 
1997bef8e0ddSBarry Smith @*/
1998bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices)
1999bef8e0ddSBarry Smith {
2000bef8e0ddSBarry Smith   int ierr,(*f)(Mat,int *);
2001bef8e0ddSBarry Smith 
2002bef8e0ddSBarry Smith   PetscFunctionBegin;
2003bef8e0ddSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2004549d3d68SSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void **)&f);CHKERRQ(ierr);
2005bef8e0ddSBarry Smith   if (f) {
2006bef8e0ddSBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
2007bef8e0ddSBarry Smith   } else {
2008bef8e0ddSBarry Smith     SETERRQ(1,1,"Wrong type of matrix to set column indices");
2009bef8e0ddSBarry Smith   }
2010bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2011bef8e0ddSBarry Smith }
2012bef8e0ddSBarry Smith 
2013be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
2014be6bf707SBarry Smith 
2015fb2e594dSBarry Smith EXTERN_C_BEGIN
2016be6bf707SBarry Smith #undef __FUNC__
2017*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatStoreValues_SeqAIJ"></a>*/"MatStoreValues_SeqAIJ"
2018be6bf707SBarry Smith int MatStoreValues_SeqAIJ(Mat mat)
2019be6bf707SBarry Smith {
2020be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2021549d3d68SSatish Balay   int        nz = aij->i[aij->m]+aij->indexshift,ierr;
2022be6bf707SBarry Smith 
2023be6bf707SBarry Smith   PetscFunctionBegin;
2024be6bf707SBarry Smith   if (aij->nonew != 1) {
2025be6bf707SBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2026be6bf707SBarry Smith   }
2027be6bf707SBarry Smith 
2028be6bf707SBarry Smith   /* allocate space for values if not already there */
2029be6bf707SBarry Smith   if (!aij->saved_values) {
2030be6bf707SBarry Smith     aij->saved_values = (Scalar*)PetscMalloc(nz*sizeof(Scalar));CHKPTRQ(aij->saved_values);
2031be6bf707SBarry Smith   }
2032be6bf707SBarry Smith 
2033be6bf707SBarry Smith   /* copy values over */
2034549d3d68SSatish Balay   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr);
2035be6bf707SBarry Smith   PetscFunctionReturn(0);
2036be6bf707SBarry Smith }
2037fb2e594dSBarry Smith EXTERN_C_END
2038be6bf707SBarry Smith 
2039be6bf707SBarry Smith #undef __FUNC__
2040*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatStoreValues""></a>*/"MatStoreValues"
2041be6bf707SBarry Smith /*@
2042be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
2043be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2044be6bf707SBarry Smith        nonlinear portion.
2045be6bf707SBarry Smith 
2046be6bf707SBarry Smith    Collect on Mat
2047be6bf707SBarry Smith 
2048be6bf707SBarry Smith   Input Parameters:
2049be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2050be6bf707SBarry Smith 
205115091d37SBarry Smith   Level: advanced
205215091d37SBarry Smith 
2053be6bf707SBarry Smith   Common Usage, with SNESSolve():
2054be6bf707SBarry Smith $    Create Jacobian matrix
2055be6bf707SBarry Smith $    Set linear terms into matrix
2056be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
2057be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
2058be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
2059be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2060be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2061be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
2062be6bf707SBarry Smith $    In your Jacobian routine
2063be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
2064be6bf707SBarry Smith $      Set nonlinear terms in matrix
2065be6bf707SBarry Smith 
2066be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
2067be6bf707SBarry Smith $    // build linear portion of Jacobian
2068be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2069be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2070be6bf707SBarry Smith $    loop over nonlinear iterations
2071be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
2072be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
2073be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
2074be6bf707SBarry Smith $       Solve linear system with Jacobian
2075be6bf707SBarry Smith $    endloop
2076be6bf707SBarry Smith 
2077be6bf707SBarry Smith   Notes:
2078be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
2079be6bf707SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before
2080be6bf707SBarry Smith     calling this routine.
2081be6bf707SBarry Smith 
2082be6bf707SBarry Smith .seealso: MatRetrieveValues()
2083be6bf707SBarry Smith 
2084be6bf707SBarry Smith @*/
2085be6bf707SBarry Smith int MatStoreValues(Mat mat)
2086be6bf707SBarry Smith {
2087be6bf707SBarry Smith   int ierr,(*f)(Mat);
2088be6bf707SBarry Smith 
2089be6bf707SBarry Smith   PetscFunctionBegin;
2090be6bf707SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2091be6bf707SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2092be6bf707SBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2093be6bf707SBarry Smith 
2094c5d6004cSBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void **)&f);CHKERRQ(ierr);
2095be6bf707SBarry Smith   if (f) {
2096be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2097be6bf707SBarry Smith   } else {
2098be6bf707SBarry Smith     SETERRQ(1,1,"Wrong type of matrix to store values");
2099be6bf707SBarry Smith   }
2100be6bf707SBarry Smith   PetscFunctionReturn(0);
2101be6bf707SBarry Smith }
2102be6bf707SBarry Smith 
2103fb2e594dSBarry Smith EXTERN_C_BEGIN
2104be6bf707SBarry Smith #undef __FUNC__
2105*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatRetrieveValues_SeqAIJ"></a>*/"MatRetrieveValues_SeqAIJ"
2106be6bf707SBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat)
2107be6bf707SBarry Smith {
2108be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2109549d3d68SSatish Balay   int        nz = aij->i[aij->m]+aij->indexshift,ierr;
2110be6bf707SBarry Smith 
2111be6bf707SBarry Smith   PetscFunctionBegin;
2112be6bf707SBarry Smith   if (aij->nonew != 1) {
2113be6bf707SBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2114be6bf707SBarry Smith   }
2115be6bf707SBarry Smith   if (!aij->saved_values) {
2116be6bf707SBarry Smith     SETERRQ(1,1,"Must call MatStoreValues(A);first");
2117be6bf707SBarry Smith   }
2118be6bf707SBarry Smith 
2119be6bf707SBarry Smith   /* copy values over */
2120549d3d68SSatish Balay   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr);
2121be6bf707SBarry Smith   PetscFunctionReturn(0);
2122be6bf707SBarry Smith }
2123fb2e594dSBarry Smith EXTERN_C_END
2124be6bf707SBarry Smith 
2125be6bf707SBarry Smith #undef __FUNC__
2126*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatRetrieveValues"></a>*/"MatRetrieveValues"
2127be6bf707SBarry Smith /*@
2128be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
2129be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2130be6bf707SBarry Smith        nonlinear portion.
2131be6bf707SBarry Smith 
2132be6bf707SBarry Smith    Collect on Mat
2133be6bf707SBarry Smith 
2134be6bf707SBarry Smith   Input Parameters:
2135be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2136be6bf707SBarry Smith 
213715091d37SBarry Smith   Level: advanced
213815091d37SBarry Smith 
2139be6bf707SBarry Smith .seealso: MatStoreValues()
2140be6bf707SBarry Smith 
2141be6bf707SBarry Smith @*/
2142be6bf707SBarry Smith int MatRetrieveValues(Mat mat)
2143be6bf707SBarry Smith {
2144be6bf707SBarry Smith   int ierr,(*f)(Mat);
2145be6bf707SBarry Smith 
2146be6bf707SBarry Smith   PetscFunctionBegin;
2147be6bf707SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2148be6bf707SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2149be6bf707SBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2150be6bf707SBarry Smith 
2151c5d6004cSBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void **)&f);CHKERRQ(ierr);
2152be6bf707SBarry Smith   if (f) {
2153be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2154be6bf707SBarry Smith   } else {
2155be6bf707SBarry Smith     SETERRQ(1,1,"Wrong type of matrix to retrieve values");
2156be6bf707SBarry Smith   }
2157be6bf707SBarry Smith   PetscFunctionReturn(0);
2158be6bf707SBarry Smith }
2159be6bf707SBarry Smith 
2160f83d6046SBarry Smith /*
2161f83d6046SBarry Smith    This allows SeqAIJ matrices to be passed to the matlab engine
2162f83d6046SBarry Smith */
2163f83d6046SBarry Smith #if defined(PETSC_HAVE_MATLAB)
2164f83d6046SBarry Smith #include "engine.h"   /* Matlab include file */
2165f83d6046SBarry Smith #include "mex.h"      /* Matlab include file */
2166f83d6046SBarry Smith EXTERN_C_BEGIN
2167f83d6046SBarry Smith #undef __FUNC__
2168f83d6046SBarry Smith #define __FUNC__ /*<a name="MatMatlabEnginePut_SeqAIJ"></a>*/"MatMatlabEnginePut_SeqAIJ"
2169f83d6046SBarry Smith int MatMatlabEnginePut_SeqAIJ(PetscObject obj,void *engine)
2170f83d6046SBarry Smith {
2171d79a51d8SBarry Smith   int        ierr,i,*aj,*ai;
2172f83d6046SBarry Smith   Mat        B = (Mat)obj;
2173f83d6046SBarry Smith   Scalar     *array;
2174f83d6046SBarry Smith   mxArray    *mat;
2175d79a51d8SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)B->data;
2176d79a51d8SBarry Smith 
2177f83d6046SBarry Smith 
2178f83d6046SBarry Smith   PetscFunctionBegin;
2179d79a51d8SBarry Smith   mat  = mxCreateSparse(B->n,B->m,aij->nz,(mxComplexity)0);
2180d79a51d8SBarry Smith   ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(Scalar));CHKERRQ(ierr);
2181d79a51d8SBarry Smith   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
2182d79a51d8SBarry Smith   ai   = mxGetJc(mat);
2183d79a51d8SBarry Smith   aj   = mxGetIr(mat);
2184d79a51d8SBarry Smith   ierr = PetscMemcpy(aj,aij->j,aij->nz*sizeof(int));CHKERRQ(ierr);
2185d79a51d8SBarry Smith   ierr = PetscMemcpy(ai,aij->i,(B->m+1)*sizeof(int));CHKERRQ(ierr);
2186f83d6046SBarry Smith 
2187d79a51d8SBarry Smith   /* Matlab indices always start at 1 */
2188d79a51d8SBarry Smith   if (!aij->indexshift) {
2189d79a51d8SBarry Smith     for (i=0; i<aij->m+1; i++) {
2190d79a51d8SBarry Smith       ai[i]++;
2191d79a51d8SBarry Smith     }
2192d79a51d8SBarry Smith     for (i=0; i<aij->nz; i++) {
2193d79a51d8SBarry Smith       aj[i]++;
2194d79a51d8SBarry Smith     }
2195d79a51d8SBarry Smith   }
2196*ca44d042SBarry Smith   ierr = PetscObjectName(obj);CHKERRQ(ierr);
2197f83d6046SBarry Smith   mxSetName(mat,obj->name);
2198f83d6046SBarry Smith   engPutArray((Engine *)engine,mat);
2199f83d6046SBarry Smith   PetscFunctionReturn(0);
2200f83d6046SBarry Smith }
2201f83d6046SBarry Smith EXTERN_C_END
2202f83d6046SBarry Smith #endif
2203f83d6046SBarry Smith 
2204be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
2205cb5b572fSBarry Smith 
2206bef8e0ddSBarry Smith #undef __FUNC__
2207*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatCreateSeqAIJ"></a>*/"MatCreateSeqAIJ"
220817ab2063SBarry Smith /*@C
2209682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
22100d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
22116e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
221251c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
22132bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
221417ab2063SBarry Smith 
2215db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2216db81eaa0SLois Curfman McInnes 
221717ab2063SBarry Smith    Input Parameters:
2218db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
221917ab2063SBarry Smith .  m - number of rows
222017ab2063SBarry Smith .  n - number of columns
222117ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
222251c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
22232bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
222417ab2063SBarry Smith 
222517ab2063SBarry Smith    Output Parameter:
2226416022c9SBarry Smith .  A - the matrix
222717ab2063SBarry Smith 
2228b259b22eSLois Curfman McInnes    Notes:
222917ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
223017ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
22310002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
223244cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
223317ab2063SBarry Smith 
223417ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2235a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
22363d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
22376da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
223817ab2063SBarry Smith 
2239682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
22404fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
2241682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
22426c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
22436c7ebb05SLois Curfman McInnes 
22446c7ebb05SLois Curfman McInnes    Options Database Keys:
2245db81eaa0SLois Curfman McInnes +  -mat_aij_no_inode  - Do not use inodes
2246db81eaa0SLois Curfman McInnes .  -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5)
2247db81eaa0SLois Curfman McInnes -  -mat_aij_oneindex - Internally use indexing starting at 1
2248db81eaa0SLois Curfman McInnes         rather than 0.  Note that when calling MatSetValues(),
2249db81eaa0SLois Curfman McInnes         the user still MUST index entries starting at 0!
225017ab2063SBarry Smith 
2251027ccd11SLois Curfman McInnes    Level: intermediate
2252027ccd11SLois Curfman McInnes 
225336db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
225436db0b34SBarry Smith 
225517ab2063SBarry Smith @*/
2256416022c9SBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,int *nnz,Mat *A)
225717ab2063SBarry Smith {
2258416022c9SBarry Smith   Mat        B;
2259416022c9SBarry Smith   Mat_SeqAIJ *b;
2260f1af5d2fSBarry Smith   int        i,len,ierr,size;
2261f1af5d2fSBarry Smith   PetscTruth flg;
22626945ee14SBarry Smith 
22633a40ed3dSBarry Smith   PetscFunctionBegin;
2264d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2265a8c6a408SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Comm must be of size 1");
2266d5d45c9bSBarry Smith 
2267b73539f3SBarry Smith   if (nz < -2) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"nz cannot be less than -2: value %d",nz);
2268b73539f3SBarry Smith   if (nnz) {
2269b73539f3SBarry Smith     for (i=0; i<m; i++) {
2270b73539f3SBarry 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]);
2271b73539f3SBarry Smith     }
2272b73539f3SBarry Smith   }
2273b73539f3SBarry Smith 
2274416022c9SBarry Smith   *A                  = 0;
22753f1db9ecSBarry Smith   PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,"Mat",comm,MatDestroy,MatView);
2276416022c9SBarry Smith   PLogObjectCreate(B);
22770452661fSBarry Smith   B->data             = (void*)(b = PetscNew(Mat_SeqAIJ));CHKPTRQ(b);
2278549d3d68SSatish Balay   ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr);
2279549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
2280e1311b90SBarry Smith   B->ops->destroy          = MatDestroy_SeqAIJ;
2281e1311b90SBarry Smith   B->ops->view             = MatView_SeqAIJ;
2282416022c9SBarry Smith   B->factor           = 0;
2283416022c9SBarry Smith   B->lupivotthreshold = 1.0;
228490f02eecSBarry Smith   B->mapping          = 0;
2285f1af5d2fSBarry Smith   ierr = OptionsGetDouble(PETSC_NULL,"-mat_lu_pivotthreshold",&B->lupivotthreshold,PETSC_NULL);CHKERRQ(ierr);
2286f1af5d2fSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-pc_ilu_preserve_row_sums",&b->ilu_preserve_row_sums);CHKERRQ(ierr);
2287416022c9SBarry Smith   b->row              = 0;
2288416022c9SBarry Smith   b->col              = 0;
228982bf6240SBarry Smith   b->icol             = 0;
2290416022c9SBarry Smith   b->indexshift       = 0;
2291b810aeb4SBarry Smith   b->reallocs         = 0;
229269957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_oneindex",&flg);CHKERRQ(ierr);
229369957df2SSatish Balay   if (flg) b->indexshift = -1;
229417ab2063SBarry Smith 
229544cd7ae7SLois Curfman McInnes   b->m = m; B->m = m; B->M = m;
229644cd7ae7SLois Curfman McInnes   b->n = n; B->n = n; B->N = n;
2297a5ae1ecdSBarry Smith 
22984d197716SBarry Smith   ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr);
22994d197716SBarry Smith   ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr);
2300a5ae1ecdSBarry Smith 
23010452661fSBarry Smith   b->imax = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(b->imax);
2302f1e2ffcdSBarry Smith   if (!nnz) {
23037b8455f0SLois Curfman McInnes     if (nz == PETSC_DEFAULT) nz = 10;
23047b8455f0SLois Curfman McInnes     else if (nz <= 0)        nz = 1;
2305416022c9SBarry Smith     for (i=0; i<m; i++) b->imax[i] = nz;
230617ab2063SBarry Smith     nz = nz*m;
23073a40ed3dSBarry Smith   } else {
230817ab2063SBarry Smith     nz = 0;
2309416022c9SBarry Smith     for (i=0; i<m; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
231017ab2063SBarry Smith   }
231117ab2063SBarry Smith 
231217ab2063SBarry Smith   /* allocate the matrix space */
2313416022c9SBarry Smith   len             = nz*(sizeof(int) + sizeof(Scalar)) + (b->m+1)*sizeof(int);
23140452661fSBarry Smith   b->a            = (Scalar*)PetscMalloc(len);CHKPTRQ(b->a);
2315416022c9SBarry Smith   b->j            = (int*)(b->a + nz);
2316549d3d68SSatish Balay   ierr            = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
2317416022c9SBarry Smith   b->i            = b->j + nz;
2318f1e2ffcdSBarry Smith   b->singlemalloc = PETSC_TRUE;
231936db0b34SBarry Smith   b->freedata     = PETSC_TRUE;
232017ab2063SBarry Smith 
2321416022c9SBarry Smith   b->i[0] = -b->indexshift;
232217ab2063SBarry Smith   for (i=1; i<m+1; i++) {
2323416022c9SBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
232417ab2063SBarry Smith   }
232517ab2063SBarry Smith 
2326416022c9SBarry Smith   /* b->ilen will count nonzeros in each row so far. */
23270452661fSBarry Smith   b->ilen = (int*)PetscMalloc((m+1)*sizeof(int));
2328f09e8eb9SSatish Balay   PLogObjectMemory(B,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2329416022c9SBarry Smith   for (i=0; i<b->m; i++) { b->ilen[i] = 0;}
233017ab2063SBarry Smith 
2331416022c9SBarry Smith   b->nz                = 0;
2332416022c9SBarry Smith   b->maxnz             = nz;
2333f1e2ffcdSBarry Smith   b->sorted            = PETSC_FALSE;
233436db0b34SBarry Smith   b->ignorezeroentries = PETSC_FALSE;
2335f1e2ffcdSBarry Smith   b->roworiented       = PETSC_TRUE;
2336416022c9SBarry Smith   b->nonew             = 0;
2337416022c9SBarry Smith   b->diag              = 0;
2338416022c9SBarry Smith   b->solve_work        = 0;
233971bd300dSLois Curfman McInnes   b->spptr             = 0;
2340b65db4caSBarry Smith   b->inode.use         = PETSC_TRUE;
2341754ec7b1SSatish Balay   b->inode.node_count  = 0;
2342754ec7b1SSatish Balay   b->inode.size        = 0;
23436c7ebb05SLois Curfman McInnes   b->inode.limit       = 5;
23446c7ebb05SLois Curfman McInnes   b->inode.max_limit   = 5;
2345be6bf707SBarry Smith   b->saved_values      = 0;
23464e220ebcSLois Curfman McInnes   B->info.nz_unneeded  = (double)b->maxnz;
2347d7f994e1SBarry Smith   b->idiag             = 0;
2348d7f994e1SBarry Smith   b->ssor              = 0;
2349f1e2ffcdSBarry Smith   b->keepzeroedrows    = PETSC_FALSE;
235017ab2063SBarry Smith 
2351416022c9SBarry Smith   *A = B;
23524e220ebcSLois Curfman McInnes 
23534b14c69eSBarry Smith   /*  SuperLU is not currently supported through PETSc */
2354aa482453SBarry Smith #if defined(PETSC_HAVE_SUPERLU)
235569957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_superlu",&flg);CHKERRQ(ierr);
235669957df2SSatish Balay   if (flg) { ierr = MatUseSuperLU_SeqAIJ(B);CHKERRQ(ierr); }
23574b14c69eSBarry Smith #endif
235869957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_essl",&flg);CHKERRQ(ierr);
235969957df2SSatish Balay   if (flg) { ierr = MatUseEssl_SeqAIJ(B);CHKERRQ(ierr); }
2360*ca44d042SBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_matlab",&flg);CHKERRQ(ierr);
2361*ca44d042SBarry Smith   if (flg) {ierr = MatUseMatlab_SeqAIJ(B);CHKERRQ(ierr);}
236269957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_dxml",&flg);CHKERRQ(ierr);
236369957df2SSatish Balay   if (flg) {
2364a8c6a408SBarry Smith     if (!b->indexshift) SETERRQ(PETSC_ERR_LIB,0,"need -mat_aij_oneindex with -mat_aij_dxml");
2365416022c9SBarry Smith     ierr = MatUseDXML_SeqAIJ(B);CHKERRQ(ierr);
236617ab2063SBarry Smith   }
236769957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr);
236869957df2SSatish Balay   if (flg) {ierr = MatPrintHelp(B);CHKERRQ(ierr); }
2369bef8e0ddSBarry Smith 
2370f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C",
2371bef8e0ddSBarry Smith                                      "MatSeqAIJSetColumnIndices_SeqAIJ",
2372bc4b532fSSatish Balay                                      MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
2373f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
2374be6bf707SBarry Smith                                      "MatStoreValues_SeqAIJ",
2375bc4b532fSSatish Balay                                      MatStoreValues_SeqAIJ);CHKERRQ(ierr);
2376f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
2377be6bf707SBarry Smith                                      "MatRetrieveValues_SeqAIJ",
2378bc4b532fSSatish Balay                                      MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
2379f83d6046SBarry Smith #if defined(PETSC_HAVE_MATLAB)
2380f83d6046SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatMatlabEnginePut_SeqAIJ",MatMatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
2381f83d6046SBarry Smith #endif
23823a40ed3dSBarry Smith   PetscFunctionReturn(0);
238317ab2063SBarry Smith }
238417ab2063SBarry Smith 
23855615d1e5SSatish Balay #undef __FUNC__
2386*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatDuplicate_SeqAIJ"></a>*/"MatDuplicate_SeqAIJ"
2387be6bf707SBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
238817ab2063SBarry Smith {
2389416022c9SBarry Smith   Mat        C;
2390416022c9SBarry Smith   Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data;
2391bef8e0ddSBarry Smith   int        i,len,m = a->m,shift = a->indexshift,ierr;
239217ab2063SBarry Smith 
23933a40ed3dSBarry Smith   PetscFunctionBegin;
23944043dd9cSLois Curfman McInnes   *B = 0;
23953f1db9ecSBarry Smith   PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,"Mat",A->comm,MatDestroy,MatView);
2396416022c9SBarry Smith   PLogObjectCreate(C);
23970452661fSBarry Smith   C->data           = (void*)(c = PetscNew(Mat_SeqAIJ));CHKPTRQ(c);
2398549d3d68SSatish Balay   ierr              = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
2399e1311b90SBarry Smith   C->ops->destroy   = MatDestroy_SeqAIJ;
2400e1311b90SBarry Smith   C->ops->view      = MatView_SeqAIJ;
2401416022c9SBarry Smith   C->factor         = A->factor;
2402416022c9SBarry Smith   c->row            = 0;
2403416022c9SBarry Smith   c->col            = 0;
240482bf6240SBarry Smith   c->icol           = 0;
2405416022c9SBarry Smith   c->indexshift     = shift;
2406f1e2ffcdSBarry Smith   c->keepzeroedrows = a->keepzeroedrows;
2407c456f294SBarry Smith   C->assembled      = PETSC_TRUE;
240817ab2063SBarry Smith 
240944cd7ae7SLois Curfman McInnes   c->m = C->m   = a->m;
241044cd7ae7SLois Curfman McInnes   c->n = C->n   = a->n;
241144cd7ae7SLois Curfman McInnes   C->M          = a->m;
241244cd7ae7SLois Curfman McInnes   C->N          = a->n;
241317ab2063SBarry Smith 
24140452661fSBarry Smith   c->imax       = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->imax);
24150452661fSBarry Smith   c->ilen       = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->ilen);
241617ab2063SBarry Smith   for (i=0; i<m; i++) {
2417416022c9SBarry Smith     c->imax[i] = a->imax[i];
2418416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
241917ab2063SBarry Smith   }
242017ab2063SBarry Smith 
242117ab2063SBarry Smith   /* allocate the matrix space */
2422f1e2ffcdSBarry Smith   c->singlemalloc = PETSC_TRUE;
2423416022c9SBarry Smith   len     = (m+1)*sizeof(int)+(a->i[m])*(sizeof(Scalar)+sizeof(int));
24240452661fSBarry Smith   c->a  = (Scalar*)PetscMalloc(len);CHKPTRQ(c->a);
2425416022c9SBarry Smith   c->j  = (int*)(c->a + a->i[m] + shift);
2426416022c9SBarry Smith   c->i  = c->j + a->i[m] + shift;
2427549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));CHKERRQ(ierr);
242817ab2063SBarry Smith   if (m > 0) {
2429549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,(a->i[m]+shift)*sizeof(int));CHKERRQ(ierr);
2430be6bf707SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
2431549d3d68SSatish Balay       ierr = PetscMemcpy(c->a,a->a,(a->i[m]+shift)*sizeof(Scalar));CHKERRQ(ierr);
2432be6bf707SBarry Smith     } else {
2433549d3d68SSatish Balay       ierr = PetscMemzero(c->a,(a->i[m]+shift)*sizeof(Scalar));CHKERRQ(ierr);
243417ab2063SBarry Smith     }
243508480c60SBarry Smith   }
243617ab2063SBarry Smith 
2437f09e8eb9SSatish Balay   PLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2438416022c9SBarry Smith   c->sorted      = a->sorted;
2439416022c9SBarry Smith   c->roworiented = a->roworiented;
2440416022c9SBarry Smith   c->nonew       = a->nonew;
24417a743949SBarry Smith   c->ilu_preserve_row_sums = a->ilu_preserve_row_sums;
2442be6bf707SBarry Smith   c->saved_values = 0;
2443d7f994e1SBarry Smith   c->idiag        = 0;
2444d7f994e1SBarry Smith   c->ssor         = 0;
244536db0b34SBarry Smith   c->ignorezeroentries = a->ignorezeroentries;
244636db0b34SBarry Smith   c->freedata     = PETSC_TRUE;
244717ab2063SBarry Smith 
2448416022c9SBarry Smith   if (a->diag) {
24490452661fSBarry Smith     c->diag = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->diag);
2450416022c9SBarry Smith     PLogObjectMemory(C,(m+1)*sizeof(int));
245117ab2063SBarry Smith     for (i=0; i<m; i++) {
2452416022c9SBarry Smith       c->diag[i] = a->diag[i];
245317ab2063SBarry Smith     }
24543a40ed3dSBarry Smith   } else c->diag        = 0;
2455b65db4caSBarry Smith   c->inode.use          = a->inode.use;
24566c7ebb05SLois Curfman McInnes   c->inode.limit        = a->inode.limit;
24576c7ebb05SLois Curfman McInnes   c->inode.max_limit    = a->inode.max_limit;
2458754ec7b1SSatish Balay   if (a->inode.size){
2459daed632aSSatish Balay     c->inode.size       = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->inode.size);
2460754ec7b1SSatish Balay     c->inode.node_count = a->inode.node_count;
2461549d3d68SSatish Balay     ierr = PetscMemcpy(c->inode.size,a->inode.size,(m+1)*sizeof(int));CHKERRQ(ierr);
2462754ec7b1SSatish Balay   } else {
2463754ec7b1SSatish Balay     c->inode.size       = 0;
2464754ec7b1SSatish Balay     c->inode.node_count = 0;
2465754ec7b1SSatish Balay   }
2466416022c9SBarry Smith   c->nz                 = a->nz;
2467416022c9SBarry Smith   c->maxnz              = a->maxnz;
2468416022c9SBarry Smith   c->solve_work         = 0;
246976dd722bSSatish Balay   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
2470754ec7b1SSatish Balay 
2471416022c9SBarry Smith   *B = C;
24727b2a1423SBarry Smith   ierr = FListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
24733a40ed3dSBarry Smith   PetscFunctionReturn(0);
247417ab2063SBarry Smith }
247517ab2063SBarry Smith 
24765615d1e5SSatish Balay #undef __FUNC__
2477*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatLoad_SeqAIJ"></a>*/"MatLoad_SeqAIJ"
247819bcc07fSBarry Smith int MatLoad_SeqAIJ(Viewer viewer,MatType type,Mat *A)
247917ab2063SBarry Smith {
2480416022c9SBarry Smith   Mat_SeqAIJ   *a;
2481416022c9SBarry Smith   Mat          B;
248217699dbbSLois Curfman McInnes   int          i,nz,ierr,fd,header[4],size,*rowlengths = 0,M,N,shift;
2483bcd2baecSBarry Smith   MPI_Comm     comm;
248417ab2063SBarry Smith 
24853a40ed3dSBarry Smith   PetscFunctionBegin;
2486e864ced6SBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
2487d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2488a8c6a408SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,0,"view must have one processor");
248990ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
24900752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
2491a8c6a408SBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not matrix object in file");
249217ab2063SBarry Smith   M = header[1]; N = header[2]; nz = header[3];
249317ab2063SBarry Smith 
2494d64ed03dSBarry Smith   if (nz < 0) {
2495a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format on disk,cannot load as SeqAIJ");
2496d64ed03dSBarry Smith   }
2497d64ed03dSBarry Smith 
249817ab2063SBarry Smith   /* read in row lengths */
24990452661fSBarry Smith   rowlengths = (int*)PetscMalloc(M*sizeof(int));CHKPTRQ(rowlengths);
25000752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
250117ab2063SBarry Smith 
250217ab2063SBarry Smith   /* create our matrix */
2503416022c9SBarry Smith   ierr = MatCreateSeqAIJ(comm,M,N,0,rowlengths,A);CHKERRQ(ierr);
2504416022c9SBarry Smith   B = *A;
2505416022c9SBarry Smith   a = (Mat_SeqAIJ*)B->data;
2506416022c9SBarry Smith   shift = a->indexshift;
250717ab2063SBarry Smith 
250817ab2063SBarry Smith   /* read in column indices and adjust for Fortran indexing*/
25090752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
251017ab2063SBarry Smith   if (shift) {
251117ab2063SBarry Smith     for (i=0; i<nz; i++) {
2512416022c9SBarry Smith       a->j[i] += 1;
251317ab2063SBarry Smith     }
251417ab2063SBarry Smith   }
251517ab2063SBarry Smith 
251617ab2063SBarry Smith   /* read in nonzero values */
25170752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
251817ab2063SBarry Smith 
251917ab2063SBarry Smith   /* set matrix "i" values */
2520416022c9SBarry Smith   a->i[0] = -shift;
252117ab2063SBarry Smith   for (i=1; i<= M; i++) {
2522416022c9SBarry Smith     a->i[i]      = a->i[i-1] + rowlengths[i-1];
2523416022c9SBarry Smith     a->ilen[i-1] = rowlengths[i-1];
252417ab2063SBarry Smith   }
2525606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
252617ab2063SBarry Smith 
25276d4a8577SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
25286d4a8577SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
25293a40ed3dSBarry Smith   PetscFunctionReturn(0);
253017ab2063SBarry Smith }
253117ab2063SBarry Smith 
25325615d1e5SSatish Balay #undef __FUNC__
2533*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatEqual_SeqAIJ""></a>*/"MatEqual_SeqAIJ"
25348f6be9afSLois Curfman McInnes int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg)
25357264ac53SSatish Balay {
25367264ac53SSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data;
25370f5bd95cSBarry Smith   int        ierr;
25387264ac53SSatish Balay 
25393a40ed3dSBarry Smith   PetscFunctionBegin;
2540a8c6a408SBarry Smith   if (B->type != MATSEQAIJ) SETERRQ(PETSC_ERR_ARG_INCOMP,0,"Matrices must be same type");
25417264ac53SSatish Balay 
25427264ac53SSatish Balay   /* If the  matrix dimensions are not equal,or no of nonzeros or shift */
2543*ca44d042SBarry Smith   if ((a->m != b->m) || (a->n !=b->n) ||(a->nz != b->nz)|| (a->indexshift != b->indexshift)) {
2544*ca44d042SBarry Smith     *flg = PETSC_FALSE;
2545*ca44d042SBarry Smith     PetscFunctionReturn(0);
2546bcd2baecSBarry Smith   }
25477264ac53SSatish Balay 
25487264ac53SSatish Balay   /* if the a->i are the same */
25490f5bd95cSBarry Smith   ierr = PetscMemcmp(a->i,b->i,(a->m+1)*sizeof(int),flg);CHKERRQ(ierr);
25500f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
25517264ac53SSatish Balay 
25527264ac53SSatish Balay   /* if a->j are the same */
25530f5bd95cSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(int),flg);CHKERRQ(ierr);
25540f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
2555bcd2baecSBarry Smith 
2556bcd2baecSBarry Smith   /* if a->a are the same */
25570f5bd95cSBarry Smith   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(Scalar),flg);CHKERRQ(ierr);
25580f5bd95cSBarry Smith 
25593a40ed3dSBarry Smith   PetscFunctionReturn(0);
25607264ac53SSatish Balay 
25617264ac53SSatish Balay }
256236db0b34SBarry Smith 
256336db0b34SBarry Smith #undef __FUNC__
2564*ca44d042SBarry Smith #define __FUNC__ /*<a name="MatCreateSeqAIJWithArrays"></a>*/"MatCreateSeqAIJWithArrays"
256536db0b34SBarry Smith /*@C
256636db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
256736db0b34SBarry Smith               provided by the user.
256836db0b34SBarry Smith 
256936db0b34SBarry Smith       Coolective on MPI_Comm
257036db0b34SBarry Smith 
257136db0b34SBarry Smith    Input Parameters:
257236db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
257336db0b34SBarry Smith .   m - number of rows
257436db0b34SBarry Smith .   n - number of columns
257536db0b34SBarry Smith .   i - row indices
257636db0b34SBarry Smith .   j - column indices
257736db0b34SBarry Smith -   a - matrix values
257836db0b34SBarry Smith 
257936db0b34SBarry Smith    Output Parameter:
258036db0b34SBarry Smith .   mat - the matrix
258136db0b34SBarry Smith 
258236db0b34SBarry Smith    Level: intermediate
258336db0b34SBarry Smith 
258436db0b34SBarry Smith    Notes:
25850551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
258636db0b34SBarry Smith     once the matrix is destroyed
258736db0b34SBarry Smith 
258836db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
258936db0b34SBarry Smith 
259036db0b34SBarry Smith        The i and j indices can be either 0- or 1 based
259136db0b34SBarry Smith 
259236db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ()
259336db0b34SBarry Smith 
259436db0b34SBarry Smith @*/
259536db0b34SBarry Smith int MatCreateSeqAIJWithArrays(MPI_Comm comm,int m,int n,int* i,int*j,Scalar *a,Mat *mat)
259636db0b34SBarry Smith {
259736db0b34SBarry Smith   int        ierr,ii;
259836db0b34SBarry Smith   Mat_SeqAIJ *aij;
259936db0b34SBarry Smith 
260036db0b34SBarry Smith   PetscFunctionBegin;
260136db0b34SBarry Smith   ierr = MatCreateSeqAIJ(comm,m,n,0,0,mat);CHKERRQ(ierr);
260236db0b34SBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
260336db0b34SBarry Smith   ierr = PetscFree(aij->a);CHKERRQ(ierr);
260436db0b34SBarry Smith 
260536db0b34SBarry Smith   if (i[0] == 1) {
260636db0b34SBarry Smith     aij->indexshift = -1;
260736db0b34SBarry Smith   } else if (i[0]) {
260836db0b34SBarry Smith     SETERRQ(1,1,"i (row indices) do not start with 0 or 1");
260936db0b34SBarry Smith   }
261036db0b34SBarry Smith   aij->i = i;
261136db0b34SBarry Smith   aij->j = j;
261236db0b34SBarry Smith   aij->a = a;
261336db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
261436db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
261536db0b34SBarry Smith   aij->freedata     = PETSC_FALSE;
261636db0b34SBarry Smith 
261736db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
261836db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
261936db0b34SBarry Smith #if defined(PETSC_BOPT_g)
262036db0b34SBarry 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]);
262136db0b34SBarry Smith #endif
262236db0b34SBarry Smith   }
262336db0b34SBarry Smith #if defined(PETSC_BOPT_g)
262436db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
262536db0b34SBarry Smith     if (j[ii] < -aij->indexshift) SETERRQ2(1,1,"Negative column index at location = %d index = %d",ii,j[ii]);
262636db0b34SBarry Smith     if (j[ii] > n - 1 -aij->indexshift) SETERRQ2(1,1,"Column index to large at location = %d index = %d",ii,j[ii]);
262736db0b34SBarry Smith   }
262836db0b34SBarry Smith #endif
262936db0b34SBarry Smith 
2630b65db4caSBarry Smith   /* changes indices to start at 0 */
2631b65db4caSBarry Smith   if (i[0]) {
2632b65db4caSBarry Smith     aij->indexshift = 0;
2633b65db4caSBarry Smith     for (ii=0; ii<m; ii++) {
2634b65db4caSBarry Smith       i[ii]--;
2635b65db4caSBarry Smith     }
2636b65db4caSBarry Smith     for (ii=0; ii<i[m]; ii++) {
2637b65db4caSBarry Smith       j[ii]--;
2638b65db4caSBarry Smith     }
2639b65db4caSBarry Smith   }
2640b65db4caSBarry Smith 
2641b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2642b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
264336db0b34SBarry Smith   PetscFunctionReturn(0);
264436db0b34SBarry Smith }
264536db0b34SBarry Smith 
264636db0b34SBarry Smith 
264736db0b34SBarry Smith 
2648