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