xref: /petsc/src/mat/impls/maij/maij.c (revision 82b1193eee9f666742c183d573eedc8cddd6dfd8)
1*82b1193eSBarry Smith /*$Id: aij.c,v 1.351 2000/05/13 14:19:29 bsmith Exp bsmith $*/
2*82b1193eSBarry Smith /*
3*82b1193eSBarry Smith     Defines the basic matrix operations for the AIJ (compressed row)
4*82b1193eSBarry Smith   matrix storage format.
5*82b1193eSBarry Smith */
6*82b1193eSBarry Smith 
7*82b1193eSBarry Smith #include "petscsys.h"
8*82b1193eSBarry Smith #include "src/mat/impls/aij/seq/aij.h"
9*82b1193eSBarry Smith #include "src/vec/vecimpl.h"
10*82b1193eSBarry Smith #include "src/inline/spops.h"
11*82b1193eSBarry Smith #include "src/inline/dot.h"
12*82b1193eSBarry Smith #include "petscbt.h"
13*82b1193eSBarry Smith 
14*82b1193eSBarry Smith 
15*82b1193eSBarry Smith EXTERN int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**);
16*82b1193eSBarry Smith 
17*82b1193eSBarry Smith #undef __FUNC__
18*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetRowIJ_SeqAIJ"></a>*/"MatGetRowIJ_SeqAIJ"
19*82b1193eSBarry Smith int MatGetRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *m,int **ia,int **ja,PetscTruth *done)
20*82b1193eSBarry Smith {
21*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
22*82b1193eSBarry Smith   int        ierr,i,ishift;
23*82b1193eSBarry Smith 
24*82b1193eSBarry Smith   PetscFunctionBegin;
25*82b1193eSBarry Smith   *m     = A->m;
26*82b1193eSBarry Smith   if (!ia) PetscFunctionReturn(0);
27*82b1193eSBarry Smith   ishift = a->indexshift;
28*82b1193eSBarry Smith   if (symmetric) {
29*82b1193eSBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr);
30*82b1193eSBarry Smith   } else if (oshift == 0 && ishift == -1) {
31*82b1193eSBarry Smith     int nz = a->i[a->m];
32*82b1193eSBarry Smith     /* malloc space and  subtract 1 from i and j indices */
33*82b1193eSBarry Smith     *ia = (int*)PetscMalloc((a->m+1)*sizeof(int));CHKPTRQ(*ia);
34*82b1193eSBarry Smith     *ja = (int*)PetscMalloc((nz+1)*sizeof(int));CHKPTRQ(*ja);
35*82b1193eSBarry Smith     for (i=0; i<nz; i++) (*ja)[i] = a->j[i] - 1;
36*82b1193eSBarry Smith     for (i=0; i<a->m+1; i++) (*ia)[i] = a->i[i] - 1;
37*82b1193eSBarry Smith   } else if (oshift == 1 && ishift == 0) {
38*82b1193eSBarry Smith     int nz = a->i[a->m] + 1;
39*82b1193eSBarry Smith     /* malloc space and  add 1 to i and j indices */
40*82b1193eSBarry Smith     *ia = (int*)PetscMalloc((a->m+1)*sizeof(int));CHKPTRQ(*ia);
41*82b1193eSBarry Smith     *ja = (int*)PetscMalloc((nz+1)*sizeof(int));CHKPTRQ(*ja);
42*82b1193eSBarry Smith     for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1;
43*82b1193eSBarry Smith     for (i=0; i<a->m+1; i++) (*ia)[i] = a->i[i] + 1;
44*82b1193eSBarry Smith   } else {
45*82b1193eSBarry Smith     *ia = a->i; *ja = a->j;
46*82b1193eSBarry Smith   }
47*82b1193eSBarry Smith   PetscFunctionReturn(0);
48*82b1193eSBarry Smith }
49*82b1193eSBarry Smith 
50*82b1193eSBarry Smith #undef __FUNC__
51*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatRestoreRowIJ_SeqAIJ"></a>*/"MatRestoreRowIJ_SeqAIJ"
52*82b1193eSBarry Smith int MatRestoreRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja,PetscTruth *done)
53*82b1193eSBarry Smith {
54*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
55*82b1193eSBarry Smith   int        ishift = a->indexshift,ierr;
56*82b1193eSBarry Smith 
57*82b1193eSBarry Smith   PetscFunctionBegin;
58*82b1193eSBarry Smith   if (!ia) PetscFunctionReturn(0);
59*82b1193eSBarry Smith   if (symmetric || (oshift == 0 && ishift == -1) || (oshift == 1 && ishift == 0)) {
60*82b1193eSBarry Smith     ierr = PetscFree(*ia);CHKERRQ(ierr);
61*82b1193eSBarry Smith     ierr = PetscFree(*ja);CHKERRQ(ierr);
62*82b1193eSBarry Smith   }
63*82b1193eSBarry Smith   PetscFunctionReturn(0);
64*82b1193eSBarry Smith }
65*82b1193eSBarry Smith 
66*82b1193eSBarry Smith #undef __FUNC__
67*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetColumnIJ_SeqAIJ"></a>*/"MatGetColumnIJ_SeqAIJ"
68*82b1193eSBarry Smith int MatGetColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done)
69*82b1193eSBarry Smith {
70*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
71*82b1193eSBarry Smith   int        ierr,i,ishift = a->indexshift,*collengths,*cia,*cja,n = A->n,m = A->m;
72*82b1193eSBarry Smith   int        nz = a->i[m]+ishift,row,*jj,mr,col;
73*82b1193eSBarry Smith 
74*82b1193eSBarry Smith   PetscFunctionBegin;
75*82b1193eSBarry Smith   *nn     = A->n;
76*82b1193eSBarry Smith   if (!ia) PetscFunctionReturn(0);
77*82b1193eSBarry Smith   if (symmetric) {
78*82b1193eSBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr);
79*82b1193eSBarry Smith   } else {
80*82b1193eSBarry Smith     collengths = (int*)PetscMalloc((n+1)*sizeof(int));CHKPTRQ(collengths);
81*82b1193eSBarry Smith     ierr       = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr);
82*82b1193eSBarry Smith     cia        = (int*)PetscMalloc((n+1)*sizeof(int));CHKPTRQ(cia);
83*82b1193eSBarry Smith     cja        = (int*)PetscMalloc((nz+1)*sizeof(int));CHKPTRQ(cja);
84*82b1193eSBarry Smith     jj = a->j;
85*82b1193eSBarry Smith     for (i=0; i<nz; i++) {
86*82b1193eSBarry Smith       collengths[jj[i] + ishift]++;
87*82b1193eSBarry Smith     }
88*82b1193eSBarry Smith     cia[0] = oshift;
89*82b1193eSBarry Smith     for (i=0; i<n; i++) {
90*82b1193eSBarry Smith       cia[i+1] = cia[i] + collengths[i];
91*82b1193eSBarry Smith     }
92*82b1193eSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr);
93*82b1193eSBarry Smith     jj   = a->j;
94*82b1193eSBarry Smith     for (row=0; row<m; row++) {
95*82b1193eSBarry Smith       mr = a->i[row+1] - a->i[row];
96*82b1193eSBarry Smith       for (i=0; i<mr; i++) {
97*82b1193eSBarry Smith         col = *jj++ + ishift;
98*82b1193eSBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
99*82b1193eSBarry Smith       }
100*82b1193eSBarry Smith     }
101*82b1193eSBarry Smith     ierr = PetscFree(collengths);CHKERRQ(ierr);
102*82b1193eSBarry Smith     *ia = cia; *ja = cja;
103*82b1193eSBarry Smith   }
104*82b1193eSBarry Smith   PetscFunctionReturn(0);
105*82b1193eSBarry Smith }
106*82b1193eSBarry Smith 
107*82b1193eSBarry Smith #undef __FUNC__
108*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatRestoreColumnIJ_SeqAIJ"></a>*/"MatRestoreColumnIJ_SeqAIJ"
109*82b1193eSBarry Smith int MatRestoreColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja,PetscTruth *done)
110*82b1193eSBarry Smith {
111*82b1193eSBarry Smith   int ierr;
112*82b1193eSBarry Smith 
113*82b1193eSBarry Smith   PetscFunctionBegin;
114*82b1193eSBarry Smith   if (!ia) PetscFunctionReturn(0);
115*82b1193eSBarry Smith 
116*82b1193eSBarry Smith   ierr = PetscFree(*ia);CHKERRQ(ierr);
117*82b1193eSBarry Smith   ierr = PetscFree(*ja);CHKERRQ(ierr);
118*82b1193eSBarry Smith 
119*82b1193eSBarry Smith   PetscFunctionReturn(0);
120*82b1193eSBarry Smith }
121*82b1193eSBarry Smith 
122*82b1193eSBarry Smith #define CHUNKSIZE   15
123*82b1193eSBarry Smith 
124*82b1193eSBarry Smith #undef __FUNC__
125*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatSetValues_SeqAIJ"></a>*/"MatSetValues_SeqAIJ"
126*82b1193eSBarry Smith int MatSetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
127*82b1193eSBarry Smith {
128*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
129*82b1193eSBarry Smith   int        *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted = a->sorted;
130*82b1193eSBarry Smith   int        *imax = a->imax,*ai = a->i,*ailen = a->ilen,roworiented = a->roworiented;
131*82b1193eSBarry Smith   int        *aj = a->j,nonew = a->nonew,shift = a->indexshift,ierr;
132*82b1193eSBarry Smith   Scalar     *ap,value,*aa = a->a;
133*82b1193eSBarry Smith   PetscTruth ignorezeroentries = ((a->ignorezeroentries && is == ADD_VALUES) ? PETSC_TRUE:PETSC_FALSE);
134*82b1193eSBarry Smith 
135*82b1193eSBarry Smith   PetscFunctionBegin;
136*82b1193eSBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
137*82b1193eSBarry Smith     row  = im[k];
138*82b1193eSBarry Smith     if (row < 0) continue;
139*82b1193eSBarry Smith #if defined(PETSC_USE_BOPT_g)
140*82b1193eSBarry Smith     if (row >= a->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large: row %d max %d",row,a->m);
141*82b1193eSBarry Smith #endif
142*82b1193eSBarry Smith     rp   = aj + ai[row] + shift; ap = aa + ai[row] + shift;
143*82b1193eSBarry Smith     rmax = imax[row]; nrow = ailen[row];
144*82b1193eSBarry Smith     low = 0;
145*82b1193eSBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
146*82b1193eSBarry Smith       if (in[l] < 0) continue;
147*82b1193eSBarry Smith #if defined(PETSC_USE_BOPT_g)
148*82b1193eSBarry Smith       if (in[l] >= a->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large: col %d max %d",in[l],a->n);
149*82b1193eSBarry Smith #endif
150*82b1193eSBarry Smith       col = in[l] - shift;
151*82b1193eSBarry Smith       if (roworiented) {
152*82b1193eSBarry Smith         value = v[l + k*n];
153*82b1193eSBarry Smith       } else {
154*82b1193eSBarry Smith         value = v[k + l*m];
155*82b1193eSBarry Smith       }
156*82b1193eSBarry Smith       if (value == 0.0 && ignorezeroentries) continue;
157*82b1193eSBarry Smith 
158*82b1193eSBarry Smith       if (!sorted) low = 0; high = nrow;
159*82b1193eSBarry Smith       while (high-low > 5) {
160*82b1193eSBarry Smith         t = (low+high)/2;
161*82b1193eSBarry Smith         if (rp[t] > col) high = t;
162*82b1193eSBarry Smith         else             low  = t;
163*82b1193eSBarry Smith       }
164*82b1193eSBarry Smith       for (i=low; i<high; i++) {
165*82b1193eSBarry Smith         if (rp[i] > col) break;
166*82b1193eSBarry Smith         if (rp[i] == col) {
167*82b1193eSBarry Smith           if (is == ADD_VALUES) ap[i] += value;
168*82b1193eSBarry Smith           else                  ap[i] = value;
169*82b1193eSBarry Smith           goto noinsert;
170*82b1193eSBarry Smith         }
171*82b1193eSBarry Smith       }
172*82b1193eSBarry Smith       if (nonew == 1) goto noinsert;
173*82b1193eSBarry Smith       else if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero at (%d,%d) in the matrix",row,col);
174*82b1193eSBarry Smith       if (nrow >= rmax) {
175*82b1193eSBarry Smith         /* there is no extra room in row, therefore enlarge */
176*82b1193eSBarry Smith         int    new_nz = ai[a->m] + CHUNKSIZE,len,*new_i,*new_j;
177*82b1193eSBarry Smith         Scalar *new_a;
178*82b1193eSBarry Smith 
179*82b1193eSBarry Smith         if (nonew == -2) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero at (%d,%d) in the matrix requiring new malloc()",row,col);
180*82b1193eSBarry Smith 
181*82b1193eSBarry Smith         /* malloc new storage space */
182*82b1193eSBarry Smith         len     = new_nz*(sizeof(int)+sizeof(Scalar))+(a->m+1)*sizeof(int);
183*82b1193eSBarry Smith         new_a   = (Scalar*)PetscMalloc(len);CHKPTRQ(new_a);
184*82b1193eSBarry Smith         new_j   = (int*)(new_a + new_nz);
185*82b1193eSBarry Smith         new_i   = new_j + new_nz;
186*82b1193eSBarry Smith 
187*82b1193eSBarry Smith         /* copy over old data into new slots */
188*82b1193eSBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
189*82b1193eSBarry Smith         for (ii=row+1; ii<a->m+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
190*82b1193eSBarry Smith         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow+shift)*sizeof(int));CHKERRQ(ierr);
191*82b1193eSBarry Smith         len  = (new_nz - CHUNKSIZE - ai[row] - nrow - shift);
192*82b1193eSBarry Smith         ierr = PetscMemcpy(new_j+ai[row]+shift+nrow+CHUNKSIZE,aj+ai[row]+shift+nrow,len*sizeof(int));CHKERRQ(ierr);
193*82b1193eSBarry Smith         ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow+shift)*sizeof(Scalar));CHKERRQ(ierr);
194*82b1193eSBarry Smith         ierr = PetscMemcpy(new_a+ai[row]+shift+nrow+CHUNKSIZE,aa+ai[row]+shift+nrow,len*sizeof(Scalar));CHKERRQ(ierr);
195*82b1193eSBarry Smith         /* free up old matrix storage */
196*82b1193eSBarry Smith         ierr = PetscFree(a->a);CHKERRQ(ierr);
197*82b1193eSBarry Smith         if (!a->singlemalloc) {
198*82b1193eSBarry Smith           ierr = PetscFree(a->i);CHKERRQ(ierr);
199*82b1193eSBarry Smith           ierr = PetscFree(a->j);CHKERRQ(ierr);
200*82b1193eSBarry Smith         }
201*82b1193eSBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
202*82b1193eSBarry Smith         a->singlemalloc = PETSC_TRUE;
203*82b1193eSBarry Smith 
204*82b1193eSBarry Smith         rp   = aj + ai[row] + shift; ap = aa + ai[row] + shift;
205*82b1193eSBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
206*82b1193eSBarry Smith         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + sizeof(Scalar)));
207*82b1193eSBarry Smith         a->maxnz += CHUNKSIZE;
208*82b1193eSBarry Smith         a->reallocs++;
209*82b1193eSBarry Smith       }
210*82b1193eSBarry Smith       N = nrow++ - 1; a->nz++;
211*82b1193eSBarry Smith       /* shift up all the later entries in this row */
212*82b1193eSBarry Smith       for (ii=N; ii>=i; ii--) {
213*82b1193eSBarry Smith         rp[ii+1] = rp[ii];
214*82b1193eSBarry Smith         ap[ii+1] = ap[ii];
215*82b1193eSBarry Smith       }
216*82b1193eSBarry Smith       rp[i] = col;
217*82b1193eSBarry Smith       ap[i] = value;
218*82b1193eSBarry Smith       noinsert:;
219*82b1193eSBarry Smith       low = i + 1;
220*82b1193eSBarry Smith     }
221*82b1193eSBarry Smith     ailen[row] = nrow;
222*82b1193eSBarry Smith   }
223*82b1193eSBarry Smith   PetscFunctionReturn(0);
224*82b1193eSBarry Smith }
225*82b1193eSBarry Smith 
226*82b1193eSBarry Smith #undef __FUNC__
227*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetValues_SeqAIJ"></a>*/"MatGetValues_SeqAIJ"
228*82b1193eSBarry Smith int MatGetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v)
229*82b1193eSBarry Smith {
230*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
231*82b1193eSBarry Smith   int        *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
232*82b1193eSBarry Smith   int        *ai = a->i,*ailen = a->ilen,shift = a->indexshift;
233*82b1193eSBarry Smith   Scalar     *ap,*aa = a->a,zero = 0.0;
234*82b1193eSBarry Smith 
235*82b1193eSBarry Smith   PetscFunctionBegin;
236*82b1193eSBarry Smith   for (k=0; k<m; k++) { /* loop over rows */
237*82b1193eSBarry Smith     row  = im[k];
238*82b1193eSBarry Smith     if (row < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row: %d",row);
239*82b1193eSBarry Smith     if (row >= a->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large: %d",row);
240*82b1193eSBarry Smith     rp   = aj + ai[row] + shift; ap = aa + ai[row] + shift;
241*82b1193eSBarry Smith     nrow = ailen[row];
242*82b1193eSBarry Smith     for (l=0; l<n; l++) { /* loop over columns */
243*82b1193eSBarry Smith       if (in[l] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column: %d",in[l]);
244*82b1193eSBarry Smith       if (in[l] >= a->n) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large: %d",in[l]);
245*82b1193eSBarry Smith       col = in[l] - shift;
246*82b1193eSBarry Smith       high = nrow; low = 0; /* assume unsorted */
247*82b1193eSBarry Smith       while (high-low > 5) {
248*82b1193eSBarry Smith         t = (low+high)/2;
249*82b1193eSBarry Smith         if (rp[t] > col) high = t;
250*82b1193eSBarry Smith         else             low  = t;
251*82b1193eSBarry Smith       }
252*82b1193eSBarry Smith       for (i=low; i<high; i++) {
253*82b1193eSBarry Smith         if (rp[i] > col) break;
254*82b1193eSBarry Smith         if (rp[i] == col) {
255*82b1193eSBarry Smith           *v++ = ap[i];
256*82b1193eSBarry Smith           goto finished;
257*82b1193eSBarry Smith         }
258*82b1193eSBarry Smith       }
259*82b1193eSBarry Smith       *v++ = zero;
260*82b1193eSBarry Smith       finished:;
261*82b1193eSBarry Smith     }
262*82b1193eSBarry Smith   }
263*82b1193eSBarry Smith   PetscFunctionReturn(0);
264*82b1193eSBarry Smith }
265*82b1193eSBarry Smith 
266*82b1193eSBarry Smith 
267*82b1193eSBarry Smith #undef __FUNC__
268*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatView_SeqAIJ_Binary"></a>*/"MatView_SeqAIJ_Binary"
269*82b1193eSBarry Smith int MatView_SeqAIJ_Binary(Mat A,Viewer viewer)
270*82b1193eSBarry Smith {
271*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
272*82b1193eSBarry Smith   int        i,fd,*col_lens,ierr;
273*82b1193eSBarry Smith 
274*82b1193eSBarry Smith   PetscFunctionBegin;
275*82b1193eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
276*82b1193eSBarry Smith   col_lens = (int*)PetscMalloc((4+a->m)*sizeof(int));CHKPTRQ(col_lens);
277*82b1193eSBarry Smith   col_lens[0] = MAT_COOKIE;
278*82b1193eSBarry Smith   col_lens[1] = a->m;
279*82b1193eSBarry Smith   col_lens[2] = a->n;
280*82b1193eSBarry Smith   col_lens[3] = a->nz;
281*82b1193eSBarry Smith 
282*82b1193eSBarry Smith   /* store lengths of each row and write (including header) to file */
283*82b1193eSBarry Smith   for (i=0; i<a->m; i++) {
284*82b1193eSBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
285*82b1193eSBarry Smith   }
286*82b1193eSBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1);CHKERRQ(ierr);
287*82b1193eSBarry Smith   ierr = PetscFree(col_lens);CHKERRQ(ierr);
288*82b1193eSBarry Smith 
289*82b1193eSBarry Smith   /* store column indices (zero start index) */
290*82b1193eSBarry Smith   if (a->indexshift) {
291*82b1193eSBarry Smith     for (i=0; i<a->nz; i++) a->j[i]--;
292*82b1193eSBarry Smith   }
293*82b1193eSBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,0);CHKERRQ(ierr);
294*82b1193eSBarry Smith   if (a->indexshift) {
295*82b1193eSBarry Smith     for (i=0; i<a->nz; i++) a->j[i]++;
296*82b1193eSBarry Smith   }
297*82b1193eSBarry Smith 
298*82b1193eSBarry Smith   /* store nonzero values */
299*82b1193eSBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
300*82b1193eSBarry Smith   PetscFunctionReturn(0);
301*82b1193eSBarry Smith }
302*82b1193eSBarry Smith 
303*82b1193eSBarry Smith #undef __FUNC__
304*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatView_SeqAIJ_ASCII"></a>*/"MatView_SeqAIJ_ASCII"
305*82b1193eSBarry Smith int MatView_SeqAIJ_ASCII(Mat A,Viewer viewer)
306*82b1193eSBarry Smith {
307*82b1193eSBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ*)A->data;
308*82b1193eSBarry Smith   int         ierr,i,j,m = a->m,shift = a->indexshift,format;
309*82b1193eSBarry Smith   char        *outputname;
310*82b1193eSBarry Smith 
311*82b1193eSBarry Smith   PetscFunctionBegin;
312*82b1193eSBarry Smith   ierr = ViewerGetOutputname(viewer,&outputname);CHKERRQ(ierr);
313*82b1193eSBarry Smith   ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr);
314*82b1193eSBarry Smith   if (format == VIEWER_FORMAT_ASCII_INFO_LONG || format == VIEWER_FORMAT_ASCII_INFO) {
315*82b1193eSBarry Smith     if (a->inode.size) {
316*82b1193eSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"using I-node routines: found %d nodes, limit used is %d\n",a->inode.node_count,a->inode.limit);CHKERRQ(ierr);
317*82b1193eSBarry Smith     } else {
318*82b1193eSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"not using I-node routines\n");CHKERRQ(ierr);
319*82b1193eSBarry Smith     }
320*82b1193eSBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_MATLAB) {
321*82b1193eSBarry Smith     int nofinalvalue = 0;
322*82b1193eSBarry Smith     if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != a->n-!shift)) {
323*82b1193eSBarry Smith       nofinalvalue = 1;
324*82b1193eSBarry Smith     }
325*82b1193eSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
326*82b1193eSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"%% Size = %d %d \n",m,a->n);CHKERRQ(ierr);
327*82b1193eSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"%% Nonzeros = %d \n",a->nz);CHKERRQ(ierr);
328*82b1193eSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"zzz = zeros(%d,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
329*82b1193eSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
330*82b1193eSBarry Smith 
331*82b1193eSBarry Smith     for (i=0; i<m; i++) {
332*82b1193eSBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
333*82b1193eSBarry Smith #if defined(PETSC_USE_COMPLEX)
334*82b1193eSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"%d %d  %18.16e + %18.16ei \n",i+1,a->j[j]+!shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
335*82b1193eSBarry Smith #else
336*82b1193eSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"%d %d  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
337*82b1193eSBarry Smith #endif
338*82b1193eSBarry Smith       }
339*82b1193eSBarry Smith     }
340*82b1193eSBarry Smith     if (nofinalvalue) {
341*82b1193eSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"%d %d  %18.16e\n",m,a->n,0.0);CHKERRQ(ierr);
342*82b1193eSBarry Smith     }
343*82b1193eSBarry Smith     if (outputname) {ierr = ViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",outputname);CHKERRQ(ierr);}
344*82b1193eSBarry Smith     else            {ierr = ViewerASCIIPrintf(viewer,"];\n M = spconvert(zzz);\n");CHKERRQ(ierr);}
345*82b1193eSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
346*82b1193eSBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_COMMON) {
347*82b1193eSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
348*82b1193eSBarry Smith     for (i=0; i<m; i++) {
349*82b1193eSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr);
350*82b1193eSBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
351*82b1193eSBarry Smith #if defined(PETSC_USE_COMPLEX)
352*82b1193eSBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
353*82b1193eSBarry Smith           ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
354*82b1193eSBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
355*82b1193eSBarry Smith           ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
356*82b1193eSBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
357*82b1193eSBarry Smith           ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
358*82b1193eSBarry Smith         }
359*82b1193eSBarry Smith #else
360*82b1193eSBarry Smith         if (a->a[j] != 0.0) {ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);}
361*82b1193eSBarry Smith #endif
362*82b1193eSBarry Smith       }
363*82b1193eSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
364*82b1193eSBarry Smith     }
365*82b1193eSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
366*82b1193eSBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_SYMMODU) {
367*82b1193eSBarry Smith     int nzd=0,fshift=1,*sptr;
368*82b1193eSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
369*82b1193eSBarry Smith     sptr = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(sptr);
370*82b1193eSBarry Smith     for (i=0; i<m; i++) {
371*82b1193eSBarry Smith       sptr[i] = nzd+1;
372*82b1193eSBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
373*82b1193eSBarry Smith         if (a->j[j] >= i) {
374*82b1193eSBarry Smith #if defined(PETSC_USE_COMPLEX)
375*82b1193eSBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
376*82b1193eSBarry Smith #else
377*82b1193eSBarry Smith           if (a->a[j] != 0.0) nzd++;
378*82b1193eSBarry Smith #endif
379*82b1193eSBarry Smith         }
380*82b1193eSBarry Smith       }
381*82b1193eSBarry Smith     }
382*82b1193eSBarry Smith     sptr[m] = nzd+1;
383*82b1193eSBarry Smith     ierr = ViewerASCIIPrintf(viewer," %d %d\n\n",m,nzd);CHKERRQ(ierr);
384*82b1193eSBarry Smith     for (i=0; i<m+1; i+=6) {
385*82b1193eSBarry Smith       if (i+4<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4],sptr[i+5]);CHKERRQ(ierr);}
386*82b1193eSBarry Smith       else if (i+3<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4]);CHKERRQ(ierr);}
387*82b1193eSBarry Smith       else if (i+2<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);}
388*82b1193eSBarry Smith       else if (i+1<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);}
389*82b1193eSBarry Smith       else if (i<m)   {ierr = ViewerASCIIPrintf(viewer," %d %d\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);}
390*82b1193eSBarry Smith       else            {ierr = ViewerASCIIPrintf(viewer," %d\n",sptr[i]);CHKERRQ(ierr);}
391*82b1193eSBarry Smith     }
392*82b1193eSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
393*82b1193eSBarry Smith     ierr = PetscFree(sptr);CHKERRQ(ierr);
394*82b1193eSBarry Smith     for (i=0; i<m; i++) {
395*82b1193eSBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
396*82b1193eSBarry Smith         if (a->j[j] >= i) {ierr = ViewerASCIIPrintf(viewer," %d ",a->j[j]+fshift);CHKERRQ(ierr);}
397*82b1193eSBarry Smith       }
398*82b1193eSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
399*82b1193eSBarry Smith     }
400*82b1193eSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
401*82b1193eSBarry Smith     for (i=0; i<m; i++) {
402*82b1193eSBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
403*82b1193eSBarry Smith         if (a->j[j] >= i) {
404*82b1193eSBarry Smith #if defined(PETSC_USE_COMPLEX)
405*82b1193eSBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
406*82b1193eSBarry Smith             ierr = ViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
407*82b1193eSBarry Smith           }
408*82b1193eSBarry Smith #else
409*82b1193eSBarry Smith           if (a->a[j] != 0.0) {ierr = ViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
410*82b1193eSBarry Smith #endif
411*82b1193eSBarry Smith         }
412*82b1193eSBarry Smith       }
413*82b1193eSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
414*82b1193eSBarry Smith     }
415*82b1193eSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
416*82b1193eSBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_DENSE) {
417*82b1193eSBarry Smith     int    cnt = 0,jcnt;
418*82b1193eSBarry Smith     Scalar value;
419*82b1193eSBarry Smith 
420*82b1193eSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
421*82b1193eSBarry Smith     for (i=0; i<m; i++) {
422*82b1193eSBarry Smith       jcnt = 0;
423*82b1193eSBarry Smith       for (j=0; j<a->n; j++) {
424*82b1193eSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
425*82b1193eSBarry Smith           value = a->a[cnt++];
426*82b1193eSBarry Smith           jcnt++;
427*82b1193eSBarry Smith         } else {
428*82b1193eSBarry Smith           value = 0.0;
429*82b1193eSBarry Smith         }
430*82b1193eSBarry Smith #if defined(PETSC_USE_COMPLEX)
431*82b1193eSBarry Smith         ierr = ViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
432*82b1193eSBarry Smith #else
433*82b1193eSBarry Smith         ierr = ViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
434*82b1193eSBarry Smith #endif
435*82b1193eSBarry Smith       }
436*82b1193eSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
437*82b1193eSBarry Smith     }
438*82b1193eSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
439*82b1193eSBarry Smith   } else {
440*82b1193eSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
441*82b1193eSBarry Smith     for (i=0; i<m; i++) {
442*82b1193eSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr);
443*82b1193eSBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
444*82b1193eSBarry Smith #if defined(PETSC_USE_COMPLEX)
445*82b1193eSBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0) {
446*82b1193eSBarry Smith           ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
447*82b1193eSBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
448*82b1193eSBarry Smith           ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
449*82b1193eSBarry Smith         } else {
450*82b1193eSBarry Smith           ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
451*82b1193eSBarry Smith         }
452*82b1193eSBarry Smith #else
453*82b1193eSBarry Smith         ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
454*82b1193eSBarry Smith #endif
455*82b1193eSBarry Smith       }
456*82b1193eSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
457*82b1193eSBarry Smith     }
458*82b1193eSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
459*82b1193eSBarry Smith   }
460*82b1193eSBarry Smith   ierr = ViewerFlush(viewer);CHKERRQ(ierr);
461*82b1193eSBarry Smith   PetscFunctionReturn(0);
462*82b1193eSBarry Smith }
463*82b1193eSBarry Smith 
464*82b1193eSBarry Smith #undef __FUNC__
465*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatView_SeqAIJ_Draw_Zoom"></a>*/"MatView_SeqAIJ_Draw_Zoom"
466*82b1193eSBarry Smith int MatView_SeqAIJ_Draw_Zoom(Draw draw,void *Aa)
467*82b1193eSBarry Smith {
468*82b1193eSBarry Smith   Mat         A = (Mat) Aa;
469*82b1193eSBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ*)A->data;
470*82b1193eSBarry Smith   int         ierr,i,j,m = a->m,shift = a->indexshift,color;
471*82b1193eSBarry Smith   int         format;
472*82b1193eSBarry Smith   PetscReal   xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
473*82b1193eSBarry Smith   Viewer      viewer;
474*82b1193eSBarry Smith 
475*82b1193eSBarry Smith   PetscFunctionBegin;
476*82b1193eSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
477*82b1193eSBarry Smith   ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr);
478*82b1193eSBarry Smith 
479*82b1193eSBarry Smith   ierr = DrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
480*82b1193eSBarry Smith   /* loop over matrix elements drawing boxes */
481*82b1193eSBarry Smith 
482*82b1193eSBarry Smith   if (format != VIEWER_FORMAT_DRAW_CONTOUR) {
483*82b1193eSBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
484*82b1193eSBarry Smith     color = DRAW_BLUE;
485*82b1193eSBarry Smith     for (i=0; i<m; i++) {
486*82b1193eSBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
487*82b1193eSBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
488*82b1193eSBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
489*82b1193eSBarry Smith #if defined(PETSC_USE_COMPLEX)
490*82b1193eSBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
491*82b1193eSBarry Smith #else
492*82b1193eSBarry Smith         if (a->a[j] >=  0.) continue;
493*82b1193eSBarry Smith #endif
494*82b1193eSBarry Smith         ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
495*82b1193eSBarry Smith       }
496*82b1193eSBarry Smith     }
497*82b1193eSBarry Smith     color = DRAW_CYAN;
498*82b1193eSBarry Smith     for (i=0; i<m; i++) {
499*82b1193eSBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
500*82b1193eSBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
501*82b1193eSBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
502*82b1193eSBarry Smith         if (a->a[j] !=  0.) continue;
503*82b1193eSBarry Smith         ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
504*82b1193eSBarry Smith       }
505*82b1193eSBarry Smith     }
506*82b1193eSBarry Smith     color = DRAW_RED;
507*82b1193eSBarry Smith     for (i=0; i<m; i++) {
508*82b1193eSBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
509*82b1193eSBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
510*82b1193eSBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
511*82b1193eSBarry Smith #if defined(PETSC_USE_COMPLEX)
512*82b1193eSBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
513*82b1193eSBarry Smith #else
514*82b1193eSBarry Smith         if (a->a[j] <=  0.) continue;
515*82b1193eSBarry Smith #endif
516*82b1193eSBarry Smith         ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
517*82b1193eSBarry Smith       }
518*82b1193eSBarry Smith     }
519*82b1193eSBarry Smith   } else {
520*82b1193eSBarry Smith     /* use contour shading to indicate magnitude of values */
521*82b1193eSBarry Smith     /* first determine max of all nonzero values */
522*82b1193eSBarry Smith     int    nz = a->nz,count;
523*82b1193eSBarry Smith     Draw   popup;
524*82b1193eSBarry Smith     PetscReal scale;
525*82b1193eSBarry Smith 
526*82b1193eSBarry Smith     for (i=0; i<nz; i++) {
527*82b1193eSBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
528*82b1193eSBarry Smith     }
529*82b1193eSBarry Smith     scale = (245.0 - DRAW_BASIC_COLORS)/maxv;
530*82b1193eSBarry Smith     ierr  = DrawGetPopup(draw,&popup);CHKERRQ(ierr);
531*82b1193eSBarry Smith     if (popup) {ierr  = DrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);}
532*82b1193eSBarry Smith     count = 0;
533*82b1193eSBarry Smith     for (i=0; i<m; i++) {
534*82b1193eSBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
535*82b1193eSBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
536*82b1193eSBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
537*82b1193eSBarry Smith         color = DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(a->a[count]));
538*82b1193eSBarry Smith         ierr  = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
539*82b1193eSBarry Smith         count++;
540*82b1193eSBarry Smith       }
541*82b1193eSBarry Smith     }
542*82b1193eSBarry Smith   }
543*82b1193eSBarry Smith   PetscFunctionReturn(0);
544*82b1193eSBarry Smith }
545*82b1193eSBarry Smith 
546*82b1193eSBarry Smith #undef __FUNC__
547*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatView_SeqAIJ_Draw"></a>*/"MatView_SeqAIJ_Draw"
548*82b1193eSBarry Smith int MatView_SeqAIJ_Draw(Mat A,Viewer viewer)
549*82b1193eSBarry Smith {
550*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
551*82b1193eSBarry Smith   int        ierr;
552*82b1193eSBarry Smith   Draw       draw;
553*82b1193eSBarry Smith   PetscReal  xr,yr,xl,yl,h,w;
554*82b1193eSBarry Smith   PetscTruth isnull;
555*82b1193eSBarry Smith 
556*82b1193eSBarry Smith   PetscFunctionBegin;
557*82b1193eSBarry Smith   ierr = ViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
558*82b1193eSBarry Smith   ierr = DrawIsNull(draw,&isnull);CHKERRQ(ierr);
559*82b1193eSBarry Smith   if (isnull) PetscFunctionReturn(0);
560*82b1193eSBarry Smith 
561*82b1193eSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
562*82b1193eSBarry Smith   xr  = a->n; yr = a->m; h = yr/10.0; w = xr/10.0;
563*82b1193eSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
564*82b1193eSBarry Smith   ierr = DrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
565*82b1193eSBarry Smith   ierr = DrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
566*82b1193eSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
567*82b1193eSBarry Smith   PetscFunctionReturn(0);
568*82b1193eSBarry Smith }
569*82b1193eSBarry Smith 
570*82b1193eSBarry Smith #undef __FUNC__
571*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatView_SeqAIJ"></a>*/"MatView_SeqAIJ"
572*82b1193eSBarry Smith int MatView_SeqAIJ(Mat A,Viewer viewer)
573*82b1193eSBarry Smith {
574*82b1193eSBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ*)A->data;
575*82b1193eSBarry Smith   int         ierr;
576*82b1193eSBarry Smith   PetscTruth  issocket,isascii,isbinary,isdraw;
577*82b1193eSBarry Smith 
578*82b1193eSBarry Smith   PetscFunctionBegin;
579*82b1193eSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,SOCKET_VIEWER,&issocket);CHKERRQ(ierr);
580*82b1193eSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,ASCII_VIEWER,&isascii);CHKERRQ(ierr);
581*82b1193eSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,BINARY_VIEWER,&isbinary);CHKERRQ(ierr);
582*82b1193eSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,DRAW_VIEWER,&isdraw);CHKERRQ(ierr);
583*82b1193eSBarry Smith   if (issocket) {
584*82b1193eSBarry Smith     if (a->indexshift) {
585*82b1193eSBarry Smith       SETERRQ(1,1,"Can only socket send sparse matrix with 0 based indexing");
586*82b1193eSBarry Smith     }
587*82b1193eSBarry Smith     ierr = ViewerSocketPutSparse_Private(viewer,a->m,a->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr);
588*82b1193eSBarry Smith   } else if (isascii) {
589*82b1193eSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
590*82b1193eSBarry Smith   } else if (isbinary) {
591*82b1193eSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
592*82b1193eSBarry Smith   } else if (isdraw) {
593*82b1193eSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
594*82b1193eSBarry Smith   } else {
595*82b1193eSBarry Smith     SETERRQ1(1,1,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name);
596*82b1193eSBarry Smith   }
597*82b1193eSBarry Smith   PetscFunctionReturn(0);
598*82b1193eSBarry Smith }
599*82b1193eSBarry Smith 
600*82b1193eSBarry Smith EXTERN int Mat_AIJ_CheckInode(Mat);
601*82b1193eSBarry Smith #undef __FUNC__
602*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatAssemblyEnd_SeqAIJ"></a>*/"MatAssemblyEnd_SeqAIJ"
603*82b1193eSBarry Smith int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
604*82b1193eSBarry Smith {
605*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
606*82b1193eSBarry Smith   int        fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax,ierr;
607*82b1193eSBarry Smith   int        m = a->m,*ip,N,*ailen = a->ilen,shift = a->indexshift,rmax = 0;
608*82b1193eSBarry Smith   Scalar     *aa = a->a,*ap;
609*82b1193eSBarry Smith 
610*82b1193eSBarry Smith   PetscFunctionBegin;
611*82b1193eSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
612*82b1193eSBarry Smith 
613*82b1193eSBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
614*82b1193eSBarry Smith   for (i=1; i<m; i++) {
615*82b1193eSBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
616*82b1193eSBarry Smith     fshift += imax[i-1] - ailen[i-1];
617*82b1193eSBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
618*82b1193eSBarry Smith     if (fshift) {
619*82b1193eSBarry Smith       ip = aj + ai[i] + shift;
620*82b1193eSBarry Smith       ap = aa + ai[i] + shift;
621*82b1193eSBarry Smith       N  = ailen[i];
622*82b1193eSBarry Smith       for (j=0; j<N; j++) {
623*82b1193eSBarry Smith         ip[j-fshift] = ip[j];
624*82b1193eSBarry Smith         ap[j-fshift] = ap[j];
625*82b1193eSBarry Smith       }
626*82b1193eSBarry Smith     }
627*82b1193eSBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
628*82b1193eSBarry Smith   }
629*82b1193eSBarry Smith   if (m) {
630*82b1193eSBarry Smith     fshift += imax[m-1] - ailen[m-1];
631*82b1193eSBarry Smith     ai[m]  = ai[m-1] + ailen[m-1];
632*82b1193eSBarry Smith   }
633*82b1193eSBarry Smith   /* reset ilen and imax for each row */
634*82b1193eSBarry Smith   for (i=0; i<m; i++) {
635*82b1193eSBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
636*82b1193eSBarry Smith   }
637*82b1193eSBarry Smith   a->nz = ai[m] + shift;
638*82b1193eSBarry Smith 
639*82b1193eSBarry Smith   /* diagonals may have moved, so kill the diagonal pointers */
640*82b1193eSBarry Smith   if (fshift && a->diag) {
641*82b1193eSBarry Smith     ierr = PetscFree(a->diag);CHKERRQ(ierr);
642*82b1193eSBarry Smith     PLogObjectMemory(A,-(m+1)*sizeof(int));
643*82b1193eSBarry Smith     a->diag = 0;
644*82b1193eSBarry Smith   }
645*82b1193eSBarry Smith   PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded,%d used\n",m,a->n,fshift,a->nz);
646*82b1193eSBarry Smith   PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues() is %d\n",a->reallocs);
647*82b1193eSBarry Smith   PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Most nonzeros in any row is %d\n",rmax);
648*82b1193eSBarry Smith   a->reallocs          = 0;
649*82b1193eSBarry Smith   A->info.nz_unneeded  = (double)fshift;
650*82b1193eSBarry Smith   a->rmax              = rmax;
651*82b1193eSBarry Smith 
652*82b1193eSBarry Smith   /* check out for identical nodes. If found, use inode functions */
653*82b1193eSBarry Smith   ierr = Mat_AIJ_CheckInode(A);CHKERRQ(ierr);
654*82b1193eSBarry Smith   PetscFunctionReturn(0);
655*82b1193eSBarry Smith }
656*82b1193eSBarry Smith 
657*82b1193eSBarry Smith #undef __FUNC__
658*82b1193eSBarry Smith #define __FUNC__ /*<a name="atZeroEntries_SeqAIJ"></a>*/"MatZeroEntries_SeqAIJ"
659*82b1193eSBarry Smith int MatZeroEntries_SeqAIJ(Mat A)
660*82b1193eSBarry Smith {
661*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
662*82b1193eSBarry Smith   int        ierr;
663*82b1193eSBarry Smith 
664*82b1193eSBarry Smith   PetscFunctionBegin;
665*82b1193eSBarry Smith   ierr = PetscMemzero(a->a,(a->i[a->m]+a->indexshift)*sizeof(Scalar));CHKERRQ(ierr);
666*82b1193eSBarry Smith   PetscFunctionReturn(0);
667*82b1193eSBarry Smith }
668*82b1193eSBarry Smith 
669*82b1193eSBarry Smith #undef __FUNC__
670*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatDestroy_SeqAIJ"></a>*/"MatDestroy_SeqAIJ"
671*82b1193eSBarry Smith int MatDestroy_SeqAIJ(Mat A)
672*82b1193eSBarry Smith {
673*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
674*82b1193eSBarry Smith   int        ierr;
675*82b1193eSBarry Smith 
676*82b1193eSBarry Smith   PetscFunctionBegin;
677*82b1193eSBarry Smith 
678*82b1193eSBarry Smith   if (A->mapping) {
679*82b1193eSBarry Smith     ierr = ISLocalToGlobalMappingDestroy(A->mapping);CHKERRQ(ierr);
680*82b1193eSBarry Smith   }
681*82b1193eSBarry Smith   if (A->bmapping) {
682*82b1193eSBarry Smith     ierr = ISLocalToGlobalMappingDestroy(A->bmapping);CHKERRQ(ierr);
683*82b1193eSBarry Smith   }
684*82b1193eSBarry Smith   if (A->rmap) {
685*82b1193eSBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
686*82b1193eSBarry Smith   }
687*82b1193eSBarry Smith   if (A->cmap) {
688*82b1193eSBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
689*82b1193eSBarry Smith   }
690*82b1193eSBarry Smith   if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);}
691*82b1193eSBarry Smith #if defined(PETSC_USE_LOG)
692*82b1193eSBarry Smith   PLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz);
693*82b1193eSBarry Smith #endif
694*82b1193eSBarry Smith   if (a->freedata) {
695*82b1193eSBarry Smith     ierr = PetscFree(a->a);CHKERRQ(ierr);
696*82b1193eSBarry Smith     if (!a->singlemalloc) {
697*82b1193eSBarry Smith       ierr = PetscFree(a->i);CHKERRQ(ierr);
698*82b1193eSBarry Smith       ierr = PetscFree(a->j);CHKERRQ(ierr);
699*82b1193eSBarry Smith     }
700*82b1193eSBarry Smith   }
701*82b1193eSBarry Smith   if (a->row) {
702*82b1193eSBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
703*82b1193eSBarry Smith   }
704*82b1193eSBarry Smith   if (a->col) {
705*82b1193eSBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
706*82b1193eSBarry Smith   }
707*82b1193eSBarry Smith   if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
708*82b1193eSBarry Smith   if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
709*82b1193eSBarry Smith   if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
710*82b1193eSBarry Smith   if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
711*82b1193eSBarry Smith   if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);}
712*82b1193eSBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
713*82b1193eSBarry Smith   if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);}
714*82b1193eSBarry Smith   ierr = PetscFree(a);CHKERRQ(ierr);
715*82b1193eSBarry Smith 
716*82b1193eSBarry Smith   PLogObjectDestroy(A);
717*82b1193eSBarry Smith   PetscHeaderDestroy(A);
718*82b1193eSBarry Smith   PetscFunctionReturn(0);
719*82b1193eSBarry Smith }
720*82b1193eSBarry Smith 
721*82b1193eSBarry Smith #undef __FUNC__
722*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatCompress_SeqAIJ"></a>*/"MatCompress_SeqAIJ"
723*82b1193eSBarry Smith int MatCompress_SeqAIJ(Mat A)
724*82b1193eSBarry Smith {
725*82b1193eSBarry Smith   PetscFunctionBegin;
726*82b1193eSBarry Smith   PetscFunctionReturn(0);
727*82b1193eSBarry Smith }
728*82b1193eSBarry Smith 
729*82b1193eSBarry Smith #undef __FUNC__
730*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatSetOption_SeqAIJ"></a>*/"MatSetOption_SeqAIJ"
731*82b1193eSBarry Smith int MatSetOption_SeqAIJ(Mat A,MatOption op)
732*82b1193eSBarry Smith {
733*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
734*82b1193eSBarry Smith 
735*82b1193eSBarry Smith   PetscFunctionBegin;
736*82b1193eSBarry Smith   if      (op == MAT_ROW_ORIENTED)                 a->roworiented       = PETSC_TRUE;
737*82b1193eSBarry Smith   else if (op == MAT_KEEP_ZEROED_ROWS)             a->keepzeroedrows    = PETSC_TRUE;
738*82b1193eSBarry Smith   else if (op == MAT_COLUMN_ORIENTED)              a->roworiented       = PETSC_FALSE;
739*82b1193eSBarry Smith   else if (op == MAT_COLUMNS_SORTED)               a->sorted            = PETSC_TRUE;
740*82b1193eSBarry Smith   else if (op == MAT_COLUMNS_UNSORTED)             a->sorted            = PETSC_FALSE;
741*82b1193eSBarry Smith   else if (op == MAT_NO_NEW_NONZERO_LOCATIONS)     a->nonew             = 1;
742*82b1193eSBarry Smith   else if (op == MAT_NEW_NONZERO_LOCATION_ERR)     a->nonew             = -1;
743*82b1193eSBarry Smith   else if (op == MAT_NEW_NONZERO_ALLOCATION_ERR)   a->nonew             = -2;
744*82b1193eSBarry Smith   else if (op == MAT_YES_NEW_NONZERO_LOCATIONS)    a->nonew             = 0;
745*82b1193eSBarry Smith   else if (op == MAT_IGNORE_ZERO_ENTRIES)          a->ignorezeroentries = PETSC_TRUE;
746*82b1193eSBarry Smith   else if (op == MAT_USE_INODES)                   a->inode.use         = PETSC_TRUE;
747*82b1193eSBarry Smith   else if (op == MAT_DO_NOT_USE_INODES)            a->inode.use         = PETSC_FALSE;
748*82b1193eSBarry Smith   else if (op == MAT_ROWS_SORTED ||
749*82b1193eSBarry Smith            op == MAT_ROWS_UNSORTED ||
750*82b1193eSBarry Smith            op == MAT_SYMMETRIC ||
751*82b1193eSBarry Smith            op == MAT_STRUCTURALLY_SYMMETRIC ||
752*82b1193eSBarry Smith            op == MAT_YES_NEW_DIAGONALS ||
753*82b1193eSBarry Smith            op == MAT_IGNORE_OFF_PROC_ENTRIES||
754*82b1193eSBarry Smith            op == MAT_USE_HASH_TABLE)
755*82b1193eSBarry Smith     PLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n");
756*82b1193eSBarry Smith   else if (op == MAT_NO_NEW_DIAGONALS) {
757*82b1193eSBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS");
758*82b1193eSBarry Smith   } else if (op == MAT_INODE_LIMIT_1)          a->inode.limit  = 1;
759*82b1193eSBarry Smith   else if (op == MAT_INODE_LIMIT_2)            a->inode.limit  = 2;
760*82b1193eSBarry Smith   else if (op == MAT_INODE_LIMIT_3)            a->inode.limit  = 3;
761*82b1193eSBarry Smith   else if (op == MAT_INODE_LIMIT_4)            a->inode.limit  = 4;
762*82b1193eSBarry Smith   else if (op == MAT_INODE_LIMIT_5)            a->inode.limit  = 5;
763*82b1193eSBarry Smith   else SETERRQ(PETSC_ERR_SUP,0,"unknown option");
764*82b1193eSBarry Smith   PetscFunctionReturn(0);
765*82b1193eSBarry Smith }
766*82b1193eSBarry Smith 
767*82b1193eSBarry Smith #undef __FUNC__
768*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetDiagonal_SeqAIJ"></a>*/"MatGetDiagonal_SeqAIJ"
769*82b1193eSBarry Smith int MatGetDiagonal_SeqAIJ(Mat A,Vec v)
770*82b1193eSBarry Smith {
771*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
772*82b1193eSBarry Smith   int        i,j,n,shift = a->indexshift,ierr;
773*82b1193eSBarry Smith   Scalar     *x,zero = 0.0;
774*82b1193eSBarry Smith 
775*82b1193eSBarry Smith   PetscFunctionBegin;
776*82b1193eSBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
777*82b1193eSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
778*82b1193eSBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
779*82b1193eSBarry Smith   if (n != a->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Nonconforming matrix and vector");
780*82b1193eSBarry Smith   for (i=0; i<a->m; i++) {
781*82b1193eSBarry Smith     for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
782*82b1193eSBarry Smith       if (a->j[j]+shift == i) {
783*82b1193eSBarry Smith         x[i] = a->a[j];
784*82b1193eSBarry Smith         break;
785*82b1193eSBarry Smith       }
786*82b1193eSBarry Smith     }
787*82b1193eSBarry Smith   }
788*82b1193eSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
789*82b1193eSBarry Smith   PetscFunctionReturn(0);
790*82b1193eSBarry Smith }
791*82b1193eSBarry Smith 
792*82b1193eSBarry Smith #undef __FUNC__
793*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatMultTranspose_SeqAIJ"></a>*/"MatMultTranspose_SeqAIJ"
794*82b1193eSBarry Smith int MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
795*82b1193eSBarry Smith {
796*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
797*82b1193eSBarry Smith   Scalar     *x,*y,*v,alpha,zero = 0.0;
798*82b1193eSBarry Smith   int        ierr,m = a->m,n,i,*idx,shift = a->indexshift;
799*82b1193eSBarry Smith 
800*82b1193eSBarry Smith   PetscFunctionBegin;
801*82b1193eSBarry Smith   ierr = VecSet(&zero,yy);CHKERRQ(ierr);
802*82b1193eSBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
803*82b1193eSBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
804*82b1193eSBarry Smith   y = y + shift; /* shift for Fortran start by 1 indexing */
805*82b1193eSBarry Smith   for (i=0; i<m; i++) {
806*82b1193eSBarry Smith     idx   = a->j + a->i[i] + shift;
807*82b1193eSBarry Smith     v     = a->a + a->i[i] + shift;
808*82b1193eSBarry Smith     n     = a->i[i+1] - a->i[i];
809*82b1193eSBarry Smith     alpha = x[i];
810*82b1193eSBarry Smith     while (n-->0) {y[*idx++] += alpha * *v++;}
811*82b1193eSBarry Smith   }
812*82b1193eSBarry Smith   PLogFlops(2*a->nz - a->n);
813*82b1193eSBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
814*82b1193eSBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
815*82b1193eSBarry Smith   PetscFunctionReturn(0);
816*82b1193eSBarry Smith }
817*82b1193eSBarry Smith 
818*82b1193eSBarry Smith #undef __FUNC__
819*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatMultTransposeAdd_SeqAIJ"></a>*/"MatMultTransposeAdd_SeqAIJ"
820*82b1193eSBarry Smith int MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
821*82b1193eSBarry Smith {
822*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
823*82b1193eSBarry Smith   Scalar     *x,*y,*v,alpha;
824*82b1193eSBarry Smith   int        ierr,m = a->m,n,i,*idx,shift = a->indexshift;
825*82b1193eSBarry Smith 
826*82b1193eSBarry Smith   PetscFunctionBegin;
827*82b1193eSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
828*82b1193eSBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
829*82b1193eSBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
830*82b1193eSBarry Smith   y = y + shift; /* shift for Fortran start by 1 indexing */
831*82b1193eSBarry Smith   for (i=0; i<m; i++) {
832*82b1193eSBarry Smith     idx   = a->j + a->i[i] + shift;
833*82b1193eSBarry Smith     v     = a->a + a->i[i] + shift;
834*82b1193eSBarry Smith     n     = a->i[i+1] - a->i[i];
835*82b1193eSBarry Smith     alpha = x[i];
836*82b1193eSBarry Smith     while (n-->0) {y[*idx++] += alpha * *v++;}
837*82b1193eSBarry Smith   }
838*82b1193eSBarry Smith   PLogFlops(2*a->nz);
839*82b1193eSBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
840*82b1193eSBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
841*82b1193eSBarry Smith   PetscFunctionReturn(0);
842*82b1193eSBarry Smith }
843*82b1193eSBarry Smith 
844*82b1193eSBarry Smith #undef __FUNC__
845*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatMult_SeqAIJ"></a>*/"MatMult_SeqAIJ"
846*82b1193eSBarry Smith int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
847*82b1193eSBarry Smith {
848*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
849*82b1193eSBarry Smith   Scalar     *x,*y,*v,sum;
850*82b1193eSBarry Smith   int        ierr,m = a->m,*idx,shift = a->indexshift,*ii;
851*82b1193eSBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
852*82b1193eSBarry Smith   int        n,i,jrow,j;
853*82b1193eSBarry Smith #endif
854*82b1193eSBarry Smith 
855*82b1193eSBarry Smith #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
856*82b1193eSBarry Smith #pragma disjoint(*x,*y,*v)
857*82b1193eSBarry Smith #endif
858*82b1193eSBarry Smith 
859*82b1193eSBarry Smith   PetscFunctionBegin;
860*82b1193eSBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
861*82b1193eSBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
862*82b1193eSBarry Smith   x    = x + shift;    /* shift for Fortran start by 1 indexing */
863*82b1193eSBarry Smith   idx  = a->j;
864*82b1193eSBarry Smith   v    = a->a;
865*82b1193eSBarry Smith   ii   = a->i;
866*82b1193eSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
867*82b1193eSBarry Smith   fortranmultaij_(&m,x,ii,idx+shift,v+shift,y);
868*82b1193eSBarry Smith #else
869*82b1193eSBarry Smith   v    += shift; /* shift for Fortran start by 1 indexing */
870*82b1193eSBarry Smith   idx  += shift;
871*82b1193eSBarry Smith   for (i=0; i<m; i++) {
872*82b1193eSBarry Smith     jrow = ii[i];
873*82b1193eSBarry Smith     n    = ii[i+1] - jrow;
874*82b1193eSBarry Smith     sum  = 0.0;
875*82b1193eSBarry Smith     for (j=0; j<n; j++) {
876*82b1193eSBarry Smith       sum += v[jrow]*x[idx[jrow]]; jrow++;
877*82b1193eSBarry Smith      }
878*82b1193eSBarry Smith     y[i] = sum;
879*82b1193eSBarry Smith   }
880*82b1193eSBarry Smith #endif
881*82b1193eSBarry Smith   PLogFlops(2*a->nz - m);
882*82b1193eSBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
883*82b1193eSBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
884*82b1193eSBarry Smith   PetscFunctionReturn(0);
885*82b1193eSBarry Smith }
886*82b1193eSBarry Smith 
887*82b1193eSBarry Smith #undef __FUNC__
888*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatMultAdd_SeqAIJ"></a>*/"MatMultAdd_SeqAIJ"
889*82b1193eSBarry Smith int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
890*82b1193eSBarry Smith {
891*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
892*82b1193eSBarry Smith   Scalar     *x,*y,*z,*v,sum;
893*82b1193eSBarry Smith   int        ierr,m = a->m,*idx,shift = a->indexshift,*ii;
894*82b1193eSBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
895*82b1193eSBarry Smith   int        n,i,jrow,j;
896*82b1193eSBarry Smith #endif
897*82b1193eSBarry Smith 
898*82b1193eSBarry Smith   PetscFunctionBegin;
899*82b1193eSBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
900*82b1193eSBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
901*82b1193eSBarry Smith   if (zz != yy) {
902*82b1193eSBarry Smith     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
903*82b1193eSBarry Smith   } else {
904*82b1193eSBarry Smith     z = y;
905*82b1193eSBarry Smith   }
906*82b1193eSBarry Smith   x    = x + shift; /* shift for Fortran start by 1 indexing */
907*82b1193eSBarry Smith   idx  = a->j;
908*82b1193eSBarry Smith   v    = a->a;
909*82b1193eSBarry Smith   ii   = a->i;
910*82b1193eSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
911*82b1193eSBarry Smith   fortranmultaddaij_(&m,x,ii,idx+shift,v+shift,y,z);
912*82b1193eSBarry Smith #else
913*82b1193eSBarry Smith   v   += shift; /* shift for Fortran start by 1 indexing */
914*82b1193eSBarry Smith   idx += shift;
915*82b1193eSBarry Smith   for (i=0; i<m; i++) {
916*82b1193eSBarry Smith     jrow = ii[i];
917*82b1193eSBarry Smith     n    = ii[i+1] - jrow;
918*82b1193eSBarry Smith     sum  = y[i];
919*82b1193eSBarry Smith     for (j=0; j<n; j++) {
920*82b1193eSBarry Smith       sum += v[jrow]*x[idx[jrow]]; jrow++;
921*82b1193eSBarry Smith      }
922*82b1193eSBarry Smith     z[i] = sum;
923*82b1193eSBarry Smith   }
924*82b1193eSBarry Smith #endif
925*82b1193eSBarry Smith   PLogFlops(2*a->nz);
926*82b1193eSBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
927*82b1193eSBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
928*82b1193eSBarry Smith   if (zz != yy) {
929*82b1193eSBarry Smith     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
930*82b1193eSBarry Smith   }
931*82b1193eSBarry Smith   PetscFunctionReturn(0);
932*82b1193eSBarry Smith }
933*82b1193eSBarry Smith 
934*82b1193eSBarry Smith /*
935*82b1193eSBarry Smith      Adds diagonal pointers to sparse matrix structure.
936*82b1193eSBarry Smith */
937*82b1193eSBarry Smith #undef __FUNC__
938*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatMarkDiagonal_SeqAIJ"></a>*/"MatMarkDiagonal_SeqAIJ"
939*82b1193eSBarry Smith int MatMarkDiagonal_SeqAIJ(Mat A)
940*82b1193eSBarry Smith {
941*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
942*82b1193eSBarry Smith   int        i,j,*diag,m = a->m,shift = a->indexshift;
943*82b1193eSBarry Smith 
944*82b1193eSBarry Smith   PetscFunctionBegin;
945*82b1193eSBarry Smith   if (a->diag) PetscFunctionReturn(0);
946*82b1193eSBarry Smith 
947*82b1193eSBarry Smith   diag = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(diag);
948*82b1193eSBarry Smith   PLogObjectMemory(A,(m+1)*sizeof(int));
949*82b1193eSBarry Smith   for (i=0; i<a->m; i++) {
950*82b1193eSBarry Smith     diag[i] = a->i[i+1];
951*82b1193eSBarry Smith     for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
952*82b1193eSBarry Smith       if (a->j[j]+shift == i) {
953*82b1193eSBarry Smith         diag[i] = j - shift;
954*82b1193eSBarry Smith         break;
955*82b1193eSBarry Smith       }
956*82b1193eSBarry Smith     }
957*82b1193eSBarry Smith   }
958*82b1193eSBarry Smith   a->diag = diag;
959*82b1193eSBarry Smith   PetscFunctionReturn(0);
960*82b1193eSBarry Smith }
961*82b1193eSBarry Smith 
962*82b1193eSBarry Smith /*
963*82b1193eSBarry Smith      Checks for missing diagonals
964*82b1193eSBarry Smith */
965*82b1193eSBarry Smith #undef __FUNC__
966*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatMissingDiagonal_SeqAIJ"></a>*/"MatMissingDiagonal_SeqAIJ"
967*82b1193eSBarry Smith int MatMissingDiagonal_SeqAIJ(Mat A)
968*82b1193eSBarry Smith {
969*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
970*82b1193eSBarry Smith   int        *diag,*jj = a->j,i,shift = a->indexshift,ierr;
971*82b1193eSBarry Smith 
972*82b1193eSBarry Smith   PetscFunctionBegin;
973*82b1193eSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
974*82b1193eSBarry Smith   diag = a->diag;
975*82b1193eSBarry Smith   for (i=0; i<a->m; i++) {
976*82b1193eSBarry Smith     if (jj[diag[i]+shift] != i-shift) {
977*82b1193eSBarry Smith       SETERRQ1(1,1,"Matrix is missing diagonal number %d",i);
978*82b1193eSBarry Smith     }
979*82b1193eSBarry Smith   }
980*82b1193eSBarry Smith   PetscFunctionReturn(0);
981*82b1193eSBarry Smith }
982*82b1193eSBarry Smith 
983*82b1193eSBarry Smith #undef __FUNC__
984*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatRelax_SeqAIJ"></a>*/"MatRelax_SeqAIJ"
985*82b1193eSBarry Smith int MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,int its,Vec xx)
986*82b1193eSBarry Smith {
987*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
988*82b1193eSBarry Smith   Scalar     *x,*b,*bs, d,*xs,sum,*v = a->a,*t=0,scale,*ts,*xb,*idiag=0;
989*82b1193eSBarry Smith   int        ierr,*idx,*diag,n = a->n,m = a->m,i,shift = a->indexshift;
990*82b1193eSBarry Smith 
991*82b1193eSBarry Smith   PetscFunctionBegin;
992*82b1193eSBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
993*82b1193eSBarry Smith   if (xx != bb) {
994*82b1193eSBarry Smith     ierr = VecGetArray(bb,&b);CHKERRQ(ierr);
995*82b1193eSBarry Smith   } else {
996*82b1193eSBarry Smith     b = x;
997*82b1193eSBarry Smith   }
998*82b1193eSBarry Smith 
999*82b1193eSBarry Smith   if (!a->diag) {ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);}
1000*82b1193eSBarry Smith   diag = a->diag;
1001*82b1193eSBarry Smith   xs   = x + shift; /* shifted by one for index start of a or a->j*/
1002*82b1193eSBarry Smith   if (flag == SOR_APPLY_UPPER) {
1003*82b1193eSBarry Smith    /* apply (U + D/omega) to the vector */
1004*82b1193eSBarry Smith     bs = b + shift;
1005*82b1193eSBarry Smith     for (i=0; i<m; i++) {
1006*82b1193eSBarry Smith         d    = fshift + a->a[diag[i] + shift];
1007*82b1193eSBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1008*82b1193eSBarry Smith 	PLogFlops(2*n-1);
1009*82b1193eSBarry Smith         idx  = a->j + diag[i] + (!shift);
1010*82b1193eSBarry Smith         v    = a->a + diag[i] + (!shift);
1011*82b1193eSBarry Smith         sum  = b[i]*d/omega;
1012*82b1193eSBarry Smith         SPARSEDENSEDOT(sum,bs,v,idx,n);
1013*82b1193eSBarry Smith         x[i] = sum;
1014*82b1193eSBarry Smith     }
1015*82b1193eSBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1016*82b1193eSBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
1017*82b1193eSBarry Smith     PetscFunctionReturn(0);
1018*82b1193eSBarry Smith   }
1019*82b1193eSBarry Smith 
1020*82b1193eSBarry Smith   /* setup workspace for Eisenstat */
1021*82b1193eSBarry Smith   if (flag & SOR_EISENSTAT) {
1022*82b1193eSBarry Smith     if (!a->idiag) {
1023*82b1193eSBarry Smith       a->idiag = (Scalar*)PetscMalloc(2*m*sizeof(Scalar));CHKPTRQ(a->idiag);
1024*82b1193eSBarry Smith       a->ssor  = a->idiag + m;
1025*82b1193eSBarry Smith       v        = a->a;
1026*82b1193eSBarry Smith       for (i=0; i<m; i++) { a->idiag[i] = 1.0/v[diag[i]];}
1027*82b1193eSBarry Smith     }
1028*82b1193eSBarry Smith     t     = a->ssor;
1029*82b1193eSBarry Smith     idiag = a->idiag;
1030*82b1193eSBarry Smith   }
1031*82b1193eSBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1032*82b1193eSBarry Smith     U is upper triangular, E is diagonal; This routine applies
1033*82b1193eSBarry Smith 
1034*82b1193eSBarry Smith             (L + E)^{-1} A (U + E)^{-1}
1035*82b1193eSBarry Smith 
1036*82b1193eSBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
1037*82b1193eSBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
1038*82b1193eSBarry Smith     is the relaxation factor.
1039*82b1193eSBarry Smith     */
1040*82b1193eSBarry Smith 
1041*82b1193eSBarry Smith   if (flag == SOR_APPLY_LOWER) {
1042*82b1193eSBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"SOR_APPLY_LOWER is not implemented");
1043*82b1193eSBarry Smith   } else if ((flag & SOR_EISENSTAT) && omega == 1.0 && shift == 0 && fshift == 0.0) {
1044*82b1193eSBarry Smith     /* special case for omega = 1.0 saves flops and some integer ops */
1045*82b1193eSBarry Smith     Scalar *v2;
1046*82b1193eSBarry Smith 
1047*82b1193eSBarry Smith     v2    = a->a;
1048*82b1193eSBarry Smith     /*  x = (E + U)^{-1} b */
1049*82b1193eSBarry Smith     for (i=m-1; i>=0; i--) {
1050*82b1193eSBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1051*82b1193eSBarry Smith       idx  = a->j + diag[i] + 1;
1052*82b1193eSBarry Smith       v    = a->a + diag[i] + 1;
1053*82b1193eSBarry Smith       sum  = b[i];
1054*82b1193eSBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
1055*82b1193eSBarry Smith       x[i] = sum*idiag[i];
1056*82b1193eSBarry Smith 
1057*82b1193eSBarry Smith       /*  t = b - (2*E - D)x */
1058*82b1193eSBarry Smith       t[i] = b[i] - (v2[diag[i]])*x[i];
1059*82b1193eSBarry Smith     }
1060*82b1193eSBarry Smith 
1061*82b1193eSBarry Smith     /*  t = (E + L)^{-1}t */
1062*82b1193eSBarry Smith     diag = a->diag;
1063*82b1193eSBarry Smith     for (i=0; i<m; i++) {
1064*82b1193eSBarry Smith       n    = diag[i] - a->i[i];
1065*82b1193eSBarry Smith       idx  = a->j + a->i[i];
1066*82b1193eSBarry Smith       v    = a->a + a->i[i];
1067*82b1193eSBarry Smith       sum  = t[i];
1068*82b1193eSBarry Smith       SPARSEDENSEMDOT(sum,t,v,idx,n);
1069*82b1193eSBarry Smith       t[i]  = sum*idiag[i];
1070*82b1193eSBarry Smith 
1071*82b1193eSBarry Smith       /*  x = x + t */
1072*82b1193eSBarry Smith       x[i] += t[i];
1073*82b1193eSBarry Smith     }
1074*82b1193eSBarry Smith 
1075*82b1193eSBarry Smith     PLogFlops(3*m-1 + 2*a->nz);
1076*82b1193eSBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1077*82b1193eSBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
1078*82b1193eSBarry Smith     PetscFunctionReturn(0);
1079*82b1193eSBarry Smith   } else if (flag & SOR_EISENSTAT) {
1080*82b1193eSBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1081*82b1193eSBarry Smith     U is upper triangular, E is diagonal; This routine applies
1082*82b1193eSBarry Smith 
1083*82b1193eSBarry Smith             (L + E)^{-1} A (U + E)^{-1}
1084*82b1193eSBarry Smith 
1085*82b1193eSBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
1086*82b1193eSBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
1087*82b1193eSBarry Smith     is the relaxation factor.
1088*82b1193eSBarry Smith     */
1089*82b1193eSBarry Smith     scale = (2.0/omega) - 1.0;
1090*82b1193eSBarry Smith 
1091*82b1193eSBarry Smith     /*  x = (E + U)^{-1} b */
1092*82b1193eSBarry Smith     for (i=m-1; i>=0; i--) {
1093*82b1193eSBarry Smith       d    = fshift + a->a[diag[i] + shift];
1094*82b1193eSBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1095*82b1193eSBarry Smith       idx  = a->j + diag[i] + (!shift);
1096*82b1193eSBarry Smith       v    = a->a + diag[i] + (!shift);
1097*82b1193eSBarry Smith       sum  = b[i];
1098*82b1193eSBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
1099*82b1193eSBarry Smith       x[i] = omega*(sum/d);
1100*82b1193eSBarry Smith     }
1101*82b1193eSBarry Smith 
1102*82b1193eSBarry Smith     /*  t = b - (2*E - D)x */
1103*82b1193eSBarry Smith     v = a->a;
1104*82b1193eSBarry Smith     for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++ + shift])*x[i]; }
1105*82b1193eSBarry Smith 
1106*82b1193eSBarry Smith     /*  t = (E + L)^{-1}t */
1107*82b1193eSBarry Smith     ts = t + shift; /* shifted by one for index start of a or a->j*/
1108*82b1193eSBarry Smith     diag = a->diag;
1109*82b1193eSBarry Smith     for (i=0; i<m; i++) {
1110*82b1193eSBarry Smith       d    = fshift + a->a[diag[i]+shift];
1111*82b1193eSBarry Smith       n    = diag[i] - a->i[i];
1112*82b1193eSBarry Smith       idx  = a->j + a->i[i] + shift;
1113*82b1193eSBarry Smith       v    = a->a + a->i[i] + shift;
1114*82b1193eSBarry Smith       sum  = t[i];
1115*82b1193eSBarry Smith       SPARSEDENSEMDOT(sum,ts,v,idx,n);
1116*82b1193eSBarry Smith       t[i] = omega*(sum/d);
1117*82b1193eSBarry Smith       /*  x = x + t */
1118*82b1193eSBarry Smith       x[i] += t[i];
1119*82b1193eSBarry Smith     }
1120*82b1193eSBarry Smith 
1121*82b1193eSBarry Smith     PLogFlops(6*m-1 + 2*a->nz);
1122*82b1193eSBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1123*82b1193eSBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
1124*82b1193eSBarry Smith     PetscFunctionReturn(0);
1125*82b1193eSBarry Smith   }
1126*82b1193eSBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
1127*82b1193eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
1128*82b1193eSBarry Smith       for (i=0; i<m; i++) {
1129*82b1193eSBarry Smith         d    = fshift + a->a[diag[i]+shift];
1130*82b1193eSBarry Smith         n    = diag[i] - a->i[i];
1131*82b1193eSBarry Smith 	PLogFlops(2*n-1);
1132*82b1193eSBarry Smith         idx  = a->j + a->i[i] + shift;
1133*82b1193eSBarry Smith         v    = a->a + a->i[i] + shift;
1134*82b1193eSBarry Smith         sum  = b[i];
1135*82b1193eSBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1136*82b1193eSBarry Smith         x[i] = omega*(sum/d);
1137*82b1193eSBarry Smith       }
1138*82b1193eSBarry Smith       xb = x;
1139*82b1193eSBarry Smith     } else xb = b;
1140*82b1193eSBarry Smith     if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) &&
1141*82b1193eSBarry Smith         (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) {
1142*82b1193eSBarry Smith       for (i=0; i<m; i++) {
1143*82b1193eSBarry Smith         x[i] *= a->a[diag[i]+shift];
1144*82b1193eSBarry Smith       }
1145*82b1193eSBarry Smith       PLogFlops(m);
1146*82b1193eSBarry Smith     }
1147*82b1193eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
1148*82b1193eSBarry Smith       for (i=m-1; i>=0; i--) {
1149*82b1193eSBarry Smith         d    = fshift + a->a[diag[i] + shift];
1150*82b1193eSBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1151*82b1193eSBarry Smith 	PLogFlops(2*n-1);
1152*82b1193eSBarry Smith         idx  = a->j + diag[i] + (!shift);
1153*82b1193eSBarry Smith         v    = a->a + diag[i] + (!shift);
1154*82b1193eSBarry Smith         sum  = xb[i];
1155*82b1193eSBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1156*82b1193eSBarry Smith         x[i] = omega*(sum/d);
1157*82b1193eSBarry Smith       }
1158*82b1193eSBarry Smith     }
1159*82b1193eSBarry Smith     its--;
1160*82b1193eSBarry Smith   }
1161*82b1193eSBarry Smith   while (its--) {
1162*82b1193eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
1163*82b1193eSBarry Smith       for (i=0; i<m; i++) {
1164*82b1193eSBarry Smith         d    = fshift + a->a[diag[i]+shift];
1165*82b1193eSBarry Smith         n    = a->i[i+1] - a->i[i];
1166*82b1193eSBarry Smith 	PLogFlops(2*n-1);
1167*82b1193eSBarry Smith         idx  = a->j + a->i[i] + shift;
1168*82b1193eSBarry Smith         v    = a->a + a->i[i] + shift;
1169*82b1193eSBarry Smith         sum  = b[i];
1170*82b1193eSBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1171*82b1193eSBarry Smith         x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d;
1172*82b1193eSBarry Smith       }
1173*82b1193eSBarry Smith     }
1174*82b1193eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
1175*82b1193eSBarry Smith       for (i=m-1; i>=0; i--) {
1176*82b1193eSBarry Smith         d    = fshift + a->a[diag[i] + shift];
1177*82b1193eSBarry Smith         n    = a->i[i+1] - a->i[i];
1178*82b1193eSBarry Smith 	PLogFlops(2*n-1);
1179*82b1193eSBarry Smith         idx  = a->j + a->i[i] + shift;
1180*82b1193eSBarry Smith         v    = a->a + a->i[i] + shift;
1181*82b1193eSBarry Smith         sum  = b[i];
1182*82b1193eSBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1183*82b1193eSBarry Smith         x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d;
1184*82b1193eSBarry Smith       }
1185*82b1193eSBarry Smith     }
1186*82b1193eSBarry Smith   }
1187*82b1193eSBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1188*82b1193eSBarry Smith   if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
1189*82b1193eSBarry Smith   PetscFunctionReturn(0);
1190*82b1193eSBarry Smith }
1191*82b1193eSBarry Smith 
1192*82b1193eSBarry Smith #undef __FUNC__
1193*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetInfo_SeqAIJ"></a>*/"MatGetInfo_SeqAIJ"
1194*82b1193eSBarry Smith int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
1195*82b1193eSBarry Smith {
1196*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1197*82b1193eSBarry Smith 
1198*82b1193eSBarry Smith   PetscFunctionBegin;
1199*82b1193eSBarry Smith   info->rows_global    = (double)a->m;
1200*82b1193eSBarry Smith   info->columns_global = (double)a->n;
1201*82b1193eSBarry Smith   info->rows_local     = (double)a->m;
1202*82b1193eSBarry Smith   info->columns_local  = (double)a->n;
1203*82b1193eSBarry Smith   info->block_size     = 1.0;
1204*82b1193eSBarry Smith   info->nz_allocated   = (double)a->maxnz;
1205*82b1193eSBarry Smith   info->nz_used        = (double)a->nz;
1206*82b1193eSBarry Smith   info->nz_unneeded    = (double)(a->maxnz - a->nz);
1207*82b1193eSBarry Smith   info->assemblies     = (double)A->num_ass;
1208*82b1193eSBarry Smith   info->mallocs        = (double)a->reallocs;
1209*82b1193eSBarry Smith   info->memory         = A->mem;
1210*82b1193eSBarry Smith   if (A->factor) {
1211*82b1193eSBarry Smith     info->fill_ratio_given  = A->info.fill_ratio_given;
1212*82b1193eSBarry Smith     info->fill_ratio_needed = A->info.fill_ratio_needed;
1213*82b1193eSBarry Smith     info->factor_mallocs    = A->info.factor_mallocs;
1214*82b1193eSBarry Smith   } else {
1215*82b1193eSBarry Smith     info->fill_ratio_given  = 0;
1216*82b1193eSBarry Smith     info->fill_ratio_needed = 0;
1217*82b1193eSBarry Smith     info->factor_mallocs    = 0;
1218*82b1193eSBarry Smith   }
1219*82b1193eSBarry Smith   PetscFunctionReturn(0);
1220*82b1193eSBarry Smith }
1221*82b1193eSBarry Smith 
1222*82b1193eSBarry Smith EXTERN int MatLUFactorSymbolic_SeqAIJ(Mat,IS,IS,MatLUInfo*,Mat*);
1223*82b1193eSBarry Smith EXTERN int MatLUFactorNumeric_SeqAIJ(Mat,Mat*);
1224*82b1193eSBarry Smith EXTERN int MatLUFactor_SeqAIJ(Mat,IS,IS,MatLUInfo*);
1225*82b1193eSBarry Smith EXTERN int MatSolve_SeqAIJ(Mat,Vec,Vec);
1226*82b1193eSBarry Smith EXTERN int MatSolveAdd_SeqAIJ(Mat,Vec,Vec,Vec);
1227*82b1193eSBarry Smith EXTERN int MatSolveTranspose_SeqAIJ(Mat,Vec,Vec);
1228*82b1193eSBarry Smith EXTERN int MatSolveTransposeAdd_SeqAIJ(Mat,Vec,Vec,Vec);
1229*82b1193eSBarry Smith 
1230*82b1193eSBarry Smith #undef __FUNC__
1231*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatZeroRows_SeqAIJ"></a>*/"MatZeroRows_SeqAIJ"
1232*82b1193eSBarry Smith int MatZeroRows_SeqAIJ(Mat A,IS is,Scalar *diag)
1233*82b1193eSBarry Smith {
1234*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1235*82b1193eSBarry Smith   int         i,ierr,N,*rows,m = a->m - 1,shift = a->indexshift;
1236*82b1193eSBarry Smith 
1237*82b1193eSBarry Smith   PetscFunctionBegin;
1238*82b1193eSBarry Smith   ierr = ISGetSize(is,&N);CHKERRQ(ierr);
1239*82b1193eSBarry Smith   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
1240*82b1193eSBarry Smith   if (a->keepzeroedrows) {
1241*82b1193eSBarry Smith     for (i=0; i<N; i++) {
1242*82b1193eSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range");
1243*82b1193eSBarry Smith       ierr = PetscMemzero(&a->a[a->i[rows[i]]+shift],a->ilen[rows[i]]*sizeof(Scalar));CHKERRQ(ierr);
1244*82b1193eSBarry Smith     }
1245*82b1193eSBarry Smith     if (diag) {
1246*82b1193eSBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1247*82b1193eSBarry Smith       ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1248*82b1193eSBarry Smith       for (i=0; i<N; i++) {
1249*82b1193eSBarry Smith         a->a[a->diag[rows[i]]] = *diag;
1250*82b1193eSBarry Smith       }
1251*82b1193eSBarry Smith     }
1252*82b1193eSBarry Smith   } else {
1253*82b1193eSBarry Smith     if (diag) {
1254*82b1193eSBarry Smith       for (i=0; i<N; i++) {
1255*82b1193eSBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range");
1256*82b1193eSBarry Smith         if (a->ilen[rows[i]] > 0) {
1257*82b1193eSBarry Smith           a->ilen[rows[i]]          = 1;
1258*82b1193eSBarry Smith           a->a[a->i[rows[i]]+shift] = *diag;
1259*82b1193eSBarry Smith           a->j[a->i[rows[i]]+shift] = rows[i]+shift;
1260*82b1193eSBarry Smith         } else { /* in case row was completely empty */
1261*82b1193eSBarry Smith           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr);
1262*82b1193eSBarry Smith         }
1263*82b1193eSBarry Smith       }
1264*82b1193eSBarry Smith     } else {
1265*82b1193eSBarry Smith       for (i=0; i<N; i++) {
1266*82b1193eSBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range");
1267*82b1193eSBarry Smith         a->ilen[rows[i]] = 0;
1268*82b1193eSBarry Smith       }
1269*82b1193eSBarry Smith     }
1270*82b1193eSBarry Smith   }
1271*82b1193eSBarry Smith   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
1272*82b1193eSBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1273*82b1193eSBarry Smith   PetscFunctionReturn(0);
1274*82b1193eSBarry Smith }
1275*82b1193eSBarry Smith 
1276*82b1193eSBarry Smith #undef __FUNC__
1277*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetSize_SeqAIJ"></a>*/"MatGetSize_SeqAIJ"
1278*82b1193eSBarry Smith int MatGetSize_SeqAIJ(Mat A,int *m,int *n)
1279*82b1193eSBarry Smith {
1280*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1281*82b1193eSBarry Smith 
1282*82b1193eSBarry Smith   PetscFunctionBegin;
1283*82b1193eSBarry Smith   if (m) *m = a->m;
1284*82b1193eSBarry Smith   if (n) *n = a->n;
1285*82b1193eSBarry Smith   PetscFunctionReturn(0);
1286*82b1193eSBarry Smith }
1287*82b1193eSBarry Smith 
1288*82b1193eSBarry Smith #undef __FUNC__
1289*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetOwnershipRange_SeqAIJ"></a>*/"MatGetOwnershipRange_SeqAIJ"
1290*82b1193eSBarry Smith int MatGetOwnershipRange_SeqAIJ(Mat A,int *m,int *n)
1291*82b1193eSBarry Smith {
1292*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1293*82b1193eSBarry Smith 
1294*82b1193eSBarry Smith   PetscFunctionBegin;
1295*82b1193eSBarry Smith   if (m) *m = 0;
1296*82b1193eSBarry Smith   if (n) *n = a->m;
1297*82b1193eSBarry Smith   PetscFunctionReturn(0);
1298*82b1193eSBarry Smith }
1299*82b1193eSBarry Smith 
1300*82b1193eSBarry Smith #undef __FUNC__
1301*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetRow_SeqAIJ"></a>*/"MatGetRow_SeqAIJ"
1302*82b1193eSBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
1303*82b1193eSBarry Smith {
1304*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1305*82b1193eSBarry Smith   int        *itmp,i,shift = a->indexshift;
1306*82b1193eSBarry Smith 
1307*82b1193eSBarry Smith   PetscFunctionBegin;
1308*82b1193eSBarry Smith   if (row < 0 || row >= a->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Row %d out of range",row);
1309*82b1193eSBarry Smith 
1310*82b1193eSBarry Smith   *nz = a->i[row+1] - a->i[row];
1311*82b1193eSBarry Smith   if (v) *v = a->a + a->i[row] + shift;
1312*82b1193eSBarry Smith   if (idx) {
1313*82b1193eSBarry Smith     itmp = a->j + a->i[row] + shift;
1314*82b1193eSBarry Smith     if (*nz && shift) {
1315*82b1193eSBarry Smith       *idx = (int*)PetscMalloc((*nz)*sizeof(int));CHKPTRQ(*idx);
1316*82b1193eSBarry Smith       for (i=0; i<(*nz); i++) {(*idx)[i] = itmp[i] + shift;}
1317*82b1193eSBarry Smith     } else if (*nz) {
1318*82b1193eSBarry Smith       *idx = itmp;
1319*82b1193eSBarry Smith     }
1320*82b1193eSBarry Smith     else *idx = 0;
1321*82b1193eSBarry Smith   }
1322*82b1193eSBarry Smith   PetscFunctionReturn(0);
1323*82b1193eSBarry Smith }
1324*82b1193eSBarry Smith 
1325*82b1193eSBarry Smith #undef __FUNC__
1326*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatRestoreRow_SeqAIJ"></a>*/"MatRestoreRow_SeqAIJ"
1327*82b1193eSBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
1328*82b1193eSBarry Smith {
1329*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1330*82b1193eSBarry Smith   int ierr;
1331*82b1193eSBarry Smith 
1332*82b1193eSBarry Smith   PetscFunctionBegin;
1333*82b1193eSBarry Smith   if (idx) {if (*idx && a->indexshift) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
1334*82b1193eSBarry Smith   PetscFunctionReturn(0);
1335*82b1193eSBarry Smith }
1336*82b1193eSBarry Smith 
1337*82b1193eSBarry Smith #undef __FUNC__
1338*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatNorm_SeqAIJ"></a>*/"MatNorm_SeqAIJ"
1339*82b1193eSBarry Smith int MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *norm)
1340*82b1193eSBarry Smith {
1341*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1342*82b1193eSBarry Smith   Scalar     *v = a->a;
1343*82b1193eSBarry Smith   PetscReal  sum = 0.0;
1344*82b1193eSBarry Smith   int        i,j,shift = a->indexshift,ierr;
1345*82b1193eSBarry Smith 
1346*82b1193eSBarry Smith   PetscFunctionBegin;
1347*82b1193eSBarry Smith   if (type == NORM_FROBENIUS) {
1348*82b1193eSBarry Smith     for (i=0; i<a->nz; i++) {
1349*82b1193eSBarry Smith #if defined(PETSC_USE_COMPLEX)
1350*82b1193eSBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1351*82b1193eSBarry Smith #else
1352*82b1193eSBarry Smith       sum += (*v)*(*v); v++;
1353*82b1193eSBarry Smith #endif
1354*82b1193eSBarry Smith     }
1355*82b1193eSBarry Smith     *norm = sqrt(sum);
1356*82b1193eSBarry Smith   } else if (type == NORM_1) {
1357*82b1193eSBarry Smith     PetscReal *tmp;
1358*82b1193eSBarry Smith     int    *jj = a->j;
1359*82b1193eSBarry Smith     tmp = (PetscReal*)PetscMalloc((a->n+1)*sizeof(PetscReal));CHKPTRQ(tmp);
1360*82b1193eSBarry Smith     ierr = PetscMemzero(tmp,a->n*sizeof(PetscReal));CHKERRQ(ierr);
1361*82b1193eSBarry Smith     *norm = 0.0;
1362*82b1193eSBarry Smith     for (j=0; j<a->nz; j++) {
1363*82b1193eSBarry Smith         tmp[*jj++ + shift] += PetscAbsScalar(*v);  v++;
1364*82b1193eSBarry Smith     }
1365*82b1193eSBarry Smith     for (j=0; j<a->n; j++) {
1366*82b1193eSBarry Smith       if (tmp[j] > *norm) *norm = tmp[j];
1367*82b1193eSBarry Smith     }
1368*82b1193eSBarry Smith     ierr = PetscFree(tmp);CHKERRQ(ierr);
1369*82b1193eSBarry Smith   } else if (type == NORM_INFINITY) {
1370*82b1193eSBarry Smith     *norm = 0.0;
1371*82b1193eSBarry Smith     for (j=0; j<a->m; j++) {
1372*82b1193eSBarry Smith       v = a->a + a->i[j] + shift;
1373*82b1193eSBarry Smith       sum = 0.0;
1374*82b1193eSBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1375*82b1193eSBarry Smith         sum += PetscAbsScalar(*v); v++;
1376*82b1193eSBarry Smith       }
1377*82b1193eSBarry Smith       if (sum > *norm) *norm = sum;
1378*82b1193eSBarry Smith     }
1379*82b1193eSBarry Smith   } else {
1380*82b1193eSBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"No support for two norm");
1381*82b1193eSBarry Smith   }
1382*82b1193eSBarry Smith   PetscFunctionReturn(0);
1383*82b1193eSBarry Smith }
1384*82b1193eSBarry Smith 
1385*82b1193eSBarry Smith #undef __FUNC__
1386*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatTranspose_SeqAIJ"></a>*/"MatTranspose_SeqAIJ"
1387*82b1193eSBarry Smith int MatTranspose_SeqAIJ(Mat A,Mat *B)
1388*82b1193eSBarry Smith {
1389*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1390*82b1193eSBarry Smith   Mat        C;
1391*82b1193eSBarry Smith   int        i,ierr,*aj = a->j,*ai = a->i,m = a->m,len,*col;
1392*82b1193eSBarry Smith   int        shift = a->indexshift,refct;
1393*82b1193eSBarry Smith   Scalar     *array = a->a;
1394*82b1193eSBarry Smith 
1395*82b1193eSBarry Smith   PetscFunctionBegin;
1396*82b1193eSBarry Smith   if (!B && m != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Square matrix only for in-place");
1397*82b1193eSBarry Smith   col  = (int*)PetscMalloc((1+a->n)*sizeof(int));CHKPTRQ(col);
1398*82b1193eSBarry Smith   ierr = PetscMemzero(col,(1+a->n)*sizeof(int));CHKERRQ(ierr);
1399*82b1193eSBarry Smith   if (shift) {
1400*82b1193eSBarry Smith     for (i=0; i<ai[m]-1; i++) aj[i] -= 1;
1401*82b1193eSBarry Smith   }
1402*82b1193eSBarry Smith   for (i=0; i<ai[m]+shift; i++) col[aj[i]] += 1;
1403*82b1193eSBarry Smith   ierr = MatCreateSeqAIJ(A->comm,a->n,m,0,col,&C);CHKERRQ(ierr);
1404*82b1193eSBarry Smith   ierr = PetscFree(col);CHKERRQ(ierr);
1405*82b1193eSBarry Smith   for (i=0; i<m; i++) {
1406*82b1193eSBarry Smith     len = ai[i+1]-ai[i];
1407*82b1193eSBarry Smith     ierr = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
1408*82b1193eSBarry Smith     array += len; aj += len;
1409*82b1193eSBarry Smith   }
1410*82b1193eSBarry Smith   if (shift) {
1411*82b1193eSBarry Smith     for (i=0; i<ai[m]-1; i++) aj[i] += 1;
1412*82b1193eSBarry Smith   }
1413*82b1193eSBarry Smith 
1414*82b1193eSBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1415*82b1193eSBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1416*82b1193eSBarry Smith 
1417*82b1193eSBarry Smith   if (B) {
1418*82b1193eSBarry Smith     *B = C;
1419*82b1193eSBarry Smith   } else {
1420*82b1193eSBarry Smith     PetscOps *Abops;
1421*82b1193eSBarry Smith     MatOps   Aops;
1422*82b1193eSBarry Smith 
1423*82b1193eSBarry Smith     /* This isn't really an in-place transpose */
1424*82b1193eSBarry Smith     ierr = PetscFree(a->a);CHKERRQ(ierr);
1425*82b1193eSBarry Smith     if (!a->singlemalloc) {
1426*82b1193eSBarry Smith       ierr = PetscFree(a->i);CHKERRQ(ierr);
1427*82b1193eSBarry Smith       ierr = PetscFree(a->j);
1428*82b1193eSBarry Smith     }
1429*82b1193eSBarry Smith     if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
1430*82b1193eSBarry Smith     if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
1431*82b1193eSBarry Smith     if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
1432*82b1193eSBarry Smith     if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
1433*82b1193eSBarry Smith     if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);}
1434*82b1193eSBarry Smith     ierr = PetscFree(a);CHKERRQ(ierr);
1435*82b1193eSBarry Smith 
1436*82b1193eSBarry Smith 
1437*82b1193eSBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
1438*82b1193eSBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
1439*82b1193eSBarry Smith 
1440*82b1193eSBarry Smith     /*
1441*82b1193eSBarry Smith       This is horrible, horrible code. We need to keep the
1442*82b1193eSBarry Smith       the bops and ops Structures, copy everything from C
1443*82b1193eSBarry Smith       including the function pointers..
1444*82b1193eSBarry Smith     */
1445*82b1193eSBarry Smith     ierr     = PetscMemcpy(A->ops,C->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
1446*82b1193eSBarry Smith     ierr     = PetscMemcpy(A->bops,C->bops,sizeof(PetscOps));CHKERRQ(ierr);
1447*82b1193eSBarry Smith     Abops    = A->bops;
1448*82b1193eSBarry Smith     Aops     = A->ops;
1449*82b1193eSBarry Smith     refct    = A->refct;
1450*82b1193eSBarry Smith     ierr     = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr);
1451*82b1193eSBarry Smith     A->bops  = Abops;
1452*82b1193eSBarry Smith     A->ops   = Aops;
1453*82b1193eSBarry Smith     A->qlist = 0;
1454*82b1193eSBarry Smith     A->refct = refct;
1455*82b1193eSBarry Smith     /* copy over the type_name and name */
1456*82b1193eSBarry Smith     ierr     = PetscStrallocpy(C->type_name,&A->type_name);CHKERRQ(ierr);
1457*82b1193eSBarry Smith     ierr     = PetscStrallocpy(C->name,&A->name);CHKERRQ(ierr);
1458*82b1193eSBarry Smith 
1459*82b1193eSBarry Smith     PetscHeaderDestroy(C);
1460*82b1193eSBarry Smith   }
1461*82b1193eSBarry Smith   PetscFunctionReturn(0);
1462*82b1193eSBarry Smith }
1463*82b1193eSBarry Smith 
1464*82b1193eSBarry Smith #undef __FUNC__
1465*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatDiagonalScale_SeqAIJ"></a>*/"MatDiagonalScale_SeqAIJ"
1466*82b1193eSBarry Smith int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
1467*82b1193eSBarry Smith {
1468*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1469*82b1193eSBarry Smith   Scalar     *l,*r,x,*v;
1470*82b1193eSBarry Smith   int        ierr,i,j,m = a->m,n = a->n,M,nz = a->nz,*jj,shift = a->indexshift;
1471*82b1193eSBarry Smith 
1472*82b1193eSBarry Smith   PetscFunctionBegin;
1473*82b1193eSBarry Smith   if (ll) {
1474*82b1193eSBarry Smith     /* The local size is used so that VecMPI can be passed to this routine
1475*82b1193eSBarry Smith        by MatDiagonalScale_MPIAIJ */
1476*82b1193eSBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
1477*82b1193eSBarry Smith     if (m != a->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Left scaling vector wrong length");
1478*82b1193eSBarry Smith     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
1479*82b1193eSBarry Smith     v = a->a;
1480*82b1193eSBarry Smith     for (i=0; i<m; i++) {
1481*82b1193eSBarry Smith       x = l[i];
1482*82b1193eSBarry Smith       M = a->i[i+1] - a->i[i];
1483*82b1193eSBarry Smith       for (j=0; j<M; j++) { (*v++) *= x;}
1484*82b1193eSBarry Smith     }
1485*82b1193eSBarry Smith     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
1486*82b1193eSBarry Smith     PLogFlops(nz);
1487*82b1193eSBarry Smith   }
1488*82b1193eSBarry Smith   if (rr) {
1489*82b1193eSBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
1490*82b1193eSBarry Smith     if (n != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Right scaling vector wrong length");
1491*82b1193eSBarry Smith     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
1492*82b1193eSBarry Smith     v = a->a; jj = a->j;
1493*82b1193eSBarry Smith     for (i=0; i<nz; i++) {
1494*82b1193eSBarry Smith       (*v++) *= r[*jj++ + shift];
1495*82b1193eSBarry Smith     }
1496*82b1193eSBarry Smith     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
1497*82b1193eSBarry Smith     PLogFlops(nz);
1498*82b1193eSBarry Smith   }
1499*82b1193eSBarry Smith   PetscFunctionReturn(0);
1500*82b1193eSBarry Smith }
1501*82b1193eSBarry Smith 
1502*82b1193eSBarry Smith #undef __FUNC__
1503*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetSubMatrix_SeqAIJ"></a>*/"MatGetSubMatrix_SeqAIJ"
1504*82b1193eSBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatReuse scall,Mat *B)
1505*82b1193eSBarry Smith {
1506*82b1193eSBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data,*c;
1507*82b1193eSBarry Smith   int          *smap,i,k,kstart,kend,ierr,oldcols = a->n,*lens;
1508*82b1193eSBarry Smith   int          row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
1509*82b1193eSBarry Smith   int          *irow,*icol,nrows,ncols,shift = a->indexshift,*ssmap;
1510*82b1193eSBarry Smith   int          *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
1511*82b1193eSBarry Smith   Scalar       *a_new,*mat_a;
1512*82b1193eSBarry Smith   Mat          C;
1513*82b1193eSBarry Smith   PetscTruth   stride;
1514*82b1193eSBarry Smith 
1515*82b1193eSBarry Smith   PetscFunctionBegin;
1516*82b1193eSBarry Smith   ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr);
1517*82b1193eSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"ISrow is not sorted");
1518*82b1193eSBarry Smith   ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr);
1519*82b1193eSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"IScol is not sorted");
1520*82b1193eSBarry Smith 
1521*82b1193eSBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
1522*82b1193eSBarry Smith   ierr = ISGetSize(isrow,&nrows);CHKERRQ(ierr);
1523*82b1193eSBarry Smith   ierr = ISGetSize(iscol,&ncols);CHKERRQ(ierr);
1524*82b1193eSBarry Smith 
1525*82b1193eSBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
1526*82b1193eSBarry Smith   ierr = ISStride(iscol,&stride);CHKERRQ(ierr);
1527*82b1193eSBarry Smith   if (stride && step == 1) {
1528*82b1193eSBarry Smith     /* special case of contiguous rows */
1529*82b1193eSBarry Smith     lens   = (int*)PetscMalloc((ncols+nrows+1)*sizeof(int));CHKPTRQ(lens);
1530*82b1193eSBarry Smith     starts = lens + ncols;
1531*82b1193eSBarry Smith     /* loop over new rows determining lens and starting points */
1532*82b1193eSBarry Smith     for (i=0; i<nrows; i++) {
1533*82b1193eSBarry Smith       kstart  = ai[irow[i]]+shift;
1534*82b1193eSBarry Smith       kend    = kstart + ailen[irow[i]];
1535*82b1193eSBarry Smith       for (k=kstart; k<kend; k++) {
1536*82b1193eSBarry Smith         if (aj[k]+shift >= first) {
1537*82b1193eSBarry Smith           starts[i] = k;
1538*82b1193eSBarry Smith           break;
1539*82b1193eSBarry Smith 	}
1540*82b1193eSBarry Smith       }
1541*82b1193eSBarry Smith       sum = 0;
1542*82b1193eSBarry Smith       while (k < kend) {
1543*82b1193eSBarry Smith         if (aj[k++]+shift >= first+ncols) break;
1544*82b1193eSBarry Smith         sum++;
1545*82b1193eSBarry Smith       }
1546*82b1193eSBarry Smith       lens[i] = sum;
1547*82b1193eSBarry Smith     }
1548*82b1193eSBarry Smith     /* create submatrix */
1549*82b1193eSBarry Smith     if (scall == MAT_REUSE_MATRIX) {
1550*82b1193eSBarry Smith       int n_cols,n_rows;
1551*82b1193eSBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
1552*82b1193eSBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Reused submatrix wrong size");
1553*82b1193eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
1554*82b1193eSBarry Smith       C = *B;
1555*82b1193eSBarry Smith     } else {
1556*82b1193eSBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
1557*82b1193eSBarry Smith     }
1558*82b1193eSBarry Smith     c = (Mat_SeqAIJ*)C->data;
1559*82b1193eSBarry Smith 
1560*82b1193eSBarry Smith     /* loop over rows inserting into submatrix */
1561*82b1193eSBarry Smith     a_new    = c->a;
1562*82b1193eSBarry Smith     j_new    = c->j;
1563*82b1193eSBarry Smith     i_new    = c->i;
1564*82b1193eSBarry Smith     i_new[0] = -shift;
1565*82b1193eSBarry Smith     for (i=0; i<nrows; i++) {
1566*82b1193eSBarry Smith       ii    = starts[i];
1567*82b1193eSBarry Smith       lensi = lens[i];
1568*82b1193eSBarry Smith       for (k=0; k<lensi; k++) {
1569*82b1193eSBarry Smith         *j_new++ = aj[ii+k] - first;
1570*82b1193eSBarry Smith       }
1571*82b1193eSBarry Smith       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(Scalar));CHKERRQ(ierr);
1572*82b1193eSBarry Smith       a_new      += lensi;
1573*82b1193eSBarry Smith       i_new[i+1]  = i_new[i] + lensi;
1574*82b1193eSBarry Smith       c->ilen[i]  = lensi;
1575*82b1193eSBarry Smith     }
1576*82b1193eSBarry Smith     ierr = PetscFree(lens);CHKERRQ(ierr);
1577*82b1193eSBarry Smith   } else {
1578*82b1193eSBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1579*82b1193eSBarry Smith     smap  = (int*)PetscMalloc((1+oldcols)*sizeof(int));CHKPTRQ(smap);
1580*82b1193eSBarry Smith     ssmap = smap + shift;
1581*82b1193eSBarry Smith     lens  = (int*)PetscMalloc((1+nrows)*sizeof(int));CHKPTRQ(lens);
1582*82b1193eSBarry Smith     ierr  = PetscMemzero(smap,oldcols*sizeof(int));CHKERRQ(ierr);
1583*82b1193eSBarry Smith     for (i=0; i<ncols; i++) smap[icol[i]] = i+1;
1584*82b1193eSBarry Smith     /* determine lens of each row */
1585*82b1193eSBarry Smith     for (i=0; i<nrows; i++) {
1586*82b1193eSBarry Smith       kstart  = ai[irow[i]]+shift;
1587*82b1193eSBarry Smith       kend    = kstart + a->ilen[irow[i]];
1588*82b1193eSBarry Smith       lens[i] = 0;
1589*82b1193eSBarry Smith       for (k=kstart; k<kend; k++) {
1590*82b1193eSBarry Smith         if (ssmap[aj[k]]) {
1591*82b1193eSBarry Smith           lens[i]++;
1592*82b1193eSBarry Smith         }
1593*82b1193eSBarry Smith       }
1594*82b1193eSBarry Smith     }
1595*82b1193eSBarry Smith     /* Create and fill new matrix */
1596*82b1193eSBarry Smith     if (scall == MAT_REUSE_MATRIX) {
1597*82b1193eSBarry Smith       PetscTruth equal;
1598*82b1193eSBarry Smith 
1599*82b1193eSBarry Smith       c = (Mat_SeqAIJ *)((*B)->data);
1600*82b1193eSBarry Smith       if (c->m  != nrows || c->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong size");
1601*82b1193eSBarry Smith       ierr = PetscMemcmp(c->ilen,lens,c->m*sizeof(int),&equal);CHKERRQ(ierr);
1602*82b1193eSBarry Smith       if (!equal) {
1603*82b1193eSBarry Smith         SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong no of nonzeros");
1604*82b1193eSBarry Smith       }
1605*82b1193eSBarry Smith       ierr = PetscMemzero(c->ilen,c->m*sizeof(int));CHKERRQ(ierr);
1606*82b1193eSBarry Smith       C = *B;
1607*82b1193eSBarry Smith     } else {
1608*82b1193eSBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
1609*82b1193eSBarry Smith     }
1610*82b1193eSBarry Smith     c = (Mat_SeqAIJ *)(C->data);
1611*82b1193eSBarry Smith     for (i=0; i<nrows; i++) {
1612*82b1193eSBarry Smith       row    = irow[i];
1613*82b1193eSBarry Smith       kstart = ai[row]+shift;
1614*82b1193eSBarry Smith       kend   = kstart + a->ilen[row];
1615*82b1193eSBarry Smith       mat_i  = c->i[i]+shift;
1616*82b1193eSBarry Smith       mat_j  = c->j + mat_i;
1617*82b1193eSBarry Smith       mat_a  = c->a + mat_i;
1618*82b1193eSBarry Smith       mat_ilen = c->ilen + i;
1619*82b1193eSBarry Smith       for (k=kstart; k<kend; k++) {
1620*82b1193eSBarry Smith         if ((tcol=ssmap[a->j[k]])) {
1621*82b1193eSBarry Smith           *mat_j++ = tcol - (!shift);
1622*82b1193eSBarry Smith           *mat_a++ = a->a[k];
1623*82b1193eSBarry Smith           (*mat_ilen)++;
1624*82b1193eSBarry Smith 
1625*82b1193eSBarry Smith         }
1626*82b1193eSBarry Smith       }
1627*82b1193eSBarry Smith     }
1628*82b1193eSBarry Smith     /* Free work space */
1629*82b1193eSBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1630*82b1193eSBarry Smith     ierr = PetscFree(smap);CHKERRQ(ierr);
1631*82b1193eSBarry Smith     ierr = PetscFree(lens);CHKERRQ(ierr);
1632*82b1193eSBarry Smith   }
1633*82b1193eSBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1634*82b1193eSBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1635*82b1193eSBarry Smith 
1636*82b1193eSBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
1637*82b1193eSBarry Smith   *B = C;
1638*82b1193eSBarry Smith   PetscFunctionReturn(0);
1639*82b1193eSBarry Smith }
1640*82b1193eSBarry Smith 
1641*82b1193eSBarry Smith /*
1642*82b1193eSBarry Smith */
1643*82b1193eSBarry Smith #undef __FUNC__
1644*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatILUFactor_SeqAIJ"></a>*/"MatILUFactor_SeqAIJ"
1645*82b1193eSBarry Smith int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatILUInfo *info)
1646*82b1193eSBarry Smith {
1647*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data;
1648*82b1193eSBarry Smith   int        ierr;
1649*82b1193eSBarry Smith   Mat        outA;
1650*82b1193eSBarry Smith   PetscTruth row_identity,col_identity;
1651*82b1193eSBarry Smith 
1652*82b1193eSBarry Smith   PetscFunctionBegin;
1653*82b1193eSBarry Smith   if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,0,"Only levels=0 supported for in-place ilu");
1654*82b1193eSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1655*82b1193eSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1656*82b1193eSBarry Smith   if (!row_identity || !col_identity) {
1657*82b1193eSBarry Smith     SETERRQ(1,1,"Row and column permutations must be identity for in-place ILU");
1658*82b1193eSBarry Smith   }
1659*82b1193eSBarry Smith 
1660*82b1193eSBarry Smith   outA          = inA;
1661*82b1193eSBarry Smith   inA->factor   = FACTOR_LU;
1662*82b1193eSBarry Smith   a->row        = row;
1663*82b1193eSBarry Smith   a->col        = col;
1664*82b1193eSBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1665*82b1193eSBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
1666*82b1193eSBarry Smith 
1667*82b1193eSBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
1668*82b1193eSBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */
1669*82b1193eSBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1670*82b1193eSBarry Smith   PLogObjectParent(inA,a->icol);
1671*82b1193eSBarry Smith 
1672*82b1193eSBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
1673*82b1193eSBarry Smith     a->solve_work = (Scalar*)PetscMalloc((a->m+1)*sizeof(Scalar));CHKPTRQ(a->solve_work);
1674*82b1193eSBarry Smith   }
1675*82b1193eSBarry Smith 
1676*82b1193eSBarry Smith   if (!a->diag) {
1677*82b1193eSBarry Smith     ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
1678*82b1193eSBarry Smith   }
1679*82b1193eSBarry Smith   ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA);CHKERRQ(ierr);
1680*82b1193eSBarry Smith   PetscFunctionReturn(0);
1681*82b1193eSBarry Smith }
1682*82b1193eSBarry Smith 
1683*82b1193eSBarry Smith #include "pinclude/blaslapack.h"
1684*82b1193eSBarry Smith #undef __FUNC__
1685*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatScale_SeqAIJ"></a>*/"MatScale_SeqAIJ"
1686*82b1193eSBarry Smith int MatScale_SeqAIJ(Scalar *alpha,Mat inA)
1687*82b1193eSBarry Smith {
1688*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data;
1689*82b1193eSBarry Smith   int        one = 1;
1690*82b1193eSBarry Smith 
1691*82b1193eSBarry Smith   PetscFunctionBegin;
1692*82b1193eSBarry Smith   BLscal_(&a->nz,alpha,a->a,&one);
1693*82b1193eSBarry Smith   PLogFlops(a->nz);
1694*82b1193eSBarry Smith   PetscFunctionReturn(0);
1695*82b1193eSBarry Smith }
1696*82b1193eSBarry Smith 
1697*82b1193eSBarry Smith #undef __FUNC__
1698*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetSubMatrices_SeqAIJ"></a>*/"MatGetSubMatrices_SeqAIJ"
1699*82b1193eSBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n,IS *irow,IS *icol,MatReuse scall,Mat **B)
1700*82b1193eSBarry Smith {
1701*82b1193eSBarry Smith   int ierr,i;
1702*82b1193eSBarry Smith 
1703*82b1193eSBarry Smith   PetscFunctionBegin;
1704*82b1193eSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1705*82b1193eSBarry Smith     *B = (Mat*)PetscMalloc((n+1)*sizeof(Mat));CHKPTRQ(*B);
1706*82b1193eSBarry Smith   }
1707*82b1193eSBarry Smith 
1708*82b1193eSBarry Smith   for (i=0; i<n; i++) {
1709*82b1193eSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1710*82b1193eSBarry Smith   }
1711*82b1193eSBarry Smith   PetscFunctionReturn(0);
1712*82b1193eSBarry Smith }
1713*82b1193eSBarry Smith 
1714*82b1193eSBarry Smith #undef __FUNC__
1715*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetBlockSize_SeqAIJ"></a>*/"MatGetBlockSize_SeqAIJ"
1716*82b1193eSBarry Smith int MatGetBlockSize_SeqAIJ(Mat A,int *bs)
1717*82b1193eSBarry Smith {
1718*82b1193eSBarry Smith   PetscFunctionBegin;
1719*82b1193eSBarry Smith   *bs = 1;
1720*82b1193eSBarry Smith   PetscFunctionReturn(0);
1721*82b1193eSBarry Smith }
1722*82b1193eSBarry Smith 
1723*82b1193eSBarry Smith #undef __FUNC__
1724*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatIncreaseOverlap_SeqAIJ"></a>*/"MatIncreaseOverlap_SeqAIJ"
1725*82b1193eSBarry Smith int MatIncreaseOverlap_SeqAIJ(Mat A,int is_max,IS *is,int ov)
1726*82b1193eSBarry Smith {
1727*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1728*82b1193eSBarry Smith   int        shift,row,i,j,k,l,m,n,*idx,ierr,*nidx,isz,val;
1729*82b1193eSBarry Smith   int        start,end,*ai,*aj;
1730*82b1193eSBarry Smith   PetscBT    table;
1731*82b1193eSBarry Smith 
1732*82b1193eSBarry Smith   PetscFunctionBegin;
1733*82b1193eSBarry Smith   shift = a->indexshift;
1734*82b1193eSBarry Smith   m     = a->m;
1735*82b1193eSBarry Smith   ai    = a->i;
1736*82b1193eSBarry Smith   aj    = a->j+shift;
1737*82b1193eSBarry Smith 
1738*82b1193eSBarry Smith   if (ov < 0)  SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"illegal overlap value used");
1739*82b1193eSBarry Smith 
1740*82b1193eSBarry Smith   nidx  = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(nidx);
1741*82b1193eSBarry Smith   ierr  = PetscBTCreate(m,table);CHKERRQ(ierr);
1742*82b1193eSBarry Smith 
1743*82b1193eSBarry Smith   for (i=0; i<is_max; i++) {
1744*82b1193eSBarry Smith     /* Initialize the two local arrays */
1745*82b1193eSBarry Smith     isz  = 0;
1746*82b1193eSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
1747*82b1193eSBarry Smith 
1748*82b1193eSBarry Smith     /* Extract the indices, assume there can be duplicate entries */
1749*82b1193eSBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
1750*82b1193eSBarry Smith     ierr = ISGetSize(is[i],&n);CHKERRQ(ierr);
1751*82b1193eSBarry Smith 
1752*82b1193eSBarry Smith     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
1753*82b1193eSBarry Smith     for (j=0; j<n ; ++j){
1754*82b1193eSBarry Smith       if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];}
1755*82b1193eSBarry Smith     }
1756*82b1193eSBarry Smith     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
1757*82b1193eSBarry Smith     ierr = ISDestroy(is[i]);CHKERRQ(ierr);
1758*82b1193eSBarry Smith 
1759*82b1193eSBarry Smith     k = 0;
1760*82b1193eSBarry Smith     for (j=0; j<ov; j++){ /* for each overlap */
1761*82b1193eSBarry Smith       n = isz;
1762*82b1193eSBarry Smith       for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
1763*82b1193eSBarry Smith         row   = nidx[k];
1764*82b1193eSBarry Smith         start = ai[row];
1765*82b1193eSBarry Smith         end   = ai[row+1];
1766*82b1193eSBarry Smith         for (l = start; l<end ; l++){
1767*82b1193eSBarry Smith           val = aj[l] + shift;
1768*82b1193eSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
1769*82b1193eSBarry Smith         }
1770*82b1193eSBarry Smith       }
1771*82b1193eSBarry Smith     }
1772*82b1193eSBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr);
1773*82b1193eSBarry Smith   }
1774*82b1193eSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
1775*82b1193eSBarry Smith   ierr = PetscFree(nidx);CHKERRQ(ierr);
1776*82b1193eSBarry Smith   PetscFunctionReturn(0);
1777*82b1193eSBarry Smith }
1778*82b1193eSBarry Smith 
1779*82b1193eSBarry Smith /* -------------------------------------------------------------- */
1780*82b1193eSBarry Smith #undef __FUNC__
1781*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatPermute_SeqAIJ"></a>*/"MatPermute_SeqAIJ"
1782*82b1193eSBarry Smith int MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
1783*82b1193eSBarry Smith {
1784*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1785*82b1193eSBarry Smith   Scalar     *vwork;
1786*82b1193eSBarry Smith   int        i,ierr,nz,m = a->m,n = a->n,*cwork;
1787*82b1193eSBarry Smith   int        *row,*col,*cnew,j,*lens;
1788*82b1193eSBarry Smith   IS         icolp,irowp;
1789*82b1193eSBarry Smith 
1790*82b1193eSBarry Smith   PetscFunctionBegin;
1791*82b1193eSBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
1792*82b1193eSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
1793*82b1193eSBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
1794*82b1193eSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
1795*82b1193eSBarry Smith 
1796*82b1193eSBarry Smith   /* determine lengths of permuted rows */
1797*82b1193eSBarry Smith   lens = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(lens);
1798*82b1193eSBarry Smith   for (i=0; i<m; i++) {
1799*82b1193eSBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
1800*82b1193eSBarry Smith   }
1801*82b1193eSBarry Smith   ierr = MatCreateSeqAIJ(A->comm,m,n,0,lens,B);CHKERRQ(ierr);
1802*82b1193eSBarry Smith   ierr = PetscFree(lens);CHKERRQ(ierr);
1803*82b1193eSBarry Smith 
1804*82b1193eSBarry Smith   cnew = (int*)PetscMalloc(n*sizeof(int));CHKPTRQ(cnew);
1805*82b1193eSBarry Smith   for (i=0; i<m; i++) {
1806*82b1193eSBarry Smith     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
1807*82b1193eSBarry Smith     for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];}
1808*82b1193eSBarry Smith     ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
1809*82b1193eSBarry Smith     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
1810*82b1193eSBarry Smith   }
1811*82b1193eSBarry Smith   ierr = PetscFree(cnew);CHKERRQ(ierr);
1812*82b1193eSBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1813*82b1193eSBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1814*82b1193eSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
1815*82b1193eSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
1816*82b1193eSBarry Smith   ierr = ISDestroy(irowp);CHKERRQ(ierr);
1817*82b1193eSBarry Smith   ierr = ISDestroy(icolp);CHKERRQ(ierr);
1818*82b1193eSBarry Smith   PetscFunctionReturn(0);
1819*82b1193eSBarry Smith }
1820*82b1193eSBarry Smith 
1821*82b1193eSBarry Smith #undef __FUNC__
1822*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatPrintHelp_SeqAIJ"></a>*/"MatPrintHelp_SeqAIJ"
1823*82b1193eSBarry Smith int MatPrintHelp_SeqAIJ(Mat A)
1824*82b1193eSBarry Smith {
1825*82b1193eSBarry Smith   static PetscTruth called = PETSC_FALSE;
1826*82b1193eSBarry Smith   MPI_Comm          comm = A->comm;
1827*82b1193eSBarry Smith   int               ierr;
1828*82b1193eSBarry Smith 
1829*82b1193eSBarry Smith   PetscFunctionBegin;
1830*82b1193eSBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1831*82b1193eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1832*82b1193eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr);
1833*82b1193eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr);
1834*82b1193eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_no_inode: Do not use inodes\n");CHKERRQ(ierr);
1835*82b1193eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");CHKERRQ(ierr);
1836*82b1193eSBarry Smith #if defined(PETSC_HAVE_ESSL)
1837*82b1193eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_essl: Use IBM sparse LU factorization and solve.\n");CHKERRQ(ierr);
1838*82b1193eSBarry Smith #endif
1839*82b1193eSBarry Smith #if defined(PETSC_HAVE_MATLAB)
1840*82b1193eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_matlab: Use Matlab engine sparse LU factorization and solve.\n");CHKERRQ(ierr);
1841*82b1193eSBarry Smith #endif
1842*82b1193eSBarry Smith   PetscFunctionReturn(0);
1843*82b1193eSBarry Smith }
1844*82b1193eSBarry Smith EXTERN int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg);
1845*82b1193eSBarry Smith EXTERN int MatFDColoringCreate_SeqAIJ(Mat,ISColoring,MatFDColoring);
1846*82b1193eSBarry Smith EXTERN int MatColoringPatch_SeqAIJ(Mat,int,int *,ISColoring *);
1847*82b1193eSBarry Smith EXTERN int MatILUDTFactor_SeqAIJ(Mat,MatILUInfo*,IS,IS,Mat*);
1848*82b1193eSBarry Smith #undef __FUNC__
1849*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatCopy_SeqAIJ"></a>*/"MatCopy_SeqAIJ"
1850*82b1193eSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
1851*82b1193eSBarry Smith {
1852*82b1193eSBarry Smith   int    ierr;
1853*82b1193eSBarry Smith 
1854*82b1193eSBarry Smith   PetscFunctionBegin;
1855*82b1193eSBarry Smith   if (str == SAME_NONZERO_PATTERN && B->type == MATSEQAIJ) {
1856*82b1193eSBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1857*82b1193eSBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
1858*82b1193eSBarry Smith 
1859*82b1193eSBarry Smith     if (a->i[a->m]+a->indexshift != b->i[b->m]+a->indexshift) {
1860*82b1193eSBarry Smith       SETERRQ(1,1,"Number of nonzeros in two matrices are different");
1861*82b1193eSBarry Smith     }
1862*82b1193eSBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[a->m]+a->indexshift)*sizeof(Scalar));CHKERRQ(ierr);
1863*82b1193eSBarry Smith   } else {
1864*82b1193eSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
1865*82b1193eSBarry Smith   }
1866*82b1193eSBarry Smith   PetscFunctionReturn(0);
1867*82b1193eSBarry Smith }
1868*82b1193eSBarry Smith 
1869*82b1193eSBarry Smith /* -------------------------------------------------------------------*/
1870*82b1193eSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
1871*82b1193eSBarry Smith        MatGetRow_SeqAIJ,
1872*82b1193eSBarry Smith        MatRestoreRow_SeqAIJ,
1873*82b1193eSBarry Smith        MatMult_SeqAIJ,
1874*82b1193eSBarry Smith        MatMultAdd_SeqAIJ,
1875*82b1193eSBarry Smith        MatMultTranspose_SeqAIJ,
1876*82b1193eSBarry Smith        MatMultTransposeAdd_SeqAIJ,
1877*82b1193eSBarry Smith        MatSolve_SeqAIJ,
1878*82b1193eSBarry Smith        MatSolveAdd_SeqAIJ,
1879*82b1193eSBarry Smith        MatSolveTranspose_SeqAIJ,
1880*82b1193eSBarry Smith        MatSolveTransposeAdd_SeqAIJ,
1881*82b1193eSBarry Smith        MatLUFactor_SeqAIJ,
1882*82b1193eSBarry Smith        0,
1883*82b1193eSBarry Smith        MatRelax_SeqAIJ,
1884*82b1193eSBarry Smith        MatTranspose_SeqAIJ,
1885*82b1193eSBarry Smith        MatGetInfo_SeqAIJ,
1886*82b1193eSBarry Smith        MatEqual_SeqAIJ,
1887*82b1193eSBarry Smith        MatGetDiagonal_SeqAIJ,
1888*82b1193eSBarry Smith        MatDiagonalScale_SeqAIJ,
1889*82b1193eSBarry Smith        MatNorm_SeqAIJ,
1890*82b1193eSBarry Smith        0,
1891*82b1193eSBarry Smith        MatAssemblyEnd_SeqAIJ,
1892*82b1193eSBarry Smith        MatCompress_SeqAIJ,
1893*82b1193eSBarry Smith        MatSetOption_SeqAIJ,
1894*82b1193eSBarry Smith        MatZeroEntries_SeqAIJ,
1895*82b1193eSBarry Smith        MatZeroRows_SeqAIJ,
1896*82b1193eSBarry Smith        MatLUFactorSymbolic_SeqAIJ,
1897*82b1193eSBarry Smith        MatLUFactorNumeric_SeqAIJ,
1898*82b1193eSBarry Smith        0,
1899*82b1193eSBarry Smith        0,
1900*82b1193eSBarry Smith        MatGetSize_SeqAIJ,
1901*82b1193eSBarry Smith        MatGetSize_SeqAIJ,
1902*82b1193eSBarry Smith        MatGetOwnershipRange_SeqAIJ,
1903*82b1193eSBarry Smith        MatILUFactorSymbolic_SeqAIJ,
1904*82b1193eSBarry Smith        0,
1905*82b1193eSBarry Smith        0,
1906*82b1193eSBarry Smith        0,
1907*82b1193eSBarry Smith        MatDuplicate_SeqAIJ,
1908*82b1193eSBarry Smith        0,
1909*82b1193eSBarry Smith        0,
1910*82b1193eSBarry Smith        MatILUFactor_SeqAIJ,
1911*82b1193eSBarry Smith        0,
1912*82b1193eSBarry Smith        0,
1913*82b1193eSBarry Smith        MatGetSubMatrices_SeqAIJ,
1914*82b1193eSBarry Smith        MatIncreaseOverlap_SeqAIJ,
1915*82b1193eSBarry Smith        MatGetValues_SeqAIJ,
1916*82b1193eSBarry Smith        MatCopy_SeqAIJ,
1917*82b1193eSBarry Smith        MatPrintHelp_SeqAIJ,
1918*82b1193eSBarry Smith        MatScale_SeqAIJ,
1919*82b1193eSBarry Smith        0,
1920*82b1193eSBarry Smith        0,
1921*82b1193eSBarry Smith        MatILUDTFactor_SeqAIJ,
1922*82b1193eSBarry Smith        MatGetBlockSize_SeqAIJ,
1923*82b1193eSBarry Smith        MatGetRowIJ_SeqAIJ,
1924*82b1193eSBarry Smith        MatRestoreRowIJ_SeqAIJ,
1925*82b1193eSBarry Smith        MatGetColumnIJ_SeqAIJ,
1926*82b1193eSBarry Smith        MatRestoreColumnIJ_SeqAIJ,
1927*82b1193eSBarry Smith        MatFDColoringCreate_SeqAIJ,
1928*82b1193eSBarry Smith        MatColoringPatch_SeqAIJ,
1929*82b1193eSBarry Smith        0,
1930*82b1193eSBarry Smith        MatPermute_SeqAIJ,
1931*82b1193eSBarry Smith        0,
1932*82b1193eSBarry Smith        0,
1933*82b1193eSBarry Smith        0,
1934*82b1193eSBarry Smith        0,
1935*82b1193eSBarry Smith        MatGetMaps_Petsc};
1936*82b1193eSBarry Smith 
1937*82b1193eSBarry Smith EXTERN int MatUseSuperLU_SeqAIJ(Mat);
1938*82b1193eSBarry Smith EXTERN int MatUseEssl_SeqAIJ(Mat);
1939*82b1193eSBarry Smith EXTERN int MatUseMatlab_SeqAIJ(Mat);
1940*82b1193eSBarry Smith EXTERN int MatUseDXML_SeqAIJ(Mat);
1941*82b1193eSBarry Smith 
1942*82b1193eSBarry Smith EXTERN_C_BEGIN
1943*82b1193eSBarry Smith #undef __FUNC__
1944*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatSeqAIJSetColumnIndices_SeqAIJ"></a>*/"MatSeqAIJSetColumnIndices_SeqAIJ"
1945*82b1193eSBarry Smith 
1946*82b1193eSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices)
1947*82b1193eSBarry Smith {
1948*82b1193eSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
1949*82b1193eSBarry Smith   int        i,nz,n;
1950*82b1193eSBarry Smith 
1951*82b1193eSBarry Smith   PetscFunctionBegin;
1952*82b1193eSBarry Smith   if (aij->indexshift) SETERRQ(1,1,"No support with 1 based indexing");
1953*82b1193eSBarry Smith 
1954*82b1193eSBarry Smith   nz = aij->maxnz;
1955*82b1193eSBarry Smith   n  = aij->n;
1956*82b1193eSBarry Smith   for (i=0; i<nz; i++) {
1957*82b1193eSBarry Smith     aij->j[i] = indices[i];
1958*82b1193eSBarry Smith   }
1959*82b1193eSBarry Smith   aij->nz = nz;
1960*82b1193eSBarry Smith   for (i=0; i<n; i++) {
1961*82b1193eSBarry Smith     aij->ilen[i] = aij->imax[i];
1962*82b1193eSBarry Smith   }
1963*82b1193eSBarry Smith 
1964*82b1193eSBarry Smith   PetscFunctionReturn(0);
1965*82b1193eSBarry Smith }
1966*82b1193eSBarry Smith EXTERN_C_END
1967*82b1193eSBarry Smith 
1968*82b1193eSBarry Smith #undef __FUNC__
1969*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatSeqAIJSetColumnIndices"></a>*/"MatSeqAIJSetColumnIndices"
1970*82b1193eSBarry Smith /*@
1971*82b1193eSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
1972*82b1193eSBarry Smith        in the matrix.
1973*82b1193eSBarry Smith 
1974*82b1193eSBarry Smith   Input Parameters:
1975*82b1193eSBarry Smith +  mat - the SeqAIJ matrix
1976*82b1193eSBarry Smith -  indices - the column indices
1977*82b1193eSBarry Smith 
1978*82b1193eSBarry Smith   Level: advanced
1979*82b1193eSBarry Smith 
1980*82b1193eSBarry Smith   Notes:
1981*82b1193eSBarry Smith     This can be called if you have precomputed the nonzero structure of the
1982*82b1193eSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
1983*82b1193eSBarry Smith   of the MatSetValues() operation.
1984*82b1193eSBarry Smith 
1985*82b1193eSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
1986*82b1193eSBarry Smith   MatCreateSeqAIJ().
1987*82b1193eSBarry Smith 
1988*82b1193eSBarry Smith     MUST be called before any calls to MatSetValues();
1989*82b1193eSBarry Smith 
1990*82b1193eSBarry Smith @*/
1991*82b1193eSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices)
1992*82b1193eSBarry Smith {
1993*82b1193eSBarry Smith   int ierr,(*f)(Mat,int *);
1994*82b1193eSBarry Smith 
1995*82b1193eSBarry Smith   PetscFunctionBegin;
1996*82b1193eSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1997*82b1193eSBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void **)&f);CHKERRQ(ierr);
1998*82b1193eSBarry Smith   if (f) {
1999*82b1193eSBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
2000*82b1193eSBarry Smith   } else {
2001*82b1193eSBarry Smith     SETERRQ(1,1,"Wrong type of matrix to set column indices");
2002*82b1193eSBarry Smith   }
2003*82b1193eSBarry Smith   PetscFunctionReturn(0);
2004*82b1193eSBarry Smith }
2005*82b1193eSBarry Smith 
2006*82b1193eSBarry Smith /* ----------------------------------------------------------------------------------------*/
2007*82b1193eSBarry Smith 
2008*82b1193eSBarry Smith EXTERN_C_BEGIN
2009*82b1193eSBarry Smith #undef __FUNC__
2010*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatStoreValues_SeqAIJ"></a>*/"MatStoreValues_SeqAIJ"
2011*82b1193eSBarry Smith int MatStoreValues_SeqAIJ(Mat mat)
2012*82b1193eSBarry Smith {
2013*82b1193eSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2014*82b1193eSBarry Smith   int        nz = aij->i[aij->m]+aij->indexshift,ierr;
2015*82b1193eSBarry Smith 
2016*82b1193eSBarry Smith   PetscFunctionBegin;
2017*82b1193eSBarry Smith   if (aij->nonew != 1) {
2018*82b1193eSBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2019*82b1193eSBarry Smith   }
2020*82b1193eSBarry Smith 
2021*82b1193eSBarry Smith   /* allocate space for values if not already there */
2022*82b1193eSBarry Smith   if (!aij->saved_values) {
2023*82b1193eSBarry Smith     aij->saved_values = (Scalar*)PetscMalloc(nz*sizeof(Scalar));CHKPTRQ(aij->saved_values);
2024*82b1193eSBarry Smith   }
2025*82b1193eSBarry Smith 
2026*82b1193eSBarry Smith   /* copy values over */
2027*82b1193eSBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr);
2028*82b1193eSBarry Smith   PetscFunctionReturn(0);
2029*82b1193eSBarry Smith }
2030*82b1193eSBarry Smith EXTERN_C_END
2031*82b1193eSBarry Smith 
2032*82b1193eSBarry Smith #undef __FUNC__
2033*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatStoreValues""></a>*/"MatStoreValues"
2034*82b1193eSBarry Smith /*@
2035*82b1193eSBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
2036*82b1193eSBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2037*82b1193eSBarry Smith        nonlinear portion.
2038*82b1193eSBarry Smith 
2039*82b1193eSBarry Smith    Collect on Mat
2040*82b1193eSBarry Smith 
2041*82b1193eSBarry Smith   Input Parameters:
2042*82b1193eSBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2043*82b1193eSBarry Smith 
2044*82b1193eSBarry Smith   Level: advanced
2045*82b1193eSBarry Smith 
2046*82b1193eSBarry Smith   Common Usage, with SNESSolve():
2047*82b1193eSBarry Smith $    Create Jacobian matrix
2048*82b1193eSBarry Smith $    Set linear terms into matrix
2049*82b1193eSBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
2050*82b1193eSBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
2051*82b1193eSBarry Smith $      boundary conditions again will not change the nonzero structure
2052*82b1193eSBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2053*82b1193eSBarry Smith $    ierr = MatStoreValues(mat);
2054*82b1193eSBarry Smith $    Call SNESSetJacobian() with matrix
2055*82b1193eSBarry Smith $    In your Jacobian routine
2056*82b1193eSBarry Smith $      ierr = MatRetrieveValues(mat);
2057*82b1193eSBarry Smith $      Set nonlinear terms in matrix
2058*82b1193eSBarry Smith 
2059*82b1193eSBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
2060*82b1193eSBarry Smith $    // build linear portion of Jacobian
2061*82b1193eSBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2062*82b1193eSBarry Smith $    ierr = MatStoreValues(mat);
2063*82b1193eSBarry Smith $    loop over nonlinear iterations
2064*82b1193eSBarry Smith $       ierr = MatRetrieveValues(mat);
2065*82b1193eSBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
2066*82b1193eSBarry Smith $       // call MatAssemblyBegin/End() on matrix
2067*82b1193eSBarry Smith $       Solve linear system with Jacobian
2068*82b1193eSBarry Smith $    endloop
2069*82b1193eSBarry Smith 
2070*82b1193eSBarry Smith   Notes:
2071*82b1193eSBarry Smith     Matrix must already be assemblied before calling this routine
2072*82b1193eSBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before
2073*82b1193eSBarry Smith     calling this routine.
2074*82b1193eSBarry Smith 
2075*82b1193eSBarry Smith .seealso: MatRetrieveValues()
2076*82b1193eSBarry Smith 
2077*82b1193eSBarry Smith @*/
2078*82b1193eSBarry Smith int MatStoreValues(Mat mat)
2079*82b1193eSBarry Smith {
2080*82b1193eSBarry Smith   int ierr,(*f)(Mat);
2081*82b1193eSBarry Smith 
2082*82b1193eSBarry Smith   PetscFunctionBegin;
2083*82b1193eSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2084*82b1193eSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2085*82b1193eSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2086*82b1193eSBarry Smith 
2087*82b1193eSBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void **)&f);CHKERRQ(ierr);
2088*82b1193eSBarry Smith   if (f) {
2089*82b1193eSBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2090*82b1193eSBarry Smith   } else {
2091*82b1193eSBarry Smith     SETERRQ(1,1,"Wrong type of matrix to store values");
2092*82b1193eSBarry Smith   }
2093*82b1193eSBarry Smith   PetscFunctionReturn(0);
2094*82b1193eSBarry Smith }
2095*82b1193eSBarry Smith 
2096*82b1193eSBarry Smith EXTERN_C_BEGIN
2097*82b1193eSBarry Smith #undef __FUNC__
2098*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatRetrieveValues_SeqAIJ"></a>*/"MatRetrieveValues_SeqAIJ"
2099*82b1193eSBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat)
2100*82b1193eSBarry Smith {
2101*82b1193eSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2102*82b1193eSBarry Smith   int        nz = aij->i[aij->m]+aij->indexshift,ierr;
2103*82b1193eSBarry Smith 
2104*82b1193eSBarry Smith   PetscFunctionBegin;
2105*82b1193eSBarry Smith   if (aij->nonew != 1) {
2106*82b1193eSBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2107*82b1193eSBarry Smith   }
2108*82b1193eSBarry Smith   if (!aij->saved_values) {
2109*82b1193eSBarry Smith     SETERRQ(1,1,"Must call MatStoreValues(A);first");
2110*82b1193eSBarry Smith   }
2111*82b1193eSBarry Smith 
2112*82b1193eSBarry Smith   /* copy values over */
2113*82b1193eSBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr);
2114*82b1193eSBarry Smith   PetscFunctionReturn(0);
2115*82b1193eSBarry Smith }
2116*82b1193eSBarry Smith EXTERN_C_END
2117*82b1193eSBarry Smith 
2118*82b1193eSBarry Smith #undef __FUNC__
2119*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatRetrieveValues"></a>*/"MatRetrieveValues"
2120*82b1193eSBarry Smith /*@
2121*82b1193eSBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
2122*82b1193eSBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2123*82b1193eSBarry Smith        nonlinear portion.
2124*82b1193eSBarry Smith 
2125*82b1193eSBarry Smith    Collect on Mat
2126*82b1193eSBarry Smith 
2127*82b1193eSBarry Smith   Input Parameters:
2128*82b1193eSBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2129*82b1193eSBarry Smith 
2130*82b1193eSBarry Smith   Level: advanced
2131*82b1193eSBarry Smith 
2132*82b1193eSBarry Smith .seealso: MatStoreValues()
2133*82b1193eSBarry Smith 
2134*82b1193eSBarry Smith @*/
2135*82b1193eSBarry Smith int MatRetrieveValues(Mat mat)
2136*82b1193eSBarry Smith {
2137*82b1193eSBarry Smith   int ierr,(*f)(Mat);
2138*82b1193eSBarry Smith 
2139*82b1193eSBarry Smith   PetscFunctionBegin;
2140*82b1193eSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2141*82b1193eSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2142*82b1193eSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2143*82b1193eSBarry Smith 
2144*82b1193eSBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void **)&f);CHKERRQ(ierr);
2145*82b1193eSBarry Smith   if (f) {
2146*82b1193eSBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2147*82b1193eSBarry Smith   } else {
2148*82b1193eSBarry Smith     SETERRQ(1,1,"Wrong type of matrix to retrieve values");
2149*82b1193eSBarry Smith   }
2150*82b1193eSBarry Smith   PetscFunctionReturn(0);
2151*82b1193eSBarry Smith }
2152*82b1193eSBarry Smith 
2153*82b1193eSBarry Smith /*
2154*82b1193eSBarry Smith    This allows SeqAIJ matrices to be passed to the matlab engine
2155*82b1193eSBarry Smith */
2156*82b1193eSBarry Smith #if defined(PETSC_HAVE_MATLAB)
2157*82b1193eSBarry Smith #include "engine.h"   /* Matlab include file */
2158*82b1193eSBarry Smith #include "mex.h"      /* Matlab include file */
2159*82b1193eSBarry Smith EXTERN_C_BEGIN
2160*82b1193eSBarry Smith #undef __FUNC__
2161*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatMatlabEnginePut_SeqAIJ"></a>*/"MatMatlabEnginePut_SeqAIJ"
2162*82b1193eSBarry Smith int MatMatlabEnginePut_SeqAIJ(PetscObject obj,void *engine)
2163*82b1193eSBarry Smith {
2164*82b1193eSBarry Smith   int        ierr,i,*aj,*ai;
2165*82b1193eSBarry Smith   Mat        B = (Mat)obj;
2166*82b1193eSBarry Smith   Scalar     *array;
2167*82b1193eSBarry Smith   mxArray    *mat;
2168*82b1193eSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)B->data;
2169*82b1193eSBarry Smith 
2170*82b1193eSBarry Smith 
2171*82b1193eSBarry Smith   PetscFunctionBegin;
2172*82b1193eSBarry Smith   mat  = mxCreateSparse(B->n,B->m,aij->nz,mxREAL);
2173*82b1193eSBarry Smith   ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(Scalar));CHKERRQ(ierr);
2174*82b1193eSBarry Smith   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
2175*82b1193eSBarry Smith   ai   = mxGetJc(mat);
2176*82b1193eSBarry Smith   aj   = mxGetIr(mat);
2177*82b1193eSBarry Smith   ierr = PetscMemcpy(aj,aij->j,aij->nz*sizeof(int));CHKERRQ(ierr);
2178*82b1193eSBarry Smith   ierr = PetscMemcpy(ai,aij->i,(B->m+1)*sizeof(int));CHKERRQ(ierr);
2179*82b1193eSBarry Smith 
2180*82b1193eSBarry Smith   /* Matlab indices start at 0 for sparse (what a surprise) */
2181*82b1193eSBarry Smith   if (aij->indexshift) {
2182*82b1193eSBarry Smith     for (i=0; i<B->m+1; i++) {
2183*82b1193eSBarry Smith       ai[i]--;
2184*82b1193eSBarry Smith     }
2185*82b1193eSBarry Smith     for (i=0; i<aij->nz; i++) {
2186*82b1193eSBarry Smith       aj[i]--;
2187*82b1193eSBarry Smith     }
2188*82b1193eSBarry Smith   }
2189*82b1193eSBarry Smith   ierr = PetscObjectName(obj);CHKERRQ(ierr);
2190*82b1193eSBarry Smith   mxSetName(mat,obj->name);
2191*82b1193eSBarry Smith   engPutArray((Engine *)engine,mat);
2192*82b1193eSBarry Smith   PetscFunctionReturn(0);
2193*82b1193eSBarry Smith }
2194*82b1193eSBarry Smith EXTERN_C_END
2195*82b1193eSBarry Smith #endif
2196*82b1193eSBarry Smith 
2197*82b1193eSBarry Smith /* --------------------------------------------------------------------------------*/
2198*82b1193eSBarry Smith 
2199*82b1193eSBarry Smith #undef __FUNC__
2200*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatCreateSeqAIJ"></a>*/"MatCreateSeqAIJ"
2201*82b1193eSBarry Smith /*@C
2202*82b1193eSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
2203*82b1193eSBarry Smith    (the default parallel PETSc format).  For good matrix assembly performance
2204*82b1193eSBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
2205*82b1193eSBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
2206*82b1193eSBarry Smith    during matrix assembly can be increased by more than a factor of 50.
2207*82b1193eSBarry Smith 
2208*82b1193eSBarry Smith    Collective on MPI_Comm
2209*82b1193eSBarry Smith 
2210*82b1193eSBarry Smith    Input Parameters:
2211*82b1193eSBarry Smith +  comm - MPI communicator, set to PETSC_COMM_SELF
2212*82b1193eSBarry Smith .  m - number of rows
2213*82b1193eSBarry Smith .  n - number of columns
2214*82b1193eSBarry Smith .  nz - number of nonzeros per row (same for all rows)
2215*82b1193eSBarry Smith -  nnz - array containing the number of nonzeros in the various rows
2216*82b1193eSBarry Smith          (possibly different for each row) or PETSC_NULL
2217*82b1193eSBarry Smith 
2218*82b1193eSBarry Smith    Output Parameter:
2219*82b1193eSBarry Smith .  A - the matrix
2220*82b1193eSBarry Smith 
2221*82b1193eSBarry Smith    Notes:
2222*82b1193eSBarry Smith    The AIJ format (also called the Yale sparse matrix format or
2223*82b1193eSBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
2224*82b1193eSBarry Smith    storage.  That is, the stored row and column indices can begin at
2225*82b1193eSBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
2226*82b1193eSBarry Smith 
2227*82b1193eSBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2228*82b1193eSBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
2229*82b1193eSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
2230*82b1193eSBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
2231*82b1193eSBarry Smith 
2232*82b1193eSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
2233*82b1193eSBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
2234*82b1193eSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
2235*82b1193eSBarry Smith    reusing matrix information to achieve increased efficiency.
2236*82b1193eSBarry Smith 
2237*82b1193eSBarry Smith    Options Database Keys:
2238*82b1193eSBarry Smith +  -mat_aij_no_inode  - Do not use inodes
2239*82b1193eSBarry Smith .  -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5)
2240*82b1193eSBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
2241*82b1193eSBarry Smith         rather than 0.  Note that when calling MatSetValues(),
2242*82b1193eSBarry Smith         the user still MUST index entries starting at 0!
2243*82b1193eSBarry Smith 
2244*82b1193eSBarry Smith    Level: intermediate
2245*82b1193eSBarry Smith 
2246*82b1193eSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
2247*82b1193eSBarry Smith 
2248*82b1193eSBarry Smith @*/
2249*82b1193eSBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,int *nnz,Mat *A)
2250*82b1193eSBarry Smith {
2251*82b1193eSBarry Smith   Mat        B;
2252*82b1193eSBarry Smith   Mat_SeqAIJ *b;
2253*82b1193eSBarry Smith   int        i,len,ierr,size;
2254*82b1193eSBarry Smith   PetscTruth flg;
2255*82b1193eSBarry Smith 
2256*82b1193eSBarry Smith   PetscFunctionBegin;
2257*82b1193eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2258*82b1193eSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Comm must be of size 1");
2259*82b1193eSBarry Smith 
2260*82b1193eSBarry Smith   if (nz < -2) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"nz cannot be less than -2: value %d",nz);
2261*82b1193eSBarry Smith   if (nnz) {
2262*82b1193eSBarry Smith     for (i=0; i<m; i++) {
2263*82b1193eSBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
2264*82b1193eSBarry Smith     }
2265*82b1193eSBarry Smith   }
2266*82b1193eSBarry Smith 
2267*82b1193eSBarry Smith   *A                  = 0;
2268*82b1193eSBarry Smith   PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,"Mat",comm,MatDestroy,MatView);
2269*82b1193eSBarry Smith   PLogObjectCreate(B);
2270*82b1193eSBarry Smith   B->data             = (void*)(b = PetscNew(Mat_SeqAIJ));CHKPTRQ(b);
2271*82b1193eSBarry Smith   ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr);
2272*82b1193eSBarry Smith   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
2273*82b1193eSBarry Smith   B->ops->destroy          = MatDestroy_SeqAIJ;
2274*82b1193eSBarry Smith   B->ops->view             = MatView_SeqAIJ;
2275*82b1193eSBarry Smith   B->factor           = 0;
2276*82b1193eSBarry Smith   B->lupivotthreshold = 1.0;
2277*82b1193eSBarry Smith   B->mapping          = 0;
2278*82b1193eSBarry Smith   ierr = OptionsGetDouble(PETSC_NULL,"-mat_lu_pivotthreshold",&B->lupivotthreshold,PETSC_NULL);CHKERRQ(ierr);
2279*82b1193eSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-pc_ilu_preserve_row_sums",&b->ilu_preserve_row_sums);CHKERRQ(ierr);
2280*82b1193eSBarry Smith   b->row              = 0;
2281*82b1193eSBarry Smith   b->col              = 0;
2282*82b1193eSBarry Smith   b->icol             = 0;
2283*82b1193eSBarry Smith   b->indexshift       = 0;
2284*82b1193eSBarry Smith   b->reallocs         = 0;
2285*82b1193eSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_oneindex",&flg);CHKERRQ(ierr);
2286*82b1193eSBarry Smith   if (flg) b->indexshift = -1;
2287*82b1193eSBarry Smith 
2288*82b1193eSBarry Smith   b->m = m; B->m = m; B->M = m;
2289*82b1193eSBarry Smith   b->n = n; B->n = n; B->N = n;
2290*82b1193eSBarry Smith 
2291*82b1193eSBarry Smith   ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr);
2292*82b1193eSBarry Smith   ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr);
2293*82b1193eSBarry Smith 
2294*82b1193eSBarry Smith   b->imax = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(b->imax);
2295*82b1193eSBarry Smith   if (!nnz) {
2296*82b1193eSBarry Smith     if (nz == PETSC_DEFAULT) nz = 10;
2297*82b1193eSBarry Smith     else if (nz <= 0)        nz = 1;
2298*82b1193eSBarry Smith     for (i=0; i<m; i++) b->imax[i] = nz;
2299*82b1193eSBarry Smith     nz = nz*m;
2300*82b1193eSBarry Smith   } else {
2301*82b1193eSBarry Smith     nz = 0;
2302*82b1193eSBarry Smith     for (i=0; i<m; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
2303*82b1193eSBarry Smith   }
2304*82b1193eSBarry Smith 
2305*82b1193eSBarry Smith   /* allocate the matrix space */
2306*82b1193eSBarry Smith   len             = nz*(sizeof(int) + sizeof(Scalar)) + (b->m+1)*sizeof(int);
2307*82b1193eSBarry Smith   b->a            = (Scalar*)PetscMalloc(len);CHKPTRQ(b->a);
2308*82b1193eSBarry Smith   b->j            = (int*)(b->a + nz);
2309*82b1193eSBarry Smith   ierr            = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
2310*82b1193eSBarry Smith   b->i            = b->j + nz;
2311*82b1193eSBarry Smith   b->singlemalloc = PETSC_TRUE;
2312*82b1193eSBarry Smith   b->freedata     = PETSC_TRUE;
2313*82b1193eSBarry Smith 
2314*82b1193eSBarry Smith   b->i[0] = -b->indexshift;
2315*82b1193eSBarry Smith   for (i=1; i<m+1; i++) {
2316*82b1193eSBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
2317*82b1193eSBarry Smith   }
2318*82b1193eSBarry Smith 
2319*82b1193eSBarry Smith   /* b->ilen will count nonzeros in each row so far. */
2320*82b1193eSBarry Smith   b->ilen = (int*)PetscMalloc((m+1)*sizeof(int));
2321*82b1193eSBarry Smith   PLogObjectMemory(B,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2322*82b1193eSBarry Smith   for (i=0; i<b->m; i++) { b->ilen[i] = 0;}
2323*82b1193eSBarry Smith 
2324*82b1193eSBarry Smith   b->nz                = 0;
2325*82b1193eSBarry Smith   b->maxnz             = nz;
2326*82b1193eSBarry Smith   b->sorted            = PETSC_FALSE;
2327*82b1193eSBarry Smith   b->ignorezeroentries = PETSC_FALSE;
2328*82b1193eSBarry Smith   b->roworiented       = PETSC_TRUE;
2329*82b1193eSBarry Smith   b->nonew             = 0;
2330*82b1193eSBarry Smith   b->diag              = 0;
2331*82b1193eSBarry Smith   b->solve_work        = 0;
2332*82b1193eSBarry Smith   b->spptr             = 0;
2333*82b1193eSBarry Smith   b->inode.use         = PETSC_TRUE;
2334*82b1193eSBarry Smith   b->inode.node_count  = 0;
2335*82b1193eSBarry Smith   b->inode.size        = 0;
2336*82b1193eSBarry Smith   b->inode.limit       = 5;
2337*82b1193eSBarry Smith   b->inode.max_limit   = 5;
2338*82b1193eSBarry Smith   b->saved_values      = 0;
2339*82b1193eSBarry Smith   B->info.nz_unneeded  = (double)b->maxnz;
2340*82b1193eSBarry Smith   b->idiag             = 0;
2341*82b1193eSBarry Smith   b->ssor              = 0;
2342*82b1193eSBarry Smith   b->keepzeroedrows    = PETSC_FALSE;
2343*82b1193eSBarry Smith 
2344*82b1193eSBarry Smith   *A = B;
2345*82b1193eSBarry Smith 
2346*82b1193eSBarry Smith   /*  SuperLU is not currently supported through PETSc */
2347*82b1193eSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
2348*82b1193eSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_superlu",&flg);CHKERRQ(ierr);
2349*82b1193eSBarry Smith   if (flg) { ierr = MatUseSuperLU_SeqAIJ(B);CHKERRQ(ierr); }
2350*82b1193eSBarry Smith #endif
2351*82b1193eSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_essl",&flg);CHKERRQ(ierr);
2352*82b1193eSBarry Smith   if (flg) { ierr = MatUseEssl_SeqAIJ(B);CHKERRQ(ierr); }
2353*82b1193eSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_matlab",&flg);CHKERRQ(ierr);
2354*82b1193eSBarry Smith   if (flg) {ierr = MatUseMatlab_SeqAIJ(B);CHKERRQ(ierr);}
2355*82b1193eSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_dxml",&flg);CHKERRQ(ierr);
2356*82b1193eSBarry Smith   if (flg) {
2357*82b1193eSBarry Smith     if (!b->indexshift) SETERRQ(PETSC_ERR_LIB,0,"need -mat_aij_oneindex with -mat_aij_dxml");
2358*82b1193eSBarry Smith     ierr = MatUseDXML_SeqAIJ(B);CHKERRQ(ierr);
2359*82b1193eSBarry Smith   }
2360*82b1193eSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr);
2361*82b1193eSBarry Smith   if (flg) {ierr = MatPrintHelp(B);CHKERRQ(ierr); }
2362*82b1193eSBarry Smith 
2363*82b1193eSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C",
2364*82b1193eSBarry Smith                                      "MatSeqAIJSetColumnIndices_SeqAIJ",
2365*82b1193eSBarry Smith                                      MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
2366*82b1193eSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
2367*82b1193eSBarry Smith                                      "MatStoreValues_SeqAIJ",
2368*82b1193eSBarry Smith                                      MatStoreValues_SeqAIJ);CHKERRQ(ierr);
2369*82b1193eSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
2370*82b1193eSBarry Smith                                      "MatRetrieveValues_SeqAIJ",
2371*82b1193eSBarry Smith                                      MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
2372*82b1193eSBarry Smith #if defined(PETSC_HAVE_MATLAB)
2373*82b1193eSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatMatlabEnginePut_SeqAIJ",MatMatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
2374*82b1193eSBarry Smith #endif
2375*82b1193eSBarry Smith   PetscFunctionReturn(0);
2376*82b1193eSBarry Smith }
2377*82b1193eSBarry Smith 
2378*82b1193eSBarry Smith #undef __FUNC__
2379*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatDuplicate_SeqAIJ"></a>*/"MatDuplicate_SeqAIJ"
2380*82b1193eSBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
2381*82b1193eSBarry Smith {
2382*82b1193eSBarry Smith   Mat        C;
2383*82b1193eSBarry Smith   Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data;
2384*82b1193eSBarry Smith   int        i,len,m = a->m,shift = a->indexshift,ierr;
2385*82b1193eSBarry Smith 
2386*82b1193eSBarry Smith   PetscFunctionBegin;
2387*82b1193eSBarry Smith   *B = 0;
2388*82b1193eSBarry Smith   PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,"Mat",A->comm,MatDestroy,MatView);
2389*82b1193eSBarry Smith   PLogObjectCreate(C);
2390*82b1193eSBarry Smith   C->data           = (void*)(c = PetscNew(Mat_SeqAIJ));CHKPTRQ(c);
2391*82b1193eSBarry Smith   ierr              = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
2392*82b1193eSBarry Smith   C->ops->destroy   = MatDestroy_SeqAIJ;
2393*82b1193eSBarry Smith   C->ops->view      = MatView_SeqAIJ;
2394*82b1193eSBarry Smith   C->factor         = A->factor;
2395*82b1193eSBarry Smith   c->row            = 0;
2396*82b1193eSBarry Smith   c->col            = 0;
2397*82b1193eSBarry Smith   c->icol           = 0;
2398*82b1193eSBarry Smith   c->indexshift     = shift;
2399*82b1193eSBarry Smith   c->keepzeroedrows = a->keepzeroedrows;
2400*82b1193eSBarry Smith   C->assembled      = PETSC_TRUE;
2401*82b1193eSBarry Smith 
2402*82b1193eSBarry Smith   c->m = C->m   = a->m;
2403*82b1193eSBarry Smith   c->n = C->n   = a->n;
2404*82b1193eSBarry Smith   C->M          = a->m;
2405*82b1193eSBarry Smith   C->N          = a->n;
2406*82b1193eSBarry Smith 
2407*82b1193eSBarry Smith   c->imax       = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->imax);
2408*82b1193eSBarry Smith   c->ilen       = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->ilen);
2409*82b1193eSBarry Smith   for (i=0; i<m; i++) {
2410*82b1193eSBarry Smith     c->imax[i] = a->imax[i];
2411*82b1193eSBarry Smith     c->ilen[i] = a->ilen[i];
2412*82b1193eSBarry Smith   }
2413*82b1193eSBarry Smith 
2414*82b1193eSBarry Smith   /* allocate the matrix space */
2415*82b1193eSBarry Smith   c->singlemalloc = PETSC_TRUE;
2416*82b1193eSBarry Smith   len     = (m+1)*sizeof(int)+(a->i[m])*(sizeof(Scalar)+sizeof(int));
2417*82b1193eSBarry Smith   c->a  = (Scalar*)PetscMalloc(len);CHKPTRQ(c->a);
2418*82b1193eSBarry Smith   c->j  = (int*)(c->a + a->i[m] + shift);
2419*82b1193eSBarry Smith   c->i  = c->j + a->i[m] + shift;
2420*82b1193eSBarry Smith   ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));CHKERRQ(ierr);
2421*82b1193eSBarry Smith   if (m > 0) {
2422*82b1193eSBarry Smith     ierr = PetscMemcpy(c->j,a->j,(a->i[m]+shift)*sizeof(int));CHKERRQ(ierr);
2423*82b1193eSBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
2424*82b1193eSBarry Smith       ierr = PetscMemcpy(c->a,a->a,(a->i[m]+shift)*sizeof(Scalar));CHKERRQ(ierr);
2425*82b1193eSBarry Smith     } else {
2426*82b1193eSBarry Smith       ierr = PetscMemzero(c->a,(a->i[m]+shift)*sizeof(Scalar));CHKERRQ(ierr);
2427*82b1193eSBarry Smith     }
2428*82b1193eSBarry Smith   }
2429*82b1193eSBarry Smith 
2430*82b1193eSBarry Smith   PLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2431*82b1193eSBarry Smith   c->sorted      = a->sorted;
2432*82b1193eSBarry Smith   c->roworiented = a->roworiented;
2433*82b1193eSBarry Smith   c->nonew       = a->nonew;
2434*82b1193eSBarry Smith   c->ilu_preserve_row_sums = a->ilu_preserve_row_sums;
2435*82b1193eSBarry Smith   c->saved_values = 0;
2436*82b1193eSBarry Smith   c->idiag        = 0;
2437*82b1193eSBarry Smith   c->ssor         = 0;
2438*82b1193eSBarry Smith   c->ignorezeroentries = a->ignorezeroentries;
2439*82b1193eSBarry Smith   c->freedata     = PETSC_TRUE;
2440*82b1193eSBarry Smith 
2441*82b1193eSBarry Smith   if (a->diag) {
2442*82b1193eSBarry Smith     c->diag = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->diag);
2443*82b1193eSBarry Smith     PLogObjectMemory(C,(m+1)*sizeof(int));
2444*82b1193eSBarry Smith     for (i=0; i<m; i++) {
2445*82b1193eSBarry Smith       c->diag[i] = a->diag[i];
2446*82b1193eSBarry Smith     }
2447*82b1193eSBarry Smith   } else c->diag        = 0;
2448*82b1193eSBarry Smith   c->inode.use          = a->inode.use;
2449*82b1193eSBarry Smith   c->inode.limit        = a->inode.limit;
2450*82b1193eSBarry Smith   c->inode.max_limit    = a->inode.max_limit;
2451*82b1193eSBarry Smith   if (a->inode.size){
2452*82b1193eSBarry Smith     c->inode.size       = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->inode.size);
2453*82b1193eSBarry Smith     c->inode.node_count = a->inode.node_count;
2454*82b1193eSBarry Smith     ierr = PetscMemcpy(c->inode.size,a->inode.size,(m+1)*sizeof(int));CHKERRQ(ierr);
2455*82b1193eSBarry Smith   } else {
2456*82b1193eSBarry Smith     c->inode.size       = 0;
2457*82b1193eSBarry Smith     c->inode.node_count = 0;
2458*82b1193eSBarry Smith   }
2459*82b1193eSBarry Smith   c->nz                 = a->nz;
2460*82b1193eSBarry Smith   c->maxnz              = a->maxnz;
2461*82b1193eSBarry Smith   c->solve_work         = 0;
2462*82b1193eSBarry Smith   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
2463*82b1193eSBarry Smith 
2464*82b1193eSBarry Smith   *B = C;
2465*82b1193eSBarry Smith   ierr = FListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
2466*82b1193eSBarry Smith   PetscFunctionReturn(0);
2467*82b1193eSBarry Smith }
2468*82b1193eSBarry Smith 
2469*82b1193eSBarry Smith #undef __FUNC__
2470*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatLoad_SeqAIJ"></a>*/"MatLoad_SeqAIJ"
2471*82b1193eSBarry Smith int MatLoad_SeqAIJ(Viewer viewer,MatType type,Mat *A)
2472*82b1193eSBarry Smith {
2473*82b1193eSBarry Smith   Mat_SeqAIJ   *a;
2474*82b1193eSBarry Smith   Mat          B;
2475*82b1193eSBarry Smith   int          i,nz,ierr,fd,header[4],size,*rowlengths = 0,M,N,shift;
2476*82b1193eSBarry Smith   MPI_Comm     comm;
2477*82b1193eSBarry Smith 
2478*82b1193eSBarry Smith   PetscFunctionBegin;
2479*82b1193eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
2480*82b1193eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2481*82b1193eSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,0,"view must have one processor");
2482*82b1193eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
2483*82b1193eSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
2484*82b1193eSBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not matrix object in file");
2485*82b1193eSBarry Smith   M = header[1]; N = header[2]; nz = header[3];
2486*82b1193eSBarry Smith 
2487*82b1193eSBarry Smith   if (nz < 0) {
2488*82b1193eSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format on disk,cannot load as SeqAIJ");
2489*82b1193eSBarry Smith   }
2490*82b1193eSBarry Smith 
2491*82b1193eSBarry Smith   /* read in row lengths */
2492*82b1193eSBarry Smith   rowlengths = (int*)PetscMalloc(M*sizeof(int));CHKPTRQ(rowlengths);
2493*82b1193eSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
2494*82b1193eSBarry Smith 
2495*82b1193eSBarry Smith   /* create our matrix */
2496*82b1193eSBarry Smith   ierr = MatCreateSeqAIJ(comm,M,N,0,rowlengths,A);CHKERRQ(ierr);
2497*82b1193eSBarry Smith   B = *A;
2498*82b1193eSBarry Smith   a = (Mat_SeqAIJ*)B->data;
2499*82b1193eSBarry Smith   shift = a->indexshift;
2500*82b1193eSBarry Smith 
2501*82b1193eSBarry Smith   /* read in column indices and adjust for Fortran indexing*/
2502*82b1193eSBarry Smith   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
2503*82b1193eSBarry Smith   if (shift) {
2504*82b1193eSBarry Smith     for (i=0; i<nz; i++) {
2505*82b1193eSBarry Smith       a->j[i] += 1;
2506*82b1193eSBarry Smith     }
2507*82b1193eSBarry Smith   }
2508*82b1193eSBarry Smith 
2509*82b1193eSBarry Smith   /* read in nonzero values */
2510*82b1193eSBarry Smith   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
2511*82b1193eSBarry Smith 
2512*82b1193eSBarry Smith   /* set matrix "i" values */
2513*82b1193eSBarry Smith   a->i[0] = -shift;
2514*82b1193eSBarry Smith   for (i=1; i<= M; i++) {
2515*82b1193eSBarry Smith     a->i[i]      = a->i[i-1] + rowlengths[i-1];
2516*82b1193eSBarry Smith     a->ilen[i-1] = rowlengths[i-1];
2517*82b1193eSBarry Smith   }
2518*82b1193eSBarry Smith   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
2519*82b1193eSBarry Smith 
2520*82b1193eSBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2521*82b1193eSBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2522*82b1193eSBarry Smith   PetscFunctionReturn(0);
2523*82b1193eSBarry Smith }
2524*82b1193eSBarry Smith 
2525*82b1193eSBarry Smith #undef __FUNC__
2526*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatEqual_SeqAIJ""></a>*/"MatEqual_SeqAIJ"
2527*82b1193eSBarry Smith int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg)
2528*82b1193eSBarry Smith {
2529*82b1193eSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data;
2530*82b1193eSBarry Smith   int        ierr;
2531*82b1193eSBarry Smith 
2532*82b1193eSBarry Smith   PetscFunctionBegin;
2533*82b1193eSBarry Smith   if (B->type != MATSEQAIJ) SETERRQ(PETSC_ERR_ARG_INCOMP,0,"Matrices must be same type");
2534*82b1193eSBarry Smith 
2535*82b1193eSBarry Smith   /* If the  matrix dimensions are not equal,or no of nonzeros or shift */
2536*82b1193eSBarry Smith   if ((a->m != b->m) || (a->n !=b->n) ||(a->nz != b->nz)|| (a->indexshift != b->indexshift)) {
2537*82b1193eSBarry Smith     *flg = PETSC_FALSE;
2538*82b1193eSBarry Smith     PetscFunctionReturn(0);
2539*82b1193eSBarry Smith   }
2540*82b1193eSBarry Smith 
2541*82b1193eSBarry Smith   /* if the a->i are the same */
2542*82b1193eSBarry Smith   ierr = PetscMemcmp(a->i,b->i,(a->m+1)*sizeof(int),flg);CHKERRQ(ierr);
2543*82b1193eSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
2544*82b1193eSBarry Smith 
2545*82b1193eSBarry Smith   /* if a->j are the same */
2546*82b1193eSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(int),flg);CHKERRQ(ierr);
2547*82b1193eSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
2548*82b1193eSBarry Smith 
2549*82b1193eSBarry Smith   /* if a->a are the same */
2550*82b1193eSBarry Smith   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(Scalar),flg);CHKERRQ(ierr);
2551*82b1193eSBarry Smith 
2552*82b1193eSBarry Smith   PetscFunctionReturn(0);
2553*82b1193eSBarry Smith 
2554*82b1193eSBarry Smith }
2555*82b1193eSBarry Smith 
2556*82b1193eSBarry Smith #undef __FUNC__
2557*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatCreateSeqAIJWithArrays"></a>*/"MatCreateSeqAIJWithArrays"
2558*82b1193eSBarry Smith /*@C
2559*82b1193eSBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
2560*82b1193eSBarry Smith               provided by the user.
2561*82b1193eSBarry Smith 
2562*82b1193eSBarry Smith       Coolective on MPI_Comm
2563*82b1193eSBarry Smith 
2564*82b1193eSBarry Smith    Input Parameters:
2565*82b1193eSBarry Smith +   comm - must be an MPI communicator of size 1
2566*82b1193eSBarry Smith .   m - number of rows
2567*82b1193eSBarry Smith .   n - number of columns
2568*82b1193eSBarry Smith .   i - row indices
2569*82b1193eSBarry Smith .   j - column indices
2570*82b1193eSBarry Smith -   a - matrix values
2571*82b1193eSBarry Smith 
2572*82b1193eSBarry Smith    Output Parameter:
2573*82b1193eSBarry Smith .   mat - the matrix
2574*82b1193eSBarry Smith 
2575*82b1193eSBarry Smith    Level: intermediate
2576*82b1193eSBarry Smith 
2577*82b1193eSBarry Smith    Notes:
2578*82b1193eSBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
2579*82b1193eSBarry Smith     once the matrix is destroyed
2580*82b1193eSBarry Smith 
2581*82b1193eSBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
2582*82b1193eSBarry Smith 
2583*82b1193eSBarry Smith        The i and j indices can be either 0- or 1 based
2584*82b1193eSBarry Smith 
2585*82b1193eSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ()
2586*82b1193eSBarry Smith 
2587*82b1193eSBarry Smith @*/
2588*82b1193eSBarry Smith int MatCreateSeqAIJWithArrays(MPI_Comm comm,int m,int n,int* i,int*j,Scalar *a,Mat *mat)
2589*82b1193eSBarry Smith {
2590*82b1193eSBarry Smith   int        ierr,ii;
2591*82b1193eSBarry Smith   Mat_SeqAIJ *aij;
2592*82b1193eSBarry Smith 
2593*82b1193eSBarry Smith   PetscFunctionBegin;
2594*82b1193eSBarry Smith   ierr = MatCreateSeqAIJ(comm,m,n,0,0,mat);CHKERRQ(ierr);
2595*82b1193eSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
2596*82b1193eSBarry Smith   ierr = PetscFree(aij->a);CHKERRQ(ierr);
2597*82b1193eSBarry Smith 
2598*82b1193eSBarry Smith   if (i[0] == 1) {
2599*82b1193eSBarry Smith     aij->indexshift = -1;
2600*82b1193eSBarry Smith   } else if (i[0]) {
2601*82b1193eSBarry Smith     SETERRQ(1,1,"i (row indices) do not start with 0 or 1");
2602*82b1193eSBarry Smith   }
2603*82b1193eSBarry Smith   aij->i = i;
2604*82b1193eSBarry Smith   aij->j = j;
2605*82b1193eSBarry Smith   aij->a = a;
2606*82b1193eSBarry Smith   aij->singlemalloc = PETSC_FALSE;
2607*82b1193eSBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
2608*82b1193eSBarry Smith   aij->freedata     = PETSC_FALSE;
2609*82b1193eSBarry Smith 
2610*82b1193eSBarry Smith   for (ii=0; ii<m; ii++) {
2611*82b1193eSBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
2612*82b1193eSBarry Smith #if defined(PETSC_BOPT_g)
2613*82b1193eSBarry Smith     if (i[ii+1] - i[i] < 0) SETERRQ2(1,1,"Negative row length in i (row indices) row = %d length = %d",ii,i[ii+1] - i[ii]);
2614*82b1193eSBarry Smith #endif
2615*82b1193eSBarry Smith   }
2616*82b1193eSBarry Smith #if defined(PETSC_BOPT_g)
2617*82b1193eSBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
2618*82b1193eSBarry Smith     if (j[ii] < -aij->indexshift) SETERRQ2(1,1,"Negative column index at location = %d index = %d",ii,j[ii]);
2619*82b1193eSBarry Smith     if (j[ii] > n - 1 -aij->indexshift) SETERRQ2(1,1,"Column index to large at location = %d index = %d",ii,j[ii]);
2620*82b1193eSBarry Smith   }
2621*82b1193eSBarry Smith #endif
2622*82b1193eSBarry Smith 
2623*82b1193eSBarry Smith   /* changes indices to start at 0 */
2624*82b1193eSBarry Smith   if (i[0]) {
2625*82b1193eSBarry Smith     aij->indexshift = 0;
2626*82b1193eSBarry Smith     for (ii=0; ii<m; ii++) {
2627*82b1193eSBarry Smith       i[ii]--;
2628*82b1193eSBarry Smith     }
2629*82b1193eSBarry Smith     for (ii=0; ii<i[m]; ii++) {
2630*82b1193eSBarry Smith       j[ii]--;
2631*82b1193eSBarry Smith     }
2632*82b1193eSBarry Smith   }
2633*82b1193eSBarry Smith 
2634*82b1193eSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2635*82b1193eSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2636*82b1193eSBarry Smith   PetscFunctionReturn(0);
2637*82b1193eSBarry Smith }
2638*82b1193eSBarry Smith 
2639*82b1193eSBarry Smith 
2640*82b1193eSBarry Smith 
2641