xref: /petsc/src/mat/interface/matrix.c (revision 6d88219ba02cca0bddb8679d419bc2ba9acb6a32)
1 /*$Id: matrix.c,v 1.414 2001/09/28 18:57:28 balay Exp $*/
2 
3 /*
4    This is where the abstract matrix operations are defined
5 */
6 
7 #include "src/mat/matimpl.h"        /*I "petscmat.h" I*/
8 #include "src/vec/vecimpl.h"
9 
10 #undef __FUNCT__
11 #define __FUNCT__ "MatGetRow"
12 /*@C
13    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
14    for each row that you get to ensure that your application does
15    not bleed memory.
16 
17    Not Collective
18 
19    Input Parameters:
20 +  mat - the matrix
21 -  row - the row to get
22 
23    Output Parameters:
24 +  ncols -  the number of nonzeros in the row
25 .  cols - if not NULL, the column numbers
26 -  vals - if not NULL, the values
27 
28    Notes:
29    This routine is provided for people who need to have direct access
30    to the structure of a matrix.  We hope that we provide enough
31    high-level matrix routines that few users will need it.
32 
33    MatGetRow() always returns 0-based column indices, regardless of
34    whether the internal representation is 0-based (default) or 1-based.
35 
36    For better efficiency, set cols and/or vals to PETSC_NULL if you do
37    not wish to extract these quantities.
38 
39    The user can only examine the values extracted with MatGetRow();
40    the values cannot be altered.  To change the matrix entries, one
41    must use MatSetValues().
42 
43    You can only have one call to MatGetRow() outstanding for a particular
44    matrix at a time, per processor. MatGetRow() can only obtained rows
45    associated with the given processor, it cannot get rows from the
46    other processors; for that we suggest using MatGetSubMatrices(), then
47    MatGetRow() on the submatrix. The row indix passed to MatGetRows()
48    is in the global number of rows.
49 
50    Fortran Notes:
51    The calling sequence from Fortran is
52 .vb
53    MatGetRow(matrix,row,ncols,cols,values,ierr)
54          Mat     matrix (input)
55          integer row    (input)
56          integer ncols  (output)
57          integer cols(maxcols) (output)
58          double precision (or double complex) values(maxcols) output
59 .ve
60    where maxcols >= maximum nonzeros in any row of the matrix.
61 
62    Caution:
63    Do not try to change the contents of the output arrays (cols and vals).
64    In some cases, this may corrupt the matrix.
65 
66    Level: advanced
67 
68    Concepts: matrices^row access
69 
70 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubmatrices(), MatGetDiagonal()
71 @*/
72 int MatGetRow(Mat mat,int row,int *ncols,int **cols,PetscScalar **vals)
73 {
74   int   ierr;
75 
76   PetscFunctionBegin;
77   PetscValidHeaderSpecific(mat,MAT_COOKIE);
78   PetscValidIntPointer(ncols);
79   PetscValidType(mat);
80   MatPreallocated(mat);
81   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
82   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
83   if (!mat->ops->getrow) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
84   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
85   ierr = (*mat->ops->getrow)(mat,row,ncols,cols,vals);CHKERRQ(ierr);
86   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
87   PetscFunctionReturn(0);
88 }
89 
90 #undef __FUNCT__
91 #define __FUNCT__ "MatRestoreRow"
92 /*@C
93    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
94 
95    Not Collective
96 
97    Input Parameters:
98 +  mat - the matrix
99 .  row - the row to get
100 .  ncols, cols - the number of nonzeros and their columns
101 -  vals - if nonzero the column values
102 
103    Notes:
104    This routine should be called after you have finished examining the entries.
105 
106    Fortran Notes:
107    The calling sequence from Fortran is
108 .vb
109    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
110       Mat     matrix (input)
111       integer row    (input)
112       integer ncols  (output)
113       integer cols(maxcols) (output)
114       double precision (or double complex) values(maxcols) output
115 .ve
116    Where maxcols >= maximum nonzeros in any row of the matrix.
117 
118    In Fortran MatRestoreRow() MUST be called after MatGetRow()
119    before another call to MatGetRow() can be made.
120 
121    Level: advanced
122 
123 .seealso:  MatGetRow()
124 @*/
125 int MatRestoreRow(Mat mat,int row,int *ncols,int **cols,PetscScalar **vals)
126 {
127   int ierr;
128 
129   PetscFunctionBegin;
130   PetscValidHeaderSpecific(mat,MAT_COOKIE);
131   PetscValidIntPointer(ncols);
132   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
133   if (!mat->ops->restorerow) PetscFunctionReturn(0);
134   ierr = (*mat->ops->restorerow)(mat,row,ncols,cols,vals);CHKERRQ(ierr);
135   PetscFunctionReturn(0);
136 }
137 
138 #undef __FUNCT__
139 #define __FUNCT__ "MatView"
140 /*@C
141    MatView - Visualizes a matrix object.
142 
143    Collective on Mat
144 
145    Input Parameters:
146 +  mat - the matrix
147 -  ptr - visualization context
148 
149   Notes:
150   The available visualization contexts include
151 +    PETSC_VIEWER_STDOUT_SELF - standard output (default)
152 .    PETSC_VIEWER_STDOUT_WORLD - synchronized standard
153         output where only the first processor opens
154         the file.  All other processors send their
155         data to the first processor to print.
156 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
157 
158    The user can open alternative visualization contexts with
159 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
160 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
161          specified file; corresponding input uses MatLoad()
162 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
163          an X window display
164 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
165          Currently only the sequential dense and AIJ
166          matrix types support the Socket viewer.
167 
168    The user can call PetscViewerSetFormat() to specify the output
169    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
170    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
171 +    PETSC_VIEWER_ASCII_DEFAULT - default, prints matrix contents
172 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
173 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
174 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
175          format common among all matrix types
176 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
177          format (which is in many cases the same as the default)
178 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
179          size and structure (not the matrix entries)
180 -    PETSC_VIEWER_ASCII_INFO_LONG - prints more detailed information about
181          the matrix structure
182 
183    Level: beginner
184 
185    Concepts: matrices^viewing
186    Concepts: matrices^plotting
187    Concepts: matrices^printing
188 
189 .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
190           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
191 @*/
192 int MatView(Mat mat,PetscViewer viewer)
193 {
194   int               ierr,rows,cols;
195   PetscTruth        isascii;
196   char              *cstr;
197   PetscViewerFormat format;
198 
199   PetscFunctionBegin;
200   PetscValidHeaderSpecific(mat,MAT_COOKIE);
201   PetscValidType(mat);
202   MatPreallocated(mat);
203   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(mat->comm);
204   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE);
205   PetscCheckSameComm(mat,viewer);
206   if (!mat->assembled) SETERRQ(1,"Must call MatAssemblyBegin/End() before viewing matrix");
207 
208   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
209   if (isascii) {
210     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
211     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_LONG) {
212       if (mat->prefix) {
213         ierr = PetscViewerASCIIPrintf(viewer,"Matrix Object:(%s)\n",mat->prefix);CHKERRQ(ierr);
214       } else {
215         ierr = PetscViewerASCIIPrintf(viewer,"Matrix Object:\n");CHKERRQ(ierr);
216       }
217       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
218       ierr = MatGetType(mat,&cstr);CHKERRQ(ierr);
219       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
220       ierr = PetscViewerASCIIPrintf(viewer,"type=%s, rows=%d, cols=%d\n",cstr,rows,cols);CHKERRQ(ierr);
221       if (mat->ops->getinfo) {
222         MatInfo info;
223         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
224         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%d, allocated nonzeros=%d\n",
225                           (int)info.nz_used,(int)info.nz_allocated);CHKERRQ(ierr);
226       }
227     }
228   }
229   if (mat->ops->view) {
230     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
231     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
232     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
233   } else if (!isascii) {
234     SETERRQ1(1,"Viewer type %s not supported",((PetscObject)viewer)->type_name);
235   }
236   if (isascii) {
237     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
238     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_LONG) {
239       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
240     }
241   }
242   PetscFunctionReturn(0);
243 }
244 
245 #undef __FUNCT__
246 #define __FUNCT__ "MatScaleSystem"
247 /*@C
248    MatScaleSystem - Scale a vector solution and right hand side to
249    match the scaling of a scaled matrix.
250 
251    Collective on Mat
252 
253    Input Parameter:
254 +  mat - the matrix
255 .  x - solution vector (or PETSC_NULL)
256 +  b - right hand side vector (or PETSC_NULL)
257 
258 
259    Notes:
260    For AIJ, BAIJ, and BDiag matrix formats, the matrices are not
261    internally scaled, so this does nothing. For MPIROWBS it
262    permutes and diagonally scales.
263 
264    The SLES methods automatically call this routine when required
265    (via PCPreSolve()) so it is rarely used directly.
266 
267    Level: Developer
268 
269    Concepts: matrices^scaling
270 
271 .seealso: MatUseScaledForm(), MatUnScaleSystem()
272 @*/
273 int MatScaleSystem(Mat mat,Vec x,Vec b)
274 {
275   int ierr;
276 
277   PetscFunctionBegin;
278   PetscValidHeaderSpecific(mat,MAT_COOKIE);
279   PetscValidType(mat);
280   MatPreallocated(mat);
281   if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE);PetscCheckSameComm(mat,x);}
282   if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE);PetscCheckSameComm(mat,b);}
283 
284   if (mat->ops->scalesystem) {
285     ierr = (*mat->ops->scalesystem)(mat,x,b);CHKERRQ(ierr);
286   }
287   PetscFunctionReturn(0);
288 }
289 
290 #undef __FUNCT__
291 #define __FUNCT__ "MatUnScaleSystem"
292 /*@C
293    MatUnScaleSystem - Unscales a vector solution and right hand side to
294    match the original scaling of a scaled matrix.
295 
296    Collective on Mat
297 
298    Input Parameter:
299 +  mat - the matrix
300 .  x - solution vector (or PETSC_NULL)
301 +  b - right hand side vector (or PETSC_NULL)
302 
303 
304    Notes:
305    For AIJ, BAIJ, and BDiag matrix formats, the matrices are not
306    internally scaled, so this does nothing. For MPIROWBS it
307    permutes and diagonally scales.
308 
309    The SLES methods automatically call this routine when required
310    (via PCPreSolve()) so it is rarely used directly.
311 
312    Level: Developer
313 
314 .seealso: MatUseScaledForm(), MatScaleSystem()
315 @*/
316 int MatUnScaleSystem(Mat mat,Vec x,Vec b)
317 {
318   int ierr;
319 
320   PetscFunctionBegin;
321   PetscValidHeaderSpecific(mat,MAT_COOKIE);
322   PetscValidType(mat);
323   MatPreallocated(mat);
324   if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE);PetscCheckSameComm(mat,x);}
325   if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE);PetscCheckSameComm(mat,b);}
326   if (mat->ops->unscalesystem) {
327     ierr = (*mat->ops->unscalesystem)(mat,x,b);CHKERRQ(ierr);
328   }
329   PetscFunctionReturn(0);
330 }
331 
332 #undef __FUNCT__
333 #define __FUNCT__ "MatUseScaledForm"
334 /*@C
335    MatUseScaledForm - For matrix storage formats that scale the
336    matrix (for example MPIRowBS matrices are diagonally scaled on
337    assembly) indicates matrix operations (MatMult() etc) are
338    applied using the scaled matrix.
339 
340    Collective on Mat
341 
342    Input Parameter:
343 +  mat - the matrix
344 -  scaled - PETSC_TRUE for applying the scaled, PETSC_FALSE for
345             applying the original matrix
346 
347    Notes:
348    For scaled matrix formats, applying the original, unscaled matrix
349    will be slightly more expensive
350 
351    Level: Developer
352 
353 .seealso: MatScaleSystem(), MatUnScaleSystem()
354 @*/
355 int MatUseScaledForm(Mat mat,PetscTruth scaled)
356 {
357   int ierr;
358 
359   PetscFunctionBegin;
360   PetscValidHeaderSpecific(mat,MAT_COOKIE);
361   PetscValidType(mat);
362   MatPreallocated(mat);
363   if (mat->ops->usescaledform) {
364     ierr = (*mat->ops->usescaledform)(mat,scaled);CHKERRQ(ierr);
365   }
366   PetscFunctionReturn(0);
367 }
368 
369 #undef __FUNCT__
370 #define __FUNCT__ "MatDestroy"
371 /*@C
372    MatDestroy - Frees space taken by a matrix.
373 
374    Collective on Mat
375 
376    Input Parameter:
377 .  A - the matrix
378 
379    Level: beginner
380 
381 @*/
382 int MatDestroy(Mat A)
383 {
384   int ierr;
385 
386   PetscFunctionBegin;
387   PetscValidHeaderSpecific(A,MAT_COOKIE);
388   PetscValidType(A);
389   MatPreallocated(A);
390   if (--A->refct > 0) PetscFunctionReturn(0);
391 
392   /* if memory was published with AMS then destroy it */
393   ierr = PetscObjectDepublish(A);CHKERRQ(ierr);
394   if (A->mapping) {
395     ierr = ISLocalToGlobalMappingDestroy(A->mapping);CHKERRQ(ierr);
396   }
397   if (A->bmapping) {
398     ierr = ISLocalToGlobalMappingDestroy(A->bmapping);CHKERRQ(ierr);
399   }
400   if (A->rmap) {
401     ierr = PetscMapDestroy(A->rmap);CHKERRQ(ierr);
402   }
403   if (A->cmap) {
404     ierr = PetscMapDestroy(A->cmap);CHKERRQ(ierr);
405   }
406 
407   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
408   PetscLogObjectDestroy(A);
409   PetscHeaderDestroy(A);
410   PetscFunctionReturn(0);
411 }
412 
413 #undef __FUNCT__
414 #define __FUNCT__ "MatValid"
415 /*@
416    MatValid - Checks whether a matrix object is valid.
417 
418    Collective on Mat
419 
420    Input Parameter:
421 .  m - the matrix to check
422 
423    Output Parameter:
424    flg - flag indicating matrix status, either
425    PETSC_TRUE if matrix is valid, or PETSC_FALSE otherwise.
426 
427    Level: developer
428 
429    Concepts: matrices^validity
430 @*/
431 int MatValid(Mat m,PetscTruth *flg)
432 {
433   PetscFunctionBegin;
434   PetscValidIntPointer(flg);
435   if (!m)                           *flg = PETSC_FALSE;
436   else if (m->cookie != MAT_COOKIE) *flg = PETSC_FALSE;
437   else                              *flg = PETSC_TRUE;
438   PetscFunctionReturn(0);
439 }
440 
441 #undef __FUNCT__
442 #define __FUNCT__ "MatSetValues"
443 /*@
444    MatSetValues - Inserts or adds a block of values into a matrix.
445    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
446    MUST be called after all calls to MatSetValues() have been completed.
447 
448    Not Collective
449 
450    Input Parameters:
451 +  mat - the matrix
452 .  v - a logically two-dimensional array of values
453 .  m, idxm - the number of rows and their global indices
454 .  n, idxn - the number of columns and their global indices
455 -  addv - either ADD_VALUES or INSERT_VALUES, where
456    ADD_VALUES adds values to any existing entries, and
457    INSERT_VALUES replaces existing entries with new values
458 
459    Notes:
460    By default the values, v, are row-oriented and unsorted.
461    See MatSetOption() for other options.
462 
463    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
464    options cannot be mixed without intervening calls to the assembly
465    routines.
466 
467    MatSetValues() uses 0-based row and column numbers in Fortran
468    as well as in C.
469 
470    Negative indices may be passed in idxm and idxn, these rows and columns are
471    simply ignored. This allows easily inserting element stiffness matrices
472    with homogeneous Dirchlet boundary conditions that you don't want represented
473    in the matrix.
474 
475    Efficiency Alert:
476    The routine MatSetValuesBlocked() may offer much better efficiency
477    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
478 
479    Level: beginner
480 
481    Concepts: matrices^putting entries in
482 
483 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
484 @*/
485 int MatSetValues(Mat mat,int m,int *idxm,int n,int *idxn,PetscScalar *v,InsertMode addv)
486 {
487   int ierr;
488 
489   PetscFunctionBegin;
490   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
491   PetscValidHeaderSpecific(mat,MAT_COOKIE);
492   PetscValidType(mat);
493   MatPreallocated(mat);
494   PetscValidIntPointer(idxm);
495   PetscValidIntPointer(idxn);
496   PetscValidScalarPointer(v);
497   if (mat->insertmode == NOT_SET_VALUES) {
498     mat->insertmode = addv;
499   }
500 #if defined(PETSC_USE_BOPT_g)
501   else if (mat->insertmode != addv) {
502     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
503   }
504   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
505 #endif
506 
507   if (mat->assembled) {
508     mat->was_assembled = PETSC_TRUE;
509     mat->assembled     = PETSC_FALSE;
510   }
511   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
512   if (!mat->ops->setvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
513   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
514   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
515   PetscFunctionReturn(0);
516 }
517 
518 #undef __FUNCT__
519 #define __FUNCT__ "MatSetValuesStencil"
520 /*@C
521    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
522      Using structured grid indexing
523 
524    Not Collective
525 
526    Input Parameters:
527 +  mat - the matrix
528 .  v - a logically two-dimensional array of values
529 .  m - number of rows being entered
530 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
531 .  n - number of columns being entered
532 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
533 -  addv - either ADD_VALUES or INSERT_VALUES, where
534    ADD_VALUES adds values to any existing entries, and
535    INSERT_VALUES replaces existing entries with new values
536 
537    Notes:
538    By default the values, v, are row-oriented and unsorted.
539    See MatSetOption() for other options.
540 
541    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
542    options cannot be mixed without intervening calls to the assembly
543    routines.
544 
545    The grid coordinates are across the entire grid, not just the local portion
546 
547    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
548    as well as in C.
549 
550    In order to use this routine you must either obtain the matrix with DAGetMatrix()
551    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
552 
553    In Fortran idxm and idxn should be declared as
554 $     MatStencil idxm(4,m),idxn(4,n)
555    and the values inserted using
556 $    idxm(MatStencil_i,1) = i
557 $    idxm(MatStencil_j,1) = j
558 $    idxm(MatStencil_k,1) = k
559 $    idxm(MatStencil_c,1) = c
560    etc
561 
562    Negative indices may be passed in idxm and idxn, these rows and columns are
563    simply ignored. This allows easily inserting element stiffness matrices
564    with homogeneous Dirchlet boundary conditions that you don't want represented
565    in the matrix.
566 
567    Inspired by the structured grid interface to the HYPRE package
568    (http://www.llnl.gov/CASC/hypre)
569 
570    Efficiency Alert:
571    The routine MatSetValuesBlockedStencil() may offer much better efficiency
572    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
573 
574    Level: beginner
575 
576    Concepts: matrices^putting entries in
577 
578 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
579           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DAGetMatrix()
580 @*/
581 int MatSetValuesStencil(Mat mat,int m,MatStencil *idxm,int n,MatStencil *idxn,PetscScalar *v,InsertMode addv)
582 {
583   int j,i,ierr,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
584   int *starts = mat->stencil.starts,*dxm = (int*)idxm,*dxn = (int*)idxn,sdim = dim - (1 - (int)mat->stencil.noc);
585 
586   PetscFunctionBegin;
587   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
588   PetscValidHeaderSpecific(mat,MAT_COOKIE);
589   PetscValidType(mat);
590   PetscValidIntPointer(idxm);
591   PetscValidIntPointer(idxn);
592   PetscValidScalarPointer(v);
593 
594   if (m > 128) SETERRQ1(1,"Can only set 128 rows at a time; trying to set %d",m);
595   if (n > 128) SETERRQ1(1,"Can only set 256 columns at a time; trying to set %d",n);
596 
597   for (i=0; i<m; i++) {
598     for (j=0; j<3-sdim; j++) dxm++;
599     tmp = *dxm++ - starts[0];
600     for (j=0; j<dim-1; j++) {
601       tmp = tmp*dims[j] + *dxm++ - starts[j+1];
602     }
603     if (mat->stencil.noc) dxm++;
604     jdxm[i] = tmp;
605   }
606   for (i=0; i<n; i++) {
607     for (j=0; j<3-sdim; j++) dxn++;
608     tmp = *dxn++ - starts[0];
609     for (j=0; j<dim-1; j++) {
610       tmp = tmp*dims[j] + *dxn++ - starts[j+1];
611     }
612     if (mat->stencil.noc) dxn++;
613     jdxn[i] = tmp;
614   }
615   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
616   PetscFunctionReturn(0);
617 }
618 
619 #undef __FUNCT__
620 #define __FUNCT__ "MatSetStencil"
621 /*@
622    MatSetStencil - Sets the grid information for setting values into a matrix via
623         MatSetStencil()
624 
625    Not Collective
626 
627    Input Parameters:
628 +  mat - the matrix
629 .  dim - dimension of the grid 1,2, or 3
630 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
631 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
632 -  dof - number of degrees of freedom per node
633 
634 
635    Inspired by the structured grid interface to the HYPRE package
636    (www.llnl.gov/CASC/hyper)
637 
638    Level: beginner
639 
640    Concepts: matrices^putting entries in
641 
642 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
643           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
644 @*/
645 int MatSetStencil(Mat mat,int dim,int *dims,int *starts,int dof)
646 {
647   int i;
648 
649   PetscFunctionBegin;
650   PetscValidHeaderSpecific(mat,MAT_COOKIE);
651   PetscValidIntPointer(dims);
652   PetscValidIntPointer(starts);
653 
654   mat->stencil.dim = dim + (dof > 1);
655   for (i=0; i<dim; i++) {
656     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
657     mat->stencil.starts[i] = starts[dim-i-1];
658   }
659   mat->stencil.dims[dim]   = dof;
660   mat->stencil.starts[dim] = 0;
661   mat->stencil.noc         = (PetscTruth)(dof == 1);
662   PetscFunctionReturn(0);
663 }
664 
665 #undef __FUNCT__
666 #define __FUNCT__ "MatSetValuesBlocked"
667 /*@
668    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
669 
670    Not Collective
671 
672    Input Parameters:
673 +  mat - the matrix
674 .  v - a logically two-dimensional array of values
675 .  m, idxm - the number of block rows and their global block indices
676 .  n, idxn - the number of block columns and their global block indices
677 -  addv - either ADD_VALUES or INSERT_VALUES, where
678    ADD_VALUES adds values to any existing entries, and
679    INSERT_VALUES replaces existing entries with new values
680 
681    Notes:
682    By default the values, v, are row-oriented and unsorted. So the layout of
683    v is the same as for MatSetValues(). See MatSetOption() for other options.
684 
685    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
686    options cannot be mixed without intervening calls to the assembly
687    routines.
688 
689    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
690    as well as in C.
691 
692    Negative indices may be passed in idxm and idxn, these rows and columns are
693    simply ignored. This allows easily inserting element stiffness matrices
694    with homogeneous Dirchlet boundary conditions that you don't want represented
695    in the matrix.
696 
697    Each time an entry is set within a sparse matrix via MatSetValues(),
698    internal searching must be done to determine where to place the the
699    data in the matrix storage space.  By instead inserting blocks of
700    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
701    reduced.
702 
703    Restrictions:
704    MatSetValuesBlocked() is currently supported only for the block AIJ
705    matrix format (MATSEQBAIJ and MATMPIBAIJ, which are created via
706    MatCreateSeqBAIJ() and MatCreateMPIBAIJ()).
707 
708    Level: intermediate
709 
710    Concepts: matrices^putting entries in blocked
711 
712 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
713 @*/
714 int MatSetValuesBlocked(Mat mat,int m,int *idxm,int n,int *idxn,PetscScalar *v,InsertMode addv)
715 {
716   int ierr;
717 
718   PetscFunctionBegin;
719   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
720   PetscValidHeaderSpecific(mat,MAT_COOKIE);
721   PetscValidType(mat);
722   MatPreallocated(mat);
723   PetscValidIntPointer(idxm);
724   PetscValidIntPointer(idxn);
725   PetscValidScalarPointer(v);
726   if (mat->insertmode == NOT_SET_VALUES) {
727     mat->insertmode = addv;
728   }
729 #if defined(PETSC_USE_BOPT_g)
730   else if (mat->insertmode != addv) {
731     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
732   }
733   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
734 #endif
735 
736   if (mat->assembled) {
737     mat->was_assembled = PETSC_TRUE;
738     mat->assembled     = PETSC_FALSE;
739   }
740   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
741   if (!mat->ops->setvaluesblocked) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
742   ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
743   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
744   PetscFunctionReturn(0);
745 }
746 
747 /*MC
748    MatSetValue - Set a single entry into a matrix.
749 
750    Synopsis:
751    int MatSetValue(Mat m,int row,int col,PetscScalar value,InsertMode mode);
752 
753    Not collective
754 
755    Input Parameters:
756 +  m - the matrix
757 .  row - the row location of the entry
758 .  col - the column location of the entry
759 .  value - the value to insert
760 -  mode - either INSERT_VALUES or ADD_VALUES
761 
762    Notes:
763    For efficiency one should use MatSetValues() and set several or many
764    values simultaneously if possible.
765 
766    Note that VecSetValue() does NOT return an error code (since this
767    is checked internally).
768 
769    Level: beginner
770 
771 .seealso: MatSetValues()
772 M*/
773 
774 #undef __FUNCT__
775 #define __FUNCT__ "MatGetValues"
776 /*@
777    MatGetValues - Gets a block of values from a matrix.
778 
779    Not Collective; currently only returns a local block
780 
781    Input Parameters:
782 +  mat - the matrix
783 .  v - a logically two-dimensional array for storing the values
784 .  m, idxm - the number of rows and their global indices
785 -  n, idxn - the number of columns and their global indices
786 
787    Notes:
788    The user must allocate space (m*n PetscScalars) for the values, v.
789    The values, v, are then returned in a row-oriented format,
790    analogous to that used by default in MatSetValues().
791 
792    MatGetValues() uses 0-based row and column numbers in
793    Fortran as well as in C.
794 
795    MatGetValues() requires that the matrix has been assembled
796    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
797    MatSetValues() and MatGetValues() CANNOT be made in succession
798    without intermediate matrix assembly.
799 
800    Level: advanced
801 
802    Concepts: matrices^accessing values
803 
804 .seealso: MatGetRow(), MatGetSubmatrices(), MatSetValues()
805 @*/
806 int MatGetValues(Mat mat,int m,int *idxm,int n,int *idxn,PetscScalar *v)
807 {
808   int ierr;
809 
810   PetscFunctionBegin;
811   PetscValidHeaderSpecific(mat,MAT_COOKIE);
812   PetscValidType(mat);
813   MatPreallocated(mat);
814   PetscValidIntPointer(idxm);
815   PetscValidIntPointer(idxn);
816   PetscValidScalarPointer(v);
817   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
818   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
819   if (!mat->ops->getvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
820 
821   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
822   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
823   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
824   PetscFunctionReturn(0);
825 }
826 
827 #undef __FUNCT__
828 #define __FUNCT__ "MatSetLocalToGlobalMapping"
829 /*@
830    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
831    the routine MatSetValuesLocal() to allow users to insert matrix entries
832    using a local (per-processor) numbering.
833 
834    Not Collective
835 
836    Input Parameters:
837 +  x - the matrix
838 -  mapping - mapping created with ISLocalToGlobalMappingCreate()
839              or ISLocalToGlobalMappingCreateIS()
840 
841    Level: intermediate
842 
843    Concepts: matrices^local to global mapping
844    Concepts: local to global mapping^for matrices
845 
846 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
847 @*/
848 int MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping mapping)
849 {
850   int ierr;
851   PetscFunctionBegin;
852   PetscValidHeaderSpecific(x,MAT_COOKIE);
853   PetscValidType(x);
854   MatPreallocated(x);
855   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE);
856   if (x->mapping) {
857     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
858   }
859 
860   if (x->ops->setlocaltoglobalmapping) {
861     ierr = (*x->ops->setlocaltoglobalmapping)(x,mapping);CHKERRQ(ierr);
862   } else {
863     x->mapping = mapping;
864     ierr = PetscObjectReference((PetscObject)mapping);CHKERRQ(ierr);
865   }
866   PetscFunctionReturn(0);
867 }
868 
869 #undef __FUNCT__
870 #define __FUNCT__ "MatSetLocalToGlobalMappingBlock"
871 /*@
872    MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
873    by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
874    entries using a local (per-processor) numbering.
875 
876    Not Collective
877 
878    Input Parameters:
879 +  x - the matrix
880 -  mapping - mapping created with ISLocalToGlobalMappingCreate() or
881              ISLocalToGlobalMappingCreateIS()
882 
883    Level: intermediate
884 
885    Concepts: matrices^local to global mapping blocked
886    Concepts: local to global mapping^for matrices, blocked
887 
888 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
889            MatSetValuesBlocked(), MatSetValuesLocal()
890 @*/
891 int MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping mapping)
892 {
893   int ierr;
894   PetscFunctionBegin;
895   PetscValidHeaderSpecific(x,MAT_COOKIE);
896   PetscValidType(x);
897   MatPreallocated(x);
898   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE);
899   if (x->bmapping) {
900     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
901   }
902 
903   x->bmapping = mapping;
904   ierr = PetscObjectReference((PetscObject)mapping);CHKERRQ(ierr);
905   PetscFunctionReturn(0);
906 }
907 
908 #undef __FUNCT__
909 #define __FUNCT__ "MatSetValuesLocal"
910 /*@
911    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
912    using a local ordering of the nodes.
913 
914    Not Collective
915 
916    Input Parameters:
917 +  x - the matrix
918 .  nrow, irow - number of rows and their local indices
919 .  ncol, icol - number of columns and their local indices
920 .  y -  a logically two-dimensional array of values
921 -  addv - either INSERT_VALUES or ADD_VALUES, where
922    ADD_VALUES adds values to any existing entries, and
923    INSERT_VALUES replaces existing entries with new values
924 
925    Notes:
926    Before calling MatSetValuesLocal(), the user must first set the
927    local-to-global mapping by calling MatSetLocalToGlobalMapping().
928 
929    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
930    options cannot be mixed without intervening calls to the assembly
931    routines.
932 
933    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
934    MUST be called after all calls to MatSetValuesLocal() have been completed.
935 
936    Level: intermediate
937 
938    Concepts: matrices^putting entries in with local numbering
939 
940 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
941            MatSetValueLocal()
942 @*/
943 int MatSetValuesLocal(Mat mat,int nrow,int *irow,int ncol,int *icol,PetscScalar *y,InsertMode addv)
944 {
945   int ierr,irowm[2048],icolm[2048];
946 
947   PetscFunctionBegin;
948   PetscValidHeaderSpecific(mat,MAT_COOKIE);
949   PetscValidType(mat);
950   MatPreallocated(mat);
951   PetscValidIntPointer(irow);
952   PetscValidIntPointer(icol);
953   PetscValidScalarPointer(y);
954 
955   if (mat->insertmode == NOT_SET_VALUES) {
956     mat->insertmode = addv;
957   }
958 #if defined(PETSC_USE_BOPT_g)
959   else if (mat->insertmode != addv) {
960     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
961   }
962   if (!mat->ops->setvalueslocal && (nrow > 2048 || ncol > 2048)) {
963     SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %d %d",nrow,ncol);
964   }
965   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
966 #endif
967 
968   if (mat->assembled) {
969     mat->was_assembled = PETSC_TRUE;
970     mat->assembled     = PETSC_FALSE;
971   }
972   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
973   if (!mat->ops->setvalueslocal) {
974     ierr = ISLocalToGlobalMappingApply(mat->mapping,nrow,irow,irowm);CHKERRQ(ierr);
975     ierr = ISLocalToGlobalMappingApply(mat->mapping,ncol,icol,icolm);CHKERRQ(ierr);
976     ierr = (*mat->ops->setvalues)(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
977   } else {
978     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
979   }
980   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
981   PetscFunctionReturn(0);
982 }
983 
984 #undef __FUNCT__
985 #define __FUNCT__ "MatSetValuesBlockedLocal"
986 /*@
987    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
988    using a local ordering of the nodes a block at a time.
989 
990    Not Collective
991 
992    Input Parameters:
993 +  x - the matrix
994 .  nrow, irow - number of rows and their local indices
995 .  ncol, icol - number of columns and their local indices
996 .  y -  a logically two-dimensional array of values
997 -  addv - either INSERT_VALUES or ADD_VALUES, where
998    ADD_VALUES adds values to any existing entries, and
999    INSERT_VALUES replaces existing entries with new values
1000 
1001    Notes:
1002    Before calling MatSetValuesBlockedLocal(), the user must first set the
1003    local-to-global mapping by calling MatSetLocalToGlobalMappingBlock(),
1004    where the mapping MUST be set for matrix blocks, not for matrix elements.
1005 
1006    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
1007    options cannot be mixed without intervening calls to the assembly
1008    routines.
1009 
1010    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1011    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
1012 
1013    Level: intermediate
1014 
1015    Concepts: matrices^putting blocked values in with local numbering
1016 
1017 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
1018 @*/
1019 int MatSetValuesBlockedLocal(Mat mat,int nrow,int *irow,int ncol,int *icol,PetscScalar *y,InsertMode addv)
1020 {
1021   int ierr,irowm[2048],icolm[2048];
1022 
1023   PetscFunctionBegin;
1024   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1025   PetscValidType(mat);
1026   MatPreallocated(mat);
1027   PetscValidIntPointer(irow);
1028   PetscValidIntPointer(icol);
1029   PetscValidScalarPointer(y);
1030   if (mat->insertmode == NOT_SET_VALUES) {
1031     mat->insertmode = addv;
1032   }
1033 #if defined(PETSC_USE_BOPT_g)
1034   else if (mat->insertmode != addv) {
1035     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1036   }
1037   if (!mat->bmapping) {
1038     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with MatSetLocalToGlobalMappingBlock()");
1039   }
1040   if (nrow > 2048 || ncol > 2048) {
1041     SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %d %d",nrow,ncol);
1042   }
1043   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1044 #endif
1045 
1046   if (mat->assembled) {
1047     mat->was_assembled = PETSC_TRUE;
1048     mat->assembled     = PETSC_FALSE;
1049   }
1050   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1051   ierr = ISLocalToGlobalMappingApply(mat->bmapping,nrow,irow,irowm);CHKERRQ(ierr);
1052   ierr = ISLocalToGlobalMappingApply(mat->bmapping,ncol,icol,icolm);CHKERRQ(ierr);
1053   ierr = (*mat->ops->setvaluesblocked)(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
1054   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1055   PetscFunctionReturn(0);
1056 }
1057 
1058 /* --------------------------------------------------------*/
1059 #undef __FUNCT__
1060 #define __FUNCT__ "MatMult"
1061 /*@
1062    MatMult - Computes the matrix-vector product, y = Ax.
1063 
1064    Collective on Mat and Vec
1065 
1066    Input Parameters:
1067 +  mat - the matrix
1068 -  x   - the vector to be multilplied
1069 
1070    Output Parameters:
1071 .  y - the result
1072 
1073    Notes:
1074    The vectors x and y cannot be the same.  I.e., one cannot
1075    call MatMult(A,y,y).
1076 
1077    Level: beginner
1078 
1079    Concepts: matrix-vector product
1080 
1081 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
1082 @*/
1083 int MatMult(Mat mat,Vec x,Vec y)
1084 {
1085   int ierr;
1086 
1087   PetscFunctionBegin;
1088   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1089   PetscValidType(mat);
1090   MatPreallocated(mat);
1091   PetscValidHeaderSpecific(x,VEC_COOKIE);
1092   PetscValidHeaderSpecific(y,VEC_COOKIE);
1093 
1094   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1095   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1096   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1097   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1098   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
1099   if (mat->m != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %d %d",mat->m,y->n);
1100 
1101   if (mat->nullsp) {
1102     ierr = MatNullSpaceRemove(mat->nullsp,x,&x);CHKERRQ(ierr);
1103   }
1104 
1105   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
1106   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
1107   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
1108 
1109   if (mat->nullsp) {
1110     ierr = MatNullSpaceRemove(mat->nullsp,y,PETSC_NULL);CHKERRQ(ierr);
1111   }
1112   PetscFunctionReturn(0);
1113 }
1114 
1115 #undef __FUNCT__
1116 #define __FUNCT__ "MatMultTranspose"
1117 /*@
1118    MatMultTranspose - Computes matrix transpose times a vector.
1119 
1120    Collective on Mat and Vec
1121 
1122    Input Parameters:
1123 +  mat - the matrix
1124 -  x   - the vector to be multilplied
1125 
1126    Output Parameters:
1127 .  y - the result
1128 
1129    Notes:
1130    The vectors x and y cannot be the same.  I.e., one cannot
1131    call MatMultTranspose(A,y,y).
1132 
1133    Level: beginner
1134 
1135    Concepts: matrix vector product^transpose
1136 
1137 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd()
1138 @*/
1139 int MatMultTranspose(Mat mat,Vec x,Vec y)
1140 {
1141   int ierr;
1142 
1143   PetscFunctionBegin;
1144   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1145   PetscValidType(mat);
1146   MatPreallocated(mat);
1147   PetscValidHeaderSpecific(x,VEC_COOKIE);
1148   PetscValidHeaderSpecific(y,VEC_COOKIE);
1149 
1150   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1151   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1152   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1153   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
1154   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->N,y->N);
1155 
1156   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
1157   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
1158   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
1159   PetscFunctionReturn(0);
1160 }
1161 
1162 #undef __FUNCT__
1163 #define __FUNCT__ "MatMultAdd"
1164 /*@
1165     MatMultAdd -  Computes v3 = v2 + A * v1.
1166 
1167     Collective on Mat and Vec
1168 
1169     Input Parameters:
1170 +   mat - the matrix
1171 -   v1, v2 - the vectors
1172 
1173     Output Parameters:
1174 .   v3 - the result
1175 
1176     Notes:
1177     The vectors v1 and v3 cannot be the same.  I.e., one cannot
1178     call MatMultAdd(A,v1,v2,v1).
1179 
1180     Level: beginner
1181 
1182     Concepts: matrix vector product^addition
1183 
1184 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
1185 @*/
1186 int MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1187 {
1188   int ierr;
1189 
1190   PetscFunctionBegin;
1191   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1192   PetscValidType(mat);
1193   MatPreallocated(mat);
1194   PetscValidHeaderSpecific(v1,VEC_COOKIE);
1195   PetscValidHeaderSpecific(v2,VEC_COOKIE);
1196   PetscValidHeaderSpecific(v3,VEC_COOKIE);
1197 
1198   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1199   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1200   if (mat->N != v1->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %d %d",mat->N,v1->N);
1201   if (mat->M != v2->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %d %d",mat->M,v2->N);
1202   if (mat->M != v3->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %d %d",mat->M,v3->N);
1203   if (mat->m != v3->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %d %d",mat->m,v3->n);
1204   if (mat->m != v2->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %d %d",mat->m,v2->n);
1205   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1206 
1207   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1208   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
1209   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1210   PetscFunctionReturn(0);
1211 }
1212 
1213 #undef __FUNCT__
1214 #define __FUNCT__ "MatMultTransposeAdd"
1215 /*@
1216    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
1217 
1218    Collective on Mat and Vec
1219 
1220    Input Parameters:
1221 +  mat - the matrix
1222 -  v1, v2 - the vectors
1223 
1224    Output Parameters:
1225 .  v3 - the result
1226 
1227    Notes:
1228    The vectors v1 and v3 cannot be the same.  I.e., one cannot
1229    call MatMultTransposeAdd(A,v1,v2,v1).
1230 
1231    Level: beginner
1232 
1233    Concepts: matrix vector product^transpose and addition
1234 
1235 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
1236 @*/
1237 int MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1238 {
1239   int ierr;
1240 
1241   PetscFunctionBegin;
1242   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1243   PetscValidType(mat);
1244   MatPreallocated(mat);
1245   PetscValidHeaderSpecific(v1,VEC_COOKIE);
1246   PetscValidHeaderSpecific(v2,VEC_COOKIE);
1247   PetscValidHeaderSpecific(v3,VEC_COOKIE);
1248 
1249   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1250   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1251   if (!mat->ops->multtransposeadd) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1252   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1253   if (mat->M != v1->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %d %d",mat->M,v1->N);
1254   if (mat->N != v2->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %d %d",mat->N,v2->N);
1255   if (mat->N != v3->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %d %d",mat->N,v3->N);
1256 
1257   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1258   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
1259   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1260   PetscFunctionReturn(0);
1261 }
1262 
1263 #undef __FUNCT__
1264 #define __FUNCT__ "MatMultConstrained"
1265 /*@
1266    MatMultConstrained - The inner multiplication routine for a
1267    constrained matrix P^T A P.
1268 
1269    Collective on Mat and Vec
1270 
1271    Input Parameters:
1272 +  mat - the matrix
1273 -  x   - the vector to be multilplied
1274 
1275    Output Parameters:
1276 .  y - the result
1277 
1278    Notes:
1279    The vectors x and y cannot be the same.  I.e., one cannot
1280    call MatMult(A,y,y).
1281 
1282    Level: beginner
1283 
1284 .keywords: matrix, multiply, matrix-vector product, constraint
1285 .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1286 @*/
1287 int MatMultConstrained(Mat mat,Vec x,Vec y)
1288 {
1289   int ierr;
1290 
1291   PetscFunctionBegin;
1292   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1293   PetscValidHeaderSpecific(x,VEC_COOKIE);PetscValidHeaderSpecific(y,VEC_COOKIE);
1294   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1295   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1296   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1297   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1298   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
1299   if (mat->m != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %d %d",mat->m,y->n);
1300 
1301   MatLogEventBegin(MAT_MultConstrained,mat,x,y,0);
1302   ierr = (*mat->ops->multconstrained)(mat,x,y); CHKERRQ(ierr);
1303   MatLogEventEnd(MAT_MultConstrained,mat,x,y,0);
1304 
1305   PetscFunctionReturn(0);
1306 }
1307 /* ------------------------------------------------------------*/
1308 #undef __FUNCT__
1309 #define __FUNCT__ "MatGetInfo"
1310 /*@C
1311    MatGetInfo - Returns information about matrix storage (number of
1312    nonzeros, memory, etc.).
1313 
1314    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used
1315    as the flag
1316 
1317    Input Parameters:
1318 .  mat - the matrix
1319 
1320    Output Parameters:
1321 +  flag - flag indicating the type of parameters to be returned
1322    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
1323    MAT_GLOBAL_SUM - sum over all processors)
1324 -  info - matrix information context
1325 
1326    Notes:
1327    The MatInfo context contains a variety of matrix data, including
1328    number of nonzeros allocated and used, number of mallocs during
1329    matrix assembly, etc.  Additional information for factored matrices
1330    is provided (such as the fill ratio, number of mallocs during
1331    factorization, etc.).  Much of this info is printed to STDOUT
1332    when using the runtime options
1333 $       -log_info -mat_view_info
1334 
1335    Example for C/C++ Users:
1336    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
1337    data within the MatInfo context.  For example,
1338 .vb
1339       MatInfo info;
1340       Mat     A;
1341       double  mal, nz_a, nz_u;
1342 
1343       MatGetInfo(A,MAT_LOCAL,&info);
1344       mal  = info.mallocs;
1345       nz_a = info.nz_allocated;
1346 .ve
1347 
1348    Example for Fortran Users:
1349    Fortran users should declare info as a double precision
1350    array of dimension MAT_INFO_SIZE, and then extract the parameters
1351    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
1352    a complete list of parameter names.
1353 .vb
1354       double  precision info(MAT_INFO_SIZE)
1355       double  precision mal, nz_a
1356       Mat     A
1357       integer ierr
1358 
1359       call MatGetInfo(A,MAT_LOCAL,info,ierr)
1360       mal = info(MAT_INFO_MALLOCS)
1361       nz_a = info(MAT_INFO_NZ_ALLOCATED)
1362 .ve
1363 
1364     Level: intermediate
1365 
1366     Concepts: matrices^getting information on
1367 
1368 @*/
1369 int MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
1370 {
1371   int ierr;
1372 
1373   PetscFunctionBegin;
1374   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1375   PetscValidType(mat);
1376   MatPreallocated(mat);
1377   PetscValidPointer(info);
1378   if (!mat->ops->getinfo) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1379   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
1380   PetscFunctionReturn(0);
1381 }
1382 
1383 /* ----------------------------------------------------------*/
1384 #undef __FUNCT__
1385 #define __FUNCT__ "MatILUDTFactor"
1386 /*@C
1387    MatILUDTFactor - Performs a drop tolerance ILU factorization.
1388 
1389    Collective on Mat
1390 
1391    Input Parameters:
1392 +  mat - the matrix
1393 .  info - information about the factorization to be done
1394 .  row - row permutation
1395 -  col - column permutation
1396 
1397    Output Parameters:
1398 .  fact - the factored matrix
1399 
1400    Level: developer
1401 
1402    Notes:
1403    Most users should employ the simplified SLES interface for linear solvers
1404    instead of working directly with matrix algebra routines such as this.
1405    See, e.g., SLESCreate().
1406 
1407    This is currently only supported for the SeqAIJ matrix format using code
1408    from Yousef Saad's SPARSEKIT2  package (translated to C with f2c) and/or
1409    Matlab. SPARSEKIT2 is copyrighted by Yousef Saad with the GNU copyright
1410    and thus can be distributed with PETSc.
1411 
1412     Concepts: matrices^ILUDT factorization
1413 
1414 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatILUInfo
1415 @*/
1416 int MatILUDTFactor(Mat mat,MatILUInfo *info,IS row,IS col,Mat *fact)
1417 {
1418   int ierr;
1419 
1420   PetscFunctionBegin;
1421   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1422   PetscValidType(mat);
1423   MatPreallocated(mat);
1424   PetscValidPointer(fact);
1425   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1426   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1427   if (!mat->ops->iludtfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1428 
1429   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1430   ierr = (*mat->ops->iludtfactor)(mat,info,row,col,fact);CHKERRQ(ierr);
1431   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1432 
1433   PetscFunctionReturn(0);
1434 }
1435 
1436 #undef __FUNCT__
1437 #define __FUNCT__ "MatLUFactor"
1438 /*@
1439    MatLUFactor - Performs in-place LU factorization of matrix.
1440 
1441    Collective on Mat
1442 
1443    Input Parameters:
1444 +  mat - the matrix
1445 .  row - row permutation
1446 .  col - column permutation
1447 -  info - options for factorization, includes
1448 $          fill - expected fill as ratio of original fill.
1449 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
1450 $                   Run with the option -log_info to determine an optimal value to use
1451 
1452    Notes:
1453    Most users should employ the simplified SLES interface for linear solvers
1454    instead of working directly with matrix algebra routines such as this.
1455    See, e.g., SLESCreate().
1456 
1457    This changes the state of the matrix to a factored matrix; it cannot be used
1458    for example with MatSetValues() unless one first calls MatSetUnfactored().
1459 
1460    Level: developer
1461 
1462    Concepts: matrices^LU factorization
1463 
1464 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
1465           MatGetOrdering(), MatSetUnfactored(), MatLUInfo
1466 
1467 @*/
1468 int MatLUFactor(Mat mat,IS row,IS col,MatLUInfo *info)
1469 {
1470   int ierr;
1471 
1472   PetscFunctionBegin;
1473   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1474   PetscValidType(mat);
1475   MatPreallocated(mat);
1476   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1477   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1478   if (!mat->ops->lufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1479 
1480   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
1481   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
1482   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
1483   PetscFunctionReturn(0);
1484 }
1485 
1486 #undef __FUNCT__
1487 #define __FUNCT__ "MatILUFactor"
1488 /*@
1489    MatILUFactor - Performs in-place ILU factorization of matrix.
1490 
1491    Collective on Mat
1492 
1493    Input Parameters:
1494 +  mat - the matrix
1495 .  row - row permutation
1496 .  col - column permutation
1497 -  info - structure containing
1498 $      levels - number of levels of fill.
1499 $      expected fill - as ratio of original fill.
1500 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
1501                 missing diagonal entries)
1502 
1503    Notes:
1504    Probably really in-place only when level of fill is zero, otherwise allocates
1505    new space to store factored matrix and deletes previous memory.
1506 
1507    Most users should employ the simplified SLES interface for linear solvers
1508    instead of working directly with matrix algebra routines such as this.
1509    See, e.g., SLESCreate().
1510 
1511    Level: developer
1512 
1513    Concepts: matrices^ILU factorization
1514 
1515 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatILUInfo
1516 @*/
1517 int MatILUFactor(Mat mat,IS row,IS col,MatILUInfo *info)
1518 {
1519   int ierr;
1520 
1521   PetscFunctionBegin;
1522   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1523   PetscValidType(mat);
1524   MatPreallocated(mat);
1525   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
1526   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1527   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1528   if (!mat->ops->ilufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1529 
1530   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1531   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
1532   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1533   PetscFunctionReturn(0);
1534 }
1535 
1536 #undef __FUNCT__
1537 #define __FUNCT__ "MatLUFactorSymbolic"
1538 /*@
1539    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
1540    Call this routine before calling MatLUFactorNumeric().
1541 
1542    Collective on Mat
1543 
1544    Input Parameters:
1545 +  mat - the matrix
1546 .  row, col - row and column permutations
1547 -  info - options for factorization, includes
1548 $          fill - expected fill as ratio of original fill.
1549 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
1550 $                   Run with the option -log_info to determine an optimal value to use
1551 
1552    Output Parameter:
1553 .  fact - new matrix that has been symbolically factored
1554 
1555    Notes:
1556    See the users manual for additional information about
1557    choosing the fill factor for better efficiency.
1558 
1559    Most users should employ the simplified SLES interface for linear solvers
1560    instead of working directly with matrix algebra routines such as this.
1561    See, e.g., SLESCreate().
1562 
1563    Level: developer
1564 
1565    Concepts: matrices^LU symbolic factorization
1566 
1567 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatLUInfo
1568 @*/
1569 int MatLUFactorSymbolic(Mat mat,IS row,IS col,MatLUInfo *info,Mat *fact)
1570 {
1571   int ierr;
1572 
1573   PetscFunctionBegin;
1574   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1575   PetscValidType(mat);
1576   MatPreallocated(mat);
1577   PetscValidPointer(fact);
1578   PetscValidHeaderSpecific(row,IS_COOKIE);
1579   PetscValidHeaderSpecific(col,IS_COOKIE);
1580   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1581   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1582   if (!mat->ops->lufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic LU",mat->type_name);
1583 
1584   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
1585   ierr = (*mat->ops->lufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
1586   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
1587   PetscFunctionReturn(0);
1588 }
1589 
1590 #undef __FUNCT__
1591 #define __FUNCT__ "MatLUFactorNumeric"
1592 /*@
1593    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
1594    Call this routine after first calling MatLUFactorSymbolic().
1595 
1596    Collective on Mat
1597 
1598    Input Parameters:
1599 +  mat - the matrix
1600 -  fact - the matrix generated for the factor, from MatLUFactorSymbolic()
1601 
1602    Notes:
1603    See MatLUFactor() for in-place factorization.  See
1604    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
1605 
1606    Most users should employ the simplified SLES interface for linear solvers
1607    instead of working directly with matrix algebra routines such as this.
1608    See, e.g., SLESCreate().
1609 
1610    Level: developer
1611 
1612    Concepts: matrices^LU numeric factorization
1613 
1614 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
1615 @*/
1616 int MatLUFactorNumeric(Mat mat,Mat *fact)
1617 {
1618   int        ierr;
1619   PetscTruth flg;
1620 
1621   PetscFunctionBegin;
1622   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1623   PetscValidType(mat);
1624   MatPreallocated(mat);
1625   PetscValidPointer(fact);
1626   PetscValidHeaderSpecific(*fact,MAT_COOKIE);
1627   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1628   if (mat->M != (*fact)->M || mat->N != (*fact)->N) {
1629     SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat *fact: global dimensions are different %d should = %d %d should = %d",
1630             mat->M,(*fact)->M,mat->N,(*fact)->N);
1631   }
1632   if (!(*fact)->ops->lufactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1633 
1634   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
1635   ierr = (*(*fact)->ops->lufactornumeric)(mat,fact);CHKERRQ(ierr);
1636   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
1637   ierr = PetscOptionsHasName(PETSC_NULL,"-mat_view_draw",&flg);CHKERRQ(ierr);
1638   if (flg) {
1639     ierr = PetscOptionsHasName(PETSC_NULL,"-mat_view_contour",&flg);CHKERRQ(ierr);
1640     if (flg) {
1641       ierr = PetscViewerPushFormat(PETSC_VIEWER_DRAW_(mat->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
1642     }
1643     ierr = MatView(*fact,PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
1644     ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
1645     if (flg) {
1646       ierr = PetscViewerPopFormat(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
1647     }
1648   }
1649   PetscFunctionReturn(0);
1650 }
1651 
1652 #undef __FUNCT__
1653 #define __FUNCT__ "MatCholeskyFactor"
1654 /*@
1655    MatCholeskyFactor - Performs in-place Cholesky factorization of a
1656    symmetric matrix.
1657 
1658    Collective on Mat
1659 
1660    Input Parameters:
1661 +  mat - the matrix
1662 .  perm - row and column permutations
1663 -  f - expected fill as ratio of original fill
1664 
1665    Notes:
1666    See MatLUFactor() for the nonsymmetric case.  See also
1667    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
1668 
1669    Most users should employ the simplified SLES interface for linear solvers
1670    instead of working directly with matrix algebra routines such as this.
1671    See, e.g., SLESCreate().
1672 
1673    Level: developer
1674 
1675    Concepts: matrices^Cholesky factorization
1676 
1677 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
1678           MatGetOrdering()
1679 
1680 @*/
1681 int MatCholeskyFactor(Mat mat,IS perm,PetscReal f)
1682 {
1683   int ierr;
1684 
1685   PetscFunctionBegin;
1686   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1687   PetscValidType(mat);
1688   MatPreallocated(mat);
1689   PetscValidHeaderSpecific(perm,IS_COOKIE);
1690   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
1691   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1692   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1693   if (!mat->ops->choleskyfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1694 
1695   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
1696   ierr = (*mat->ops->choleskyfactor)(mat,perm,f);CHKERRQ(ierr);
1697   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
1698   PetscFunctionReturn(0);
1699 }
1700 
1701 #undef __FUNCT__
1702 #define __FUNCT__ "MatCholeskyFactorSymbolic"
1703 /*@
1704    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
1705    of a symmetric matrix.
1706 
1707    Collective on Mat
1708 
1709    Input Parameters:
1710 +  mat - the matrix
1711 .  perm - row and column permutations
1712 -  f - expected fill as ratio of original
1713 
1714    Output Parameter:
1715 .  fact - the factored matrix
1716 
1717    Notes:
1718    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
1719    MatCholeskyFactor() and MatCholeskyFactorNumeric().
1720 
1721    Most users should employ the simplified SLES interface for linear solvers
1722    instead of working directly with matrix algebra routines such as this.
1723    See, e.g., SLESCreate().
1724 
1725    Level: developer
1726 
1727    Concepts: matrices^Cholesky symbolic factorization
1728 
1729 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
1730           MatGetOrdering()
1731 
1732 @*/
1733 int MatCholeskyFactorSymbolic(Mat mat,IS perm,PetscReal f,Mat *fact)
1734 {
1735   int ierr;
1736 
1737   PetscFunctionBegin;
1738   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1739   PetscValidType(mat);
1740   MatPreallocated(mat);
1741   PetscValidPointer(fact);
1742   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
1743   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1744   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1745   if (!mat->ops->choleskyfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1746 
1747   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
1748   ierr = (*mat->ops->choleskyfactorsymbolic)(mat,perm,f,fact);CHKERRQ(ierr);
1749   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
1750   PetscFunctionReturn(0);
1751 }
1752 
1753 #undef __FUNCT__
1754 #define __FUNCT__ "MatCholeskyFactorNumeric"
1755 /*@
1756    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
1757    of a symmetric matrix. Call this routine after first calling
1758    MatCholeskyFactorSymbolic().
1759 
1760    Collective on Mat
1761 
1762    Input Parameter:
1763 .  mat - the initial matrix
1764 
1765    Output Parameter:
1766 .  fact - the factored matrix
1767 
1768    Notes:
1769    Most users should employ the simplified SLES interface for linear solvers
1770    instead of working directly with matrix algebra routines such as this.
1771    See, e.g., SLESCreate().
1772 
1773    Level: developer
1774 
1775    Concepts: matrices^Cholesky numeric factorization
1776 
1777 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
1778 @*/
1779 int MatCholeskyFactorNumeric(Mat mat,Mat *fact)
1780 {
1781   int ierr;
1782 
1783   PetscFunctionBegin;
1784   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1785   PetscValidType(mat);
1786   MatPreallocated(mat);
1787   PetscValidPointer(fact);
1788   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1789   if (!(*fact)->ops->choleskyfactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1790   if (mat->M != (*fact)->M || mat->N != (*fact)->N) {
1791     SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat *fact: global dim %d should = %d %d should = %d",
1792             mat->M,(*fact)->M,mat->N,(*fact)->N);
1793   }
1794 
1795   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
1796   ierr = (*(*fact)->ops->choleskyfactornumeric)(mat,fact);CHKERRQ(ierr);
1797   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
1798   PetscFunctionReturn(0);
1799 }
1800 
1801 /* ----------------------------------------------------------------*/
1802 #undef __FUNCT__
1803 #define __FUNCT__ "MatSolve"
1804 /*@
1805    MatSolve - Solves A x = b, given a factored matrix.
1806 
1807    Collective on Mat and Vec
1808 
1809    Input Parameters:
1810 +  mat - the factored matrix
1811 -  b - the right-hand-side vector
1812 
1813    Output Parameter:
1814 .  x - the result vector
1815 
1816    Notes:
1817    The vectors b and x cannot be the same.  I.e., one cannot
1818    call MatSolve(A,x,x).
1819 
1820    Notes:
1821    Most users should employ the simplified SLES interface for linear solvers
1822    instead of working directly with matrix algebra routines such as this.
1823    See, e.g., SLESCreate().
1824 
1825    Level: developer
1826 
1827    Concepts: matrices^triangular solves
1828 
1829 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
1830 @*/
1831 int MatSolve(Mat mat,Vec b,Vec x)
1832 {
1833   int ierr;
1834 
1835   PetscFunctionBegin;
1836   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1837   PetscValidType(mat);
1838   MatPreallocated(mat);
1839   PetscValidHeaderSpecific(b,VEC_COOKIE);
1840   PetscValidHeaderSpecific(x,VEC_COOKIE);
1841   PetscCheckSameComm(mat,b);
1842   PetscCheckSameComm(mat,x);
1843   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
1844   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
1845   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1846   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
1847   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
1848   if (mat->M == 0 && mat->N == 0) PetscFunctionReturn(0);
1849 
1850   if (!mat->ops->solve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1851   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
1852   ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
1853   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
1854   PetscFunctionReturn(0);
1855 }
1856 
1857 #undef __FUNCT__
1858 #define __FUNCT__ "MatForwardSolve"
1859 /* @
1860    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU.
1861 
1862    Collective on Mat and Vec
1863 
1864    Input Parameters:
1865 +  mat - the factored matrix
1866 -  b - the right-hand-side vector
1867 
1868    Output Parameter:
1869 .  x - the result vector
1870 
1871    Notes:
1872    MatSolve() should be used for most applications, as it performs
1873    a forward solve followed by a backward solve.
1874 
1875    The vectors b and x cannot be the same.  I.e., one cannot
1876    call MatForwardSolve(A,x,x).
1877 
1878    Most users should employ the simplified SLES interface for linear solvers
1879    instead of working directly with matrix algebra routines such as this.
1880    See, e.g., SLESCreate().
1881 
1882    Level: developer
1883 
1884    Concepts: matrices^forward solves
1885 
1886 .seealso: MatSolve(), MatBackwardSolve()
1887 @ */
1888 int MatForwardSolve(Mat mat,Vec b,Vec x)
1889 {
1890   int ierr;
1891 
1892   PetscFunctionBegin;
1893   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1894   PetscValidType(mat);
1895   MatPreallocated(mat);
1896   PetscValidHeaderSpecific(b,VEC_COOKIE);
1897   PetscValidHeaderSpecific(x,VEC_COOKIE);
1898   PetscCheckSameComm(mat,b);
1899   PetscCheckSameComm(mat,x);
1900   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
1901   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
1902   if (!mat->ops->forwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1903   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1904   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
1905   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
1906 
1907   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
1908   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
1909   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
1910   PetscFunctionReturn(0);
1911 }
1912 
1913 #undef __FUNCT__
1914 #define __FUNCT__ "MatBackwardSolve"
1915 /* @
1916    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
1917 
1918    Collective on Mat and Vec
1919 
1920    Input Parameters:
1921 +  mat - the factored matrix
1922 -  b - the right-hand-side vector
1923 
1924    Output Parameter:
1925 .  x - the result vector
1926 
1927    Notes:
1928    MatSolve() should be used for most applications, as it performs
1929    a forward solve followed by a backward solve.
1930 
1931    The vectors b and x cannot be the same.  I.e., one cannot
1932    call MatBackwardSolve(A,x,x).
1933 
1934    Most users should employ the simplified SLES interface for linear solvers
1935    instead of working directly with matrix algebra routines such as this.
1936    See, e.g., SLESCreate().
1937 
1938    Level: developer
1939 
1940    Concepts: matrices^backward solves
1941 
1942 .seealso: MatSolve(), MatForwardSolve()
1943 @ */
1944 int MatBackwardSolve(Mat mat,Vec b,Vec x)
1945 {
1946   int ierr;
1947 
1948   PetscFunctionBegin;
1949   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1950   PetscValidType(mat);
1951   MatPreallocated(mat);
1952   PetscValidHeaderSpecific(b,VEC_COOKIE);
1953   PetscValidHeaderSpecific(x,VEC_COOKIE);
1954   PetscCheckSameComm(mat,b);
1955   PetscCheckSameComm(mat,x);
1956   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
1957   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
1958   if (!mat->ops->backwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1959   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1960   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
1961   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
1962 
1963   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
1964   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
1965   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
1966   PetscFunctionReturn(0);
1967 }
1968 
1969 #undef __FUNCT__
1970 #define __FUNCT__ "MatSolveAdd"
1971 /*@
1972    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
1973 
1974    Collective on Mat and Vec
1975 
1976    Input Parameters:
1977 +  mat - the factored matrix
1978 .  b - the right-hand-side vector
1979 -  y - the vector to be added to
1980 
1981    Output Parameter:
1982 .  x - the result vector
1983 
1984    Notes:
1985    The vectors b and x cannot be the same.  I.e., one cannot
1986    call MatSolveAdd(A,x,y,x).
1987 
1988    Most users should employ the simplified SLES interface for linear solvers
1989    instead of working directly with matrix algebra routines such as this.
1990    See, e.g., SLESCreate().
1991 
1992    Level: developer
1993 
1994    Concepts: matrices^triangular solves
1995 
1996 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
1997 @*/
1998 int MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
1999 {
2000   PetscScalar one = 1.0;
2001   Vec    tmp;
2002   int    ierr;
2003 
2004   PetscFunctionBegin;
2005   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2006   PetscValidType(mat);
2007   MatPreallocated(mat);
2008   PetscValidHeaderSpecific(y,VEC_COOKIE);
2009   PetscValidHeaderSpecific(b,VEC_COOKIE);
2010   PetscValidHeaderSpecific(x,VEC_COOKIE);
2011   PetscCheckSameComm(mat,b);
2012   PetscCheckSameComm(mat,y);
2013   PetscCheckSameComm(mat,x);
2014   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2015   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2016   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2017   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2018   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
2019   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2020   if (x->n != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %d %d",x->n,y->n);
2021 
2022   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
2023   if (mat->ops->solveadd)  {
2024     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
2025   } else {
2026     /* do the solve then the add manually */
2027     if (x != y) {
2028       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
2029       ierr = VecAXPY(&one,y,x);CHKERRQ(ierr);
2030     } else {
2031       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
2032       PetscLogObjectParent(mat,tmp);
2033       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
2034       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
2035       ierr = VecAXPY(&one,tmp,x);CHKERRQ(ierr);
2036       ierr = VecDestroy(tmp);CHKERRQ(ierr);
2037     }
2038   }
2039   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
2040   PetscFunctionReturn(0);
2041 }
2042 
2043 #undef __FUNCT__
2044 #define __FUNCT__ "MatSolveTranspose"
2045 /*@
2046    MatSolveTranspose - Solves A' x = b, given a factored matrix.
2047 
2048    Collective on Mat and Vec
2049 
2050    Input Parameters:
2051 +  mat - the factored matrix
2052 -  b - the right-hand-side vector
2053 
2054    Output Parameter:
2055 .  x - the result vector
2056 
2057    Notes:
2058    The vectors b and x cannot be the same.  I.e., one cannot
2059    call MatSolveTranspose(A,x,x).
2060 
2061    Most users should employ the simplified SLES interface for linear solvers
2062    instead of working directly with matrix algebra routines such as this.
2063    See, e.g., SLESCreate().
2064 
2065    Level: developer
2066 
2067    Concepts: matrices^triangular solves
2068 
2069 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
2070 @*/
2071 int MatSolveTranspose(Mat mat,Vec b,Vec x)
2072 {
2073   int ierr;
2074 
2075   PetscFunctionBegin;
2076   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2077   PetscValidType(mat);
2078   MatPreallocated(mat);
2079   PetscValidHeaderSpecific(b,VEC_COOKIE);
2080   PetscValidHeaderSpecific(x,VEC_COOKIE);
2081   PetscCheckSameComm(mat,b);
2082   PetscCheckSameComm(mat,x);
2083   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2084   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2085   if (!mat->ops->solvetranspose) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s",mat->type_name);
2086   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
2087   if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->N,b->N);
2088 
2089   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
2090   ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
2091   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
2092   PetscFunctionReturn(0);
2093 }
2094 
2095 #undef __FUNCT__
2096 #define __FUNCT__ "MatSolveTransposeAdd"
2097 /*@
2098    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
2099                       factored matrix.
2100 
2101    Collective on Mat and Vec
2102 
2103    Input Parameters:
2104 +  mat - the factored matrix
2105 .  b - the right-hand-side vector
2106 -  y - the vector to be added to
2107 
2108    Output Parameter:
2109 .  x - the result vector
2110 
2111    Notes:
2112    The vectors b and x cannot be the same.  I.e., one cannot
2113    call MatSolveTransposeAdd(A,x,y,x).
2114 
2115    Most users should employ the simplified SLES interface for linear solvers
2116    instead of working directly with matrix algebra routines such as this.
2117    See, e.g., SLESCreate().
2118 
2119    Level: developer
2120 
2121    Concepts: matrices^triangular solves
2122 
2123 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
2124 @*/
2125 int MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
2126 {
2127   PetscScalar one = 1.0;
2128   int         ierr;
2129   Vec         tmp;
2130 
2131   PetscFunctionBegin;
2132   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2133   PetscValidType(mat);
2134   MatPreallocated(mat);
2135   PetscValidHeaderSpecific(y,VEC_COOKIE);
2136   PetscValidHeaderSpecific(b,VEC_COOKIE);
2137   PetscValidHeaderSpecific(x,VEC_COOKIE);
2138   PetscCheckSameComm(mat,b);
2139   PetscCheckSameComm(mat,y);
2140   PetscCheckSameComm(mat,x);
2141   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2142   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2143   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
2144   if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->N,b->N);
2145   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->N,y->N);
2146   if (x->n != y->n)   SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %d %d",x->n,y->n);
2147 
2148   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
2149   if (mat->ops->solvetransposeadd) {
2150     ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
2151   } else {
2152     /* do the solve then the add manually */
2153     if (x != y) {
2154       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
2155       ierr = VecAXPY(&one,y,x);CHKERRQ(ierr);
2156     } else {
2157       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
2158       PetscLogObjectParent(mat,tmp);
2159       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
2160       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
2161       ierr = VecAXPY(&one,tmp,x);CHKERRQ(ierr);
2162       ierr = VecDestroy(tmp);CHKERRQ(ierr);
2163     }
2164   }
2165   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
2166   PetscFunctionReturn(0);
2167 }
2168 /* ----------------------------------------------------------------*/
2169 
2170 #undef __FUNCT__
2171 #define __FUNCT__ "MatRelax"
2172 /*@
2173    MatRelax - Computes one relaxation sweep.
2174 
2175    Collective on Mat and Vec
2176 
2177    Input Parameters:
2178 +  mat - the matrix
2179 .  b - the right hand side
2180 .  omega - the relaxation factor
2181 .  flag - flag indicating the type of SOR (see below)
2182 .  shift -  diagonal shift
2183 -  its - the number of iterations
2184 
2185    Output Parameters:
2186 .  x - the solution (can contain an initial guess)
2187 
2188    SOR Flags:
2189 .     SOR_FORWARD_SWEEP - forward SOR
2190 .     SOR_BACKWARD_SWEEP - backward SOR
2191 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
2192 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
2193 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
2194 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
2195 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
2196          upper/lower triangular part of matrix to
2197          vector (with omega)
2198 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
2199 
2200    Notes:
2201    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
2202    SOR_LOCAL_SYMMETRIC_SWEEP perform seperate independent smoothings
2203    on each processor.
2204 
2205    Application programmers will not generally use MatRelax() directly,
2206    but instead will employ the SLES/PC interface.
2207 
2208    Notes for Advanced Users:
2209    The flags are implemented as bitwise inclusive or operations.
2210    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
2211    to specify a zero initial guess for SSOR.
2212 
2213    Most users should employ the simplified SLES interface for linear solvers
2214    instead of working directly with matrix algebra routines such as this.
2215    See, e.g., SLESCreate().
2216 
2217    Level: developer
2218 
2219    Concepts: matrices^relaxation
2220    Concepts: matrices^SOR
2221    Concepts: matrices^Gauss-Seidel
2222 
2223 @*/
2224 int MatRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,int its,Vec x)
2225 {
2226   int ierr;
2227 
2228   PetscFunctionBegin;
2229   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2230   PetscValidType(mat);
2231   MatPreallocated(mat);
2232   PetscValidHeaderSpecific(b,VEC_COOKIE);
2233   PetscValidHeaderSpecific(x,VEC_COOKIE);
2234   PetscCheckSameComm(mat,b);
2235   PetscCheckSameComm(mat,x);
2236   if (!mat->ops->relax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2237   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2238   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2239   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2240   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2241   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2242 
2243   ierr = PetscLogEventBegin(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2244   ierr =(*mat->ops->relax)(mat,b,omega,flag,shift,its,x);CHKERRQ(ierr);
2245   ierr = PetscLogEventEnd(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2246   PetscFunctionReturn(0);
2247 }
2248 
2249 #undef __FUNCT__
2250 #define __FUNCT__ "MatCopy_Basic"
2251 /*
2252       Default matrix copy routine.
2253 */
2254 int MatCopy_Basic(Mat A,Mat B,MatStructure str)
2255 {
2256   int         ierr,i,rstart,rend,nz,*cwork;
2257   PetscScalar *vwork;
2258 
2259   PetscFunctionBegin;
2260   ierr = MatZeroEntries(B);CHKERRQ(ierr);
2261   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
2262   for (i=rstart; i<rend; i++) {
2263     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
2264     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
2265     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
2266   }
2267   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2268   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2269   PetscFunctionReturn(0);
2270 }
2271 
2272 #undef __FUNCT__
2273 #define __FUNCT__ "MatCopy"
2274 /*@C
2275    MatCopy - Copys a matrix to another matrix.
2276 
2277    Collective on Mat
2278 
2279    Input Parameters:
2280 +  A - the matrix
2281 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
2282 
2283    Output Parameter:
2284 .  B - where the copy is put
2285 
2286    Notes:
2287    If you use SAME_NONZERO_PATTERN then the zero matrices had better have the
2288    same nonzero pattern or the routine will crash.
2289 
2290    MatCopy() copies the matrix entries of a matrix to another existing
2291    matrix (after first zeroing the second matrix).  A related routine is
2292    MatConvert(), which first creates a new matrix and then copies the data.
2293 
2294    Level: intermediate
2295 
2296    Concepts: matrices^copying
2297 
2298 .seealso: MatConvert()
2299 @*/
2300 int MatCopy(Mat A,Mat B,MatStructure str)
2301 {
2302   int ierr;
2303 
2304   PetscFunctionBegin;
2305   PetscValidHeaderSpecific(A,MAT_COOKIE);
2306   PetscValidHeaderSpecific(B,MAT_COOKIE);
2307   PetscValidType(A);
2308   MatPreallocated(A);
2309   PetscValidType(B);
2310   MatPreallocated(B);
2311   PetscCheckSameComm(A,B);
2312   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2313   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2314   if (A->M != B->M || A->N != B->N) SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %d %d",A->M,B->M,
2315                                              A->N,B->N);
2316 
2317   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
2318   if (A->ops->copy) {
2319     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
2320   } else { /* generic conversion */
2321     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2322   }
2323   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
2324   PetscFunctionReturn(0);
2325 }
2326 
2327 #include "petscsys.h"
2328 PetscTruth MatConvertRegisterAllCalled = PETSC_FALSE;
2329 PetscFList MatConvertList              = 0;
2330 
2331 #undef __FUNCT__
2332 #define __FUNCT__ "MatConvertRegister"
2333 /*@C
2334     MatConvertRegister - Allows one to register a routine that reads matrices
2335         from a binary file for a particular matrix type.
2336 
2337   Not Collective
2338 
2339   Input Parameters:
2340 +   type - the type of matrix (defined in include/petscmat.h), for example, MATSEQAIJ.
2341 -   Converter - the function that reads the matrix from the binary file.
2342 
2343   Level: developer
2344 
2345 .seealso: MatConvertRegisterAll(), MatConvert()
2346 
2347 @*/
2348 int MatConvertRegister(char *sname,char *path,char *name,int (*function)(Mat,MatType,Mat*))
2349 {
2350   int  ierr;
2351   char fullname[256];
2352 
2353   PetscFunctionBegin;
2354   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
2355   ierr = PetscFListAdd(&MatConvertList,sname,fullname,(void (*)())function);CHKERRQ(ierr);
2356   PetscFunctionReturn(0);
2357 }
2358 
2359 #undef __FUNCT__
2360 #define __FUNCT__ "MatConvert"
2361 /*@C
2362    MatConvert - Converts a matrix to another matrix, either of the same
2363    or different type.
2364 
2365    Collective on Mat
2366 
2367    Input Parameters:
2368 +  mat - the matrix
2369 -  newtype - new matrix type.  Use MATSAME to create a new matrix of the
2370    same type as the original matrix.
2371 
2372    Output Parameter:
2373 .  M - pointer to place new matrix
2374 
2375    Notes:
2376    MatConvert() first creates a new matrix and then copies the data from
2377    the first matrix.  A related routine is MatCopy(), which copies the matrix
2378    entries of one matrix to another already existing matrix context.
2379 
2380    Level: intermediate
2381 
2382    Concepts: matrices^converting between storage formats
2383 
2384 .seealso: MatCopy(), MatDuplicate()
2385 @*/
2386 int MatConvert(Mat mat,MatType newtype,Mat *M)
2387 {
2388   int        ierr;
2389   PetscTruth sametype,issame,flg;
2390   char       convname[256],mtype[256];
2391 
2392   PetscFunctionBegin;
2393   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2394   PetscValidType(mat);
2395   MatPreallocated(mat);
2396   PetscValidPointer(M);
2397   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2398   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2399 
2400   ierr = PetscOptionsGetString(PETSC_NULL,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
2401   if (flg) {
2402     newtype = mtype;
2403   }
2404   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2405 
2406   ierr = PetscTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
2407   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
2408   if ((sametype || issame) && mat->ops->duplicate) {
2409     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
2410   } else {
2411     int (*conv)(Mat,MatType,Mat*);
2412     if (!MatConvertRegisterAllCalled) {
2413       ierr = MatConvertRegisterAll(PETSC_NULL);CHKERRQ(ierr);
2414     }
2415     ierr = PetscFListFind(mat->comm,MatConvertList,newtype,(void(**)())&conv);CHKERRQ(ierr);
2416     if (conv) {
2417       ierr = (*conv)(mat,newtype,M);CHKERRQ(ierr);
2418     } else {
2419       ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
2420       ierr = PetscStrcat(convname,mat->type_name);CHKERRQ(ierr);
2421       ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
2422       ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
2423       ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
2424       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)())&conv);CHKERRQ(ierr);
2425       if (conv) {
2426         ierr = (*conv)(mat,newtype,M);CHKERRQ(ierr);
2427       } else {
2428         if (mat->ops->convert) {
2429           ierr = (*mat->ops->convert)(mat,newtype,M);CHKERRQ(ierr);
2430         } else {
2431           ierr = MatConvert_Basic(mat,newtype,M);CHKERRQ(ierr);
2432         }
2433       }
2434     }
2435   }
2436   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2437   PetscFunctionReturn(0);
2438 }
2439 
2440 
2441 #undef __FUNCT__
2442 #define __FUNCT__ "MatDuplicate"
2443 /*@C
2444    MatDuplicate - Duplicates a matrix including the non-zero structure.
2445 
2446    Collective on Mat
2447 
2448    Input Parameters:
2449 +  mat - the matrix
2450 -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
2451         values as well or not
2452 
2453    Output Parameter:
2454 .  M - pointer to place new matrix
2455 
2456    Level: intermediate
2457 
2458    Concepts: matrices^duplicating
2459 
2460 .seealso: MatCopy(), MatConvert()
2461 @*/
2462 int MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
2463 {
2464   int ierr;
2465 
2466   PetscFunctionBegin;
2467   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2468   PetscValidType(mat);
2469   MatPreallocated(mat);
2470   PetscValidPointer(M);
2471   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2472   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2473 
2474   *M  = 0;
2475   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2476   if (!mat->ops->duplicate) {
2477     SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type");
2478   }
2479   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
2480   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2481   PetscFunctionReturn(0);
2482 }
2483 
2484 #undef __FUNCT__
2485 #define __FUNCT__ "MatGetDiagonal"
2486 /*@
2487    MatGetDiagonal - Gets the diagonal of a matrix.
2488 
2489    Collective on Mat and Vec
2490 
2491    Input Parameters:
2492 +  mat - the matrix
2493 -  v - the vector for storing the diagonal
2494 
2495    Output Parameter:
2496 .  v - the diagonal of the matrix
2497 
2498    Notes:
2499    For the SeqAIJ matrix format, this routine may also be called
2500    on a LU factored matrix; in that case it routines the reciprocal of
2501    the diagonal entries in U. It returns the entries permuted by the
2502    row and column permutation used during the symbolic factorization.
2503 
2504    Level: intermediate
2505 
2506    Concepts: matrices^accessing diagonals
2507 
2508 .seealso: MatGetRow(), MatGetSubmatrices(), MatGetSubmatrix(), MatGetRowMax()
2509 @*/
2510 int MatGetDiagonal(Mat mat,Vec v)
2511 {
2512   int ierr;
2513 
2514   PetscFunctionBegin;
2515   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2516   PetscValidType(mat);
2517   MatPreallocated(mat);
2518   PetscValidHeaderSpecific(v,VEC_COOKIE);
2519   /* PetscCheckSameComm(mat,v); Could be MPI vector but Seq matrix cause of two submatrix storage */
2520   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2521   if (!mat->ops->getdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2522 
2523   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
2524   PetscFunctionReturn(0);
2525 }
2526 
2527 #undef __FUNCT__
2528 #define __FUNCT__ "MatGetRowMax"
2529 /*@
2530    MatGetRowMax - Gets the maximum value (in absolute value) of each
2531         row of the matrix
2532 
2533    Collective on Mat and Vec
2534 
2535    Input Parameters:
2536 .  mat - the matrix
2537 
2538    Output Parameter:
2539 .  v - the vector for storing the maximums
2540 
2541    Level: intermediate
2542 
2543    Concepts: matrices^getting row maximums
2544 
2545 .seealso: MatGetDiagonal(), MatGetSubmatrices(), MatGetSubmatrix()
2546 @*/
2547 int MatGetRowMax(Mat mat,Vec v)
2548 {
2549   int ierr;
2550 
2551   PetscFunctionBegin;
2552   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2553   PetscValidType(mat);
2554   MatPreallocated(mat);
2555   PetscValidHeaderSpecific(v,VEC_COOKIE);
2556   /* PetscCheckSameComm(mat,v); Could be MPI vector but Seq matrix cause of two submatrix storage */
2557   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2558   if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2559 
2560   ierr = (*mat->ops->getrowmax)(mat,v);CHKERRQ(ierr);
2561   PetscFunctionReturn(0);
2562 }
2563 
2564 #undef __FUNCT__
2565 #define __FUNCT__ "MatTranspose"
2566 /*@C
2567    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
2568 
2569    Collective on Mat
2570 
2571    Input Parameter:
2572 .  mat - the matrix to transpose
2573 
2574    Output Parameters:
2575 .  B - the transpose (or pass in PETSC_NULL for an in-place transpose)
2576 
2577    Level: intermediate
2578 
2579    Concepts: matrices^transposing
2580 
2581 .seealso: MatMultTranspose(), MatMultTransposeAdd()
2582 @*/
2583 int MatTranspose(Mat mat,Mat *B)
2584 {
2585   int ierr;
2586 
2587   PetscFunctionBegin;
2588   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2589   PetscValidType(mat);
2590   MatPreallocated(mat);
2591   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2592   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2593   if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2594   ierr = (*mat->ops->transpose)(mat,B);CHKERRQ(ierr);
2595   PetscFunctionReturn(0);
2596 }
2597 
2598 #undef __FUNCT__
2599 #define __FUNCT__ "MatPermute"
2600 /*@C
2601    MatPermute - Creates a new matrix with rows and columns permuted from the
2602    original.
2603 
2604    Collective on Mat
2605 
2606    Input Parameters:
2607 +  mat - the matrix to permute
2608 .  row - row permutation, each processor supplies only the permutation for its rows
2609 -  col - column permutation, each processor needs the entire column permutation, that is
2610          this is the same size as the total number of columns in the matrix
2611 
2612    Output Parameters:
2613 .  B - the permuted matrix
2614 
2615    Level: advanced
2616 
2617    Concepts: matrices^permuting
2618 
2619 .seealso: MatGetOrdering()
2620 @*/
2621 int MatPermute(Mat mat,IS row,IS col,Mat *B)
2622 {
2623   int ierr;
2624 
2625   PetscFunctionBegin;
2626   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2627   PetscValidType(mat);
2628   MatPreallocated(mat);
2629   PetscValidHeaderSpecific(row,IS_COOKIE);
2630   PetscValidHeaderSpecific(col,IS_COOKIE);
2631   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2632   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2633   if (!mat->ops->permute) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2634   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
2635   PetscFunctionReturn(0);
2636 }
2637 
2638 #undef __FUNCT__
2639 #define __FUNCT__ "MatPermuteSparsify"
2640 /*@C
2641   MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the
2642   original and sparsified to the prescribed tolerance.
2643 
2644   Collective on Mat
2645 
2646   Input Parameters:
2647 + A    - The matrix to permute
2648 . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
2649 . frac - The half-bandwidth as a fraction of the total size, or 0.0
2650 . tol  - The drop tolerance
2651 . rowp - The row permutation
2652 - colp - The column permutation
2653 
2654   Output Parameter:
2655 . B    - The permuted, sparsified matrix
2656 
2657   Level: advanced
2658 
2659   Note:
2660   The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
2661   restrict the half-bandwidth of the resulting matrix to 5% of the
2662   total matrix size.
2663 
2664 .keywords: matrix, permute, sparsify
2665 
2666 .seealso: MatGetOrdering(), MatPermute()
2667 @*/
2668 int MatPermuteSparsify(Mat A, int band, double frac, double tol, IS rowp, IS colp, Mat *B)
2669 {
2670   IS           irowp, icolp;
2671   int         *rows, *cols;
2672   int          M, N, locRowStart, locRowEnd;
2673   int          nz, newNz;
2674   int         *cwork, *cnew;
2675   PetscScalar *vwork, *vnew;
2676   int          bw, size;
2677   int          row, locRow, newRow, col, newCol;
2678   int          ierr;
2679 
2680   PetscFunctionBegin;
2681   PetscValidHeaderSpecific(A,    MAT_COOKIE);
2682   PetscValidHeaderSpecific(rowp, IS_COOKIE);
2683   PetscValidHeaderSpecific(colp, IS_COOKIE);
2684   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
2685   if (A->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
2686   if (!A->ops->permutesparsify) {
2687     ierr = MatGetSize(A, &M, &N);                                                                         CHKERRQ(ierr);
2688     ierr = MatGetOwnershipRange(A, &locRowStart, &locRowEnd);                                             CHKERRQ(ierr);
2689     ierr = ISGetSize(rowp, &size);                                                                        CHKERRQ(ierr);
2690     if (size != M) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %d for row permutation, should be %d", size, M);
2691     ierr = ISGetSize(colp, &size);                                                                        CHKERRQ(ierr);
2692     if (size != N) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %d for column permutation, should be %d", size, N);
2693     ierr = ISInvertPermutation(rowp, 0, &irowp);                                                          CHKERRQ(ierr);
2694     ierr = ISGetIndices(irowp, &rows);                                                                    CHKERRQ(ierr);
2695     ierr = ISInvertPermutation(colp, 0, &icolp);                                                          CHKERRQ(ierr);
2696     ierr = ISGetIndices(icolp, &cols);                                                                    CHKERRQ(ierr);
2697     ierr = PetscMalloc(N * sizeof(int),         &cnew);                                                   CHKERRQ(ierr);
2698     ierr = PetscMalloc(N * sizeof(PetscScalar), &vnew);                                                   CHKERRQ(ierr);
2699 
2700     /* Setup bandwidth to include */
2701     if (band == PETSC_DECIDE) {
2702       if (frac <= 0.0)
2703         bw = (int) (M * 0.05);
2704       else
2705         bw = (int) (M * frac);
2706     } else {
2707       if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
2708       bw = band;
2709     }
2710 
2711     /* Put values into new matrix */
2712     ierr = MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B);                                                    CHKERRQ(ierr);
2713     for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) {
2714       ierr = MatGetRow(A, row, &nz, &cwork, &vwork);                                                      CHKERRQ(ierr);
2715       newRow   = rows[locRow]+locRowStart;
2716       for(col = 0, newNz = 0; col < nz; col++) {
2717         newCol = cols[cwork[col]];
2718         if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (fabs(vwork[col]) >= tol)) {
2719           cnew[newNz] = newCol;
2720           vnew[newNz] = vwork[col];
2721           newNz++;
2722         }
2723       }
2724       ierr = MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES);                              CHKERRQ(ierr);
2725       ierr = MatRestoreRow(A, row, &nz, &cwork, &vwork);                                                  CHKERRQ(ierr);
2726     }
2727     ierr = PetscFree(cnew);                                                                               CHKERRQ(ierr);
2728     ierr = PetscFree(vnew);                                                                               CHKERRQ(ierr);
2729     ierr = MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY);                                                      CHKERRQ(ierr);
2730     ierr = MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY);                                                        CHKERRQ(ierr);
2731     ierr = ISRestoreIndices(irowp, &rows);                                                                CHKERRQ(ierr);
2732     ierr = ISRestoreIndices(icolp, &cols);                                                                CHKERRQ(ierr);
2733     ierr = ISDestroy(irowp);                                                                              CHKERRQ(ierr);
2734     ierr = ISDestroy(icolp);                                                                              CHKERRQ(ierr);
2735   } else {
2736     ierr = (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B);                                 CHKERRQ(ierr);
2737   }
2738   PetscFunctionReturn(0);
2739 }
2740 
2741 #undef __FUNCT__
2742 #define __FUNCT__ "MatEqual"
2743 /*@
2744    MatEqual - Compares two matrices.
2745 
2746    Collective on Mat
2747 
2748    Input Parameters:
2749 +  A - the first matrix
2750 -  B - the second matrix
2751 
2752    Output Parameter:
2753 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
2754 
2755    Level: intermediate
2756 
2757    Concepts: matrices^equality between
2758 @*/
2759 int MatEqual(Mat A,Mat B,PetscTruth *flg)
2760 {
2761   int ierr;
2762 
2763   PetscFunctionBegin;
2764   PetscValidHeaderSpecific(A,MAT_COOKIE);
2765   PetscValidHeaderSpecific(B,MAT_COOKIE);
2766   PetscValidType(A);
2767   MatPreallocated(A);
2768   PetscValidType(B);
2769   MatPreallocated(B);
2770   PetscValidIntPointer(flg);
2771   PetscCheckSameComm(A,B);
2772   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2773   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2774   if (A->M != B->M || A->N != B->N) SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %d %d %d %d",A->M,B->M,A->N,B->N);
2775   if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",A->type_name);
2776   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
2777   PetscFunctionReturn(0);
2778 }
2779 
2780 #undef __FUNCT__
2781 #define __FUNCT__ "MatDiagonalScale"
2782 /*@
2783    MatDiagonalScale - Scales a matrix on the left and right by diagonal
2784    matrices that are stored as vectors.  Either of the two scaling
2785    matrices can be PETSC_NULL.
2786 
2787    Collective on Mat
2788 
2789    Input Parameters:
2790 +  mat - the matrix to be scaled
2791 .  l - the left scaling vector (or PETSC_NULL)
2792 -  r - the right scaling vector (or PETSC_NULL)
2793 
2794    Notes:
2795    MatDiagonalScale() computes A = LAR, where
2796    L = a diagonal matrix, R = a diagonal matrix
2797 
2798    Level: intermediate
2799 
2800    Concepts: matrices^diagonal scaling
2801    Concepts: diagonal scaling of matrices
2802 
2803 .seealso: MatScale()
2804 @*/
2805 int MatDiagonalScale(Mat mat,Vec l,Vec r)
2806 {
2807   int ierr;
2808 
2809   PetscFunctionBegin;
2810   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2811   PetscValidType(mat);
2812   MatPreallocated(mat);
2813   if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2814   if (l) {PetscValidHeaderSpecific(l,VEC_COOKIE);PetscCheckSameComm(mat,l);}
2815   if (r) {PetscValidHeaderSpecific(r,VEC_COOKIE);PetscCheckSameComm(mat,r);}
2816   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2817   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2818 
2819   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
2820   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
2821   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
2822   PetscFunctionReturn(0);
2823 }
2824 
2825 #undef __FUNCT__
2826 #define __FUNCT__ "MatScale"
2827 /*@
2828     MatScale - Scales all elements of a matrix by a given number.
2829 
2830     Collective on Mat
2831 
2832     Input Parameters:
2833 +   mat - the matrix to be scaled
2834 -   a  - the scaling value
2835 
2836     Output Parameter:
2837 .   mat - the scaled matrix
2838 
2839     Level: intermediate
2840 
2841     Concepts: matrices^scaling all entries
2842 
2843 .seealso: MatDiagonalScale()
2844 @*/
2845 int MatScale(PetscScalar *a,Mat mat)
2846 {
2847   int ierr;
2848 
2849   PetscFunctionBegin;
2850   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2851   PetscValidType(mat);
2852   MatPreallocated(mat);
2853   PetscValidScalarPointer(a);
2854   if (!mat->ops->scale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2855   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2856   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2857 
2858   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
2859   ierr = (*mat->ops->scale)(a,mat);CHKERRQ(ierr);
2860   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
2861   PetscFunctionReturn(0);
2862 }
2863 
2864 #undef __FUNCT__
2865 #define __FUNCT__ "MatNorm"
2866 /*@
2867    MatNorm - Calculates various norms of a matrix.
2868 
2869    Collective on Mat
2870 
2871    Input Parameters:
2872 +  mat - the matrix
2873 -  type - the type of norm, NORM_1, NORM_2, NORM_FROBENIUS, NORM_INFINITY
2874 
2875    Output Parameters:
2876 .  norm - the resulting norm
2877 
2878    Level: intermediate
2879 
2880    Concepts: matrices^norm
2881    Concepts: norm^of matrix
2882 @*/
2883 int MatNorm(Mat mat,NormType type,PetscReal *norm)
2884 {
2885   int ierr;
2886 
2887   PetscFunctionBegin;
2888   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2889   PetscValidType(mat);
2890   MatPreallocated(mat);
2891   PetscValidScalarPointer(norm);
2892 
2893   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2894   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2895   if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2896   ierr = (*mat->ops->norm)(mat,type,norm);CHKERRQ(ierr);
2897   PetscFunctionReturn(0);
2898 }
2899 
2900 /*
2901      This variable is used to prevent counting of MatAssemblyBegin() that
2902    are called from within a MatAssemblyEnd().
2903 */
2904 static int MatAssemblyEnd_InUse = 0;
2905 #undef __FUNCT__
2906 #define __FUNCT__ "MatAssemblyBegin"
2907 /*@
2908    MatAssemblyBegin - Begins assembling the matrix.  This routine should
2909    be called after completing all calls to MatSetValues().
2910 
2911    Collective on Mat
2912 
2913    Input Parameters:
2914 +  mat - the matrix
2915 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
2916 
2917    Notes:
2918    MatSetValues() generally caches the values.  The matrix is ready to
2919    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
2920    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
2921    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
2922    using the matrix.
2923 
2924    Level: beginner
2925 
2926    Concepts: matrices^assembling
2927 
2928 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
2929 @*/
2930 int MatAssemblyBegin(Mat mat,MatAssemblyType type)
2931 {
2932   int ierr;
2933 
2934   PetscFunctionBegin;
2935   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2936   PetscValidType(mat);
2937   MatPreallocated(mat);
2938   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
2939   if (mat->assembled) {
2940     mat->was_assembled = PETSC_TRUE;
2941     mat->assembled     = PETSC_FALSE;
2942   }
2943   if (!MatAssemblyEnd_InUse) {
2944     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
2945     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
2946     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
2947   } else {
2948     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
2949   }
2950   PetscFunctionReturn(0);
2951 }
2952 
2953 #undef __FUNCT__
2954 #define __FUNCT__ "MatAssembed"
2955 /*@
2956    MatAssembled - Indicates if a matrix has been assembled and is ready for
2957      use; for example, in matrix-vector product.
2958 
2959    Collective on Mat
2960 
2961    Input Parameter:
2962 .  mat - the matrix
2963 
2964    Output Parameter:
2965 .  assembled - PETSC_TRUE or PETSC_FALSE
2966 
2967    Level: advanced
2968 
2969    Concepts: matrices^assembled?
2970 
2971 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
2972 @*/
2973 int MatAssembled(Mat mat,PetscTruth *assembled)
2974 {
2975   PetscFunctionBegin;
2976   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2977   PetscValidType(mat);
2978   MatPreallocated(mat);
2979   *assembled = mat->assembled;
2980   PetscFunctionReturn(0);
2981 }
2982 
2983 #undef __FUNCT__
2984 #define __FUNCT__ "MatView_Private"
2985 /*
2986     Processes command line options to determine if/how a matrix
2987   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
2988 */
2989 int MatView_Private(Mat mat)
2990 {
2991   int        ierr;
2992   PetscTruth flg;
2993 
2994   PetscFunctionBegin;
2995   ierr = PetscOptionsHasName(mat->prefix,"-mat_view_info",&flg);CHKERRQ(ierr);
2996   if (flg) {
2997     ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
2998     ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
2999     ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3000   }
3001   ierr = PetscOptionsHasName(mat->prefix,"-mat_view_info_detailed",&flg);CHKERRQ(ierr);
3002   if (flg) {
3003     ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO_LONG);CHKERRQ(ierr);
3004     ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3005     ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3006   }
3007   ierr = PetscOptionsHasName(mat->prefix,"-mat_view",&flg);CHKERRQ(ierr);
3008   if (flg) {
3009     ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3010   }
3011   ierr = PetscOptionsHasName(mat->prefix,"-mat_view_matlab",&flg);CHKERRQ(ierr);
3012   if (flg) {
3013     ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr);
3014     ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3015     ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3016   }
3017   ierr = PetscOptionsHasName(mat->prefix,"-mat_view_draw",&flg);CHKERRQ(ierr);
3018   if (flg) {
3019     ierr = PetscOptionsHasName(mat->prefix,"-mat_view_contour",&flg);CHKERRQ(ierr);
3020     if (flg) {
3021       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(mat->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
3022     }
3023     ierr = MatView(mat,PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3024     ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3025     if (flg) {
3026       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3027     }
3028   }
3029   ierr = PetscOptionsHasName(mat->prefix,"-mat_view_socket",&flg);CHKERRQ(ierr);
3030   if (flg) {
3031     ierr = MatView(mat,PETSC_VIEWER_SOCKET_(mat->comm));CHKERRQ(ierr);
3032     ierr = PetscViewerFlush(PETSC_VIEWER_SOCKET_(mat->comm));CHKERRQ(ierr);
3033   }
3034   ierr = PetscOptionsHasName(mat->prefix,"-mat_view_binary",&flg);CHKERRQ(ierr);
3035   if (flg) {
3036     ierr = MatView(mat,PETSC_VIEWER_BINARY_(mat->comm));CHKERRQ(ierr);
3037     ierr = PetscViewerFlush(PETSC_VIEWER_BINARY_(mat->comm));CHKERRQ(ierr);
3038   }
3039   PetscFunctionReturn(0);
3040 }
3041 
3042 #undef __FUNCT__
3043 #define __FUNCT__ "MatAssemblyEnd"
3044 /*@
3045    MatAssemblyEnd - Completes assembling the matrix.  This routine should
3046    be called after MatAssemblyBegin().
3047 
3048    Collective on Mat
3049 
3050    Input Parameters:
3051 +  mat - the matrix
3052 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
3053 
3054    Options Database Keys:
3055 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
3056 .  -mat_view_info_detailed - Prints more detailed info
3057 .  -mat_view - Prints matrix in ASCII format
3058 .  -mat_view_matlab - Prints matrix in Matlab format
3059 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
3060 .  -display <name> - Sets display name (default is host)
3061 -  -draw_pause <sec> - Sets number of seconds to pause after display
3062 
3063    Notes:
3064    MatSetValues() generally caches the values.  The matrix is ready to
3065    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
3066    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
3067    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
3068    using the matrix.
3069 
3070    Level: beginner
3071 
3072 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled()
3073 @*/
3074 int MatAssemblyEnd(Mat mat,MatAssemblyType type)
3075 {
3076   int        ierr;
3077   static int inassm = 0;
3078 
3079   PetscFunctionBegin;
3080   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3081   PetscValidType(mat);
3082   MatPreallocated(mat);
3083 
3084   inassm++;
3085   MatAssemblyEnd_InUse++;
3086   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
3087     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
3088     if (mat->ops->assemblyend) {
3089       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
3090     }
3091     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
3092   } else {
3093     if (mat->ops->assemblyend) {
3094       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
3095     }
3096   }
3097 
3098   /* Flush assembly is not a true assembly */
3099   if (type != MAT_FLUSH_ASSEMBLY) {
3100     mat->assembled  = PETSC_TRUE; mat->num_ass++;
3101   }
3102   mat->insertmode = NOT_SET_VALUES;
3103   MatAssemblyEnd_InUse--;
3104 
3105   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
3106     ierr = MatView_Private(mat);CHKERRQ(ierr);
3107   }
3108   inassm--;
3109   PetscFunctionReturn(0);
3110 }
3111 
3112 
3113 #undef __FUNCT__
3114 #define __FUNCT__ "MatCompress"
3115 /*@
3116    MatCompress - Tries to store the matrix in as little space as
3117    possible.  May fail if memory is already fully used, since it
3118    tries to allocate new space.
3119 
3120    Collective on Mat
3121 
3122    Input Parameters:
3123 .  mat - the matrix
3124 
3125    Level: advanced
3126 
3127 @*/
3128 int MatCompress(Mat mat)
3129 {
3130   int ierr;
3131 
3132   PetscFunctionBegin;
3133   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3134   PetscValidType(mat);
3135   MatPreallocated(mat);
3136   if (mat->ops->compress) {ierr = (*mat->ops->compress)(mat);CHKERRQ(ierr);}
3137   PetscFunctionReturn(0);
3138 }
3139 
3140 #undef __FUNCT__
3141 #define __FUNCT__ "MatSetOption"
3142 /*@
3143    MatSetOption - Sets a parameter option for a matrix. Some options
3144    may be specific to certain storage formats.  Some options
3145    determine how values will be inserted (or added). Sorted,
3146    row-oriented input will generally assemble the fastest. The default
3147    is row-oriented, nonsorted input.
3148 
3149    Collective on Mat
3150 
3151    Input Parameters:
3152 +  mat - the matrix
3153 -  option - the option, one of those listed below (and possibly others),
3154              e.g., MAT_ROWS_SORTED, MAT_NEW_NONZERO_LOCATION_ERR
3155 
3156    Options Describing Matrix Structure:
3157 +    MAT_SYMMETRIC - symmetric in terms of both structure and value
3158 -    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
3159 
3160    Options For Use with MatSetValues():
3161    Insert a logically dense subblock, which can be
3162 +    MAT_ROW_ORIENTED - row-oriented
3163 .    MAT_COLUMN_ORIENTED - column-oriented
3164 .    MAT_ROWS_SORTED - sorted by row
3165 .    MAT_ROWS_UNSORTED - not sorted by row
3166 .    MAT_COLUMNS_SORTED - sorted by column
3167 -    MAT_COLUMNS_UNSORTED - not sorted by column
3168 
3169    Not these options reflect the data you pass in with MatSetValues(); it has
3170    nothing to do with how the data is stored internally in the matrix
3171    data structure.
3172 
3173    When (re)assembling a matrix, we can restrict the input for
3174    efficiency/debugging purposes.  These options include
3175 +    MAT_NO_NEW_NONZERO_LOCATIONS - additional insertions will not be
3176         allowed if they generate a new nonzero
3177 .    MAT_YES_NEW_NONZERO_LOCATIONS - additional insertions will be allowed
3178 .    MAT_NO_NEW_DIAGONALS - additional insertions will not be allowed if
3179          they generate a nonzero in a new diagonal (for block diagonal format only)
3180 .    MAT_YES_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
3181 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
3182 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
3183 -    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
3184 
3185    Notes:
3186    Some options are relevant only for particular matrix types and
3187    are thus ignored by others.  Other options are not supported by
3188    certain matrix types and will generate an error message if set.
3189 
3190    If using a Fortran 77 module to compute a matrix, one may need to
3191    use the column-oriented option (or convert to the row-oriented
3192    format).
3193 
3194    MAT_NO_NEW_NONZERO_LOCATIONS indicates that any add or insertion
3195    that would generate a new entry in the nonzero structure is instead
3196    ignored.  Thus, if memory has not alredy been allocated for this particular
3197    data, then the insertion is ignored. For dense matrices, in which
3198    the entire array is allocated, no entries are ever ignored.
3199 
3200    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
3201    that would generate a new entry in the nonzero structure instead produces
3202    an error. (Currently supported for AIJ and BAIJ formats only.)
3203    This is a useful flag when using SAME_NONZERO_PATTERN in calling
3204    SLESSetOperators() to ensure that the nonzero pattern truely does
3205    remain unchanged.
3206 
3207    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
3208    that would generate a new entry that has not been preallocated will
3209    instead produce an error. (Currently supported for AIJ and BAIJ formats
3210    only.) This is a useful flag when debugging matrix memory preallocation.
3211 
3212    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
3213    other processors should be dropped, rather than stashed.
3214    This is useful if you know that the "owning" processor is also
3215    always generating the correct matrix entries, so that PETSc need
3216    not transfer duplicate entries generated on another processor.
3217 
3218    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
3219    searches during matrix assembly. When this flag is set, the hash table
3220    is created during the first Matrix Assembly. This hash table is
3221    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
3222    to improve the searching of indices. MAT_NO_NEW_NONZERO_LOCATIONS flag
3223    should be used with MAT_USE_HASH_TABLE flag. This option is currently
3224    supported by MATMPIBAIJ format only.
3225 
3226    MAT_KEEP_ZEROED_ROWS indicates when MatZeroRows() is called the zeroed entries
3227    are kept in the nonzero structure
3228 
3229    MAT_IGNORE_ZERO_ENTRIES - when using ADD_VALUES for AIJ matrices this will stop
3230    zero values from creating a zero location in the matrix
3231 
3232    MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
3233    ROWBS matrix types
3234 
3235    MAT_DO_NOT_USE_INODES - indicates not using inode version of the code - works
3236    with AIJ and ROWBS matrix types
3237 
3238    Level: intermediate
3239 
3240    Concepts: matrices^setting options
3241 
3242 @*/
3243 int MatSetOption(Mat mat,MatOption op)
3244 {
3245   int ierr;
3246 
3247   PetscFunctionBegin;
3248   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3249   PetscValidType(mat);
3250   MatPreallocated(mat);
3251   switch (op) {
3252   case MAT_SYMMETRIC:
3253     mat->symmetric              = PETSC_TRUE;
3254     mat->structurally_symmetric = PETSC_TRUE;
3255     break;
3256   case MAT_STRUCTURALLY_SYMMETRIC:
3257     mat->structurally_symmetric = PETSC_TRUE;
3258     break;
3259   default:
3260     if (mat->ops->setoption) {ierr = (*mat->ops->setoption)(mat,op);CHKERRQ(ierr);}
3261     break;
3262   }
3263   PetscFunctionReturn(0);
3264 }
3265 
3266 #undef __FUNCT__
3267 #define __FUNCT__ "MatZeroEntries"
3268 /*@
3269    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
3270    this routine retains the old nonzero structure.
3271 
3272    Collective on Mat
3273 
3274    Input Parameters:
3275 .  mat - the matrix
3276 
3277    Level: intermediate
3278 
3279    Concepts: matrices^zeroing
3280 
3281 .seealso: MatZeroRows()
3282 @*/
3283 int MatZeroEntries(Mat mat)
3284 {
3285   int ierr;
3286 
3287   PetscFunctionBegin;
3288   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3289   PetscValidType(mat);
3290   MatPreallocated(mat);
3291   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3292   if (!mat->ops->zeroentries) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3293 
3294   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
3295   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
3296   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
3297   PetscFunctionReturn(0);
3298 }
3299 
3300 #undef __FUNCT__
3301 #define __FUNCT__ "MatZeroRows"
3302 /*@C
3303    MatZeroRows - Zeros all entries (except possibly the main diagonal)
3304    of a set of rows of a matrix.
3305 
3306    Collective on Mat
3307 
3308    Input Parameters:
3309 +  mat - the matrix
3310 .  is - index set of rows to remove
3311 -  diag - pointer to value put in all diagonals of eliminated rows.
3312           Note that diag is not a pointer to an array, but merely a
3313           pointer to a single value.
3314 
3315    Notes:
3316    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
3317    but does not release memory.  For the dense and block diagonal
3318    formats this does not alter the nonzero structure.
3319 
3320    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
3321    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
3322    merely zeroed.
3323 
3324    The user can set a value in the diagonal entry (or for the AIJ and
3325    row formats can optionally remove the main diagonal entry from the
3326    nonzero structure as well, by passing a null pointer (PETSC_NULL
3327    in C or PETSC_NULL_SCALAR in Fortran) as the final argument).
3328 
3329    For the parallel case, all processes that share the matrix (i.e.,
3330    those in the communicator used for matrix creation) MUST call this
3331    routine, regardless of whether any rows being zeroed are owned by
3332    them.
3333 
3334 
3335    Level: intermediate
3336 
3337    Concepts: matrices^zeroing rows
3338 
3339 .seealso: MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
3340 @*/
3341 int MatZeroRows(Mat mat,IS is,PetscScalar *diag)
3342 {
3343   int ierr;
3344 
3345   PetscFunctionBegin;
3346   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3347   PetscValidType(mat);
3348   MatPreallocated(mat);
3349   PetscValidHeaderSpecific(is,IS_COOKIE);
3350   if (diag) PetscValidScalarPointer(diag);
3351   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3352   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3353   if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3354 
3355   ierr = (*mat->ops->zerorows)(mat,is,diag);CHKERRQ(ierr);
3356   ierr = MatView_Private(mat);CHKERRQ(ierr);
3357   PetscFunctionReturn(0);
3358 }
3359 
3360 #undef __FUNCT__
3361 #define __FUNCT__ "MatZeroRowsLocal"
3362 /*@C
3363    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
3364    of a set of rows of a matrix; using local numbering of rows.
3365 
3366    Collective on Mat
3367 
3368    Input Parameters:
3369 +  mat - the matrix
3370 .  is - index set of rows to remove
3371 -  diag - pointer to value put in all diagonals of eliminated rows.
3372           Note that diag is not a pointer to an array, but merely a
3373           pointer to a single value.
3374 
3375    Notes:
3376    Before calling MatZeroRowsLocal(), the user must first set the
3377    local-to-global mapping by calling MatSetLocalToGlobalMapping().
3378 
3379    For the AIJ matrix formats this removes the old nonzero structure,
3380    but does not release memory.  For the dense and block diagonal
3381    formats this does not alter the nonzero structure.
3382 
3383    The user can set a value in the diagonal entry (or for the AIJ and
3384    row formats can optionally remove the main diagonal entry from the
3385    nonzero structure as well, by passing a null pointer (PETSC_NULL
3386    in C or PETSC_NULL_SCALAR in Fortran) as the final argument).
3387 
3388    Level: intermediate
3389 
3390    Concepts: matrices^zeroing
3391 
3392 .seealso: MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
3393 @*/
3394 int MatZeroRowsLocal(Mat mat,IS is,PetscScalar *diag)
3395 {
3396   int ierr;
3397   IS  newis;
3398 
3399   PetscFunctionBegin;
3400   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3401   PetscValidType(mat);
3402   MatPreallocated(mat);
3403   PetscValidHeaderSpecific(is,IS_COOKIE);
3404   if (diag) PetscValidScalarPointer(diag);
3405   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3406   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3407 
3408   if (mat->ops->zerorowslocal) {
3409     ierr = (*mat->ops->zerorowslocal)(mat,is,diag);CHKERRQ(ierr);
3410   } else {
3411     if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
3412     ierr = ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);CHKERRQ(ierr);
3413     ierr = (*mat->ops->zerorows)(mat,newis,diag);CHKERRQ(ierr);
3414     ierr = ISDestroy(newis);CHKERRQ(ierr);
3415   }
3416   PetscFunctionReturn(0);
3417 }
3418 
3419 #undef __FUNCT__
3420 #define __FUNCT__ "MatGetSize"
3421 /*@
3422    MatGetSize - Returns the numbers of rows and columns in a matrix.
3423 
3424    Not Collective
3425 
3426    Input Parameter:
3427 .  mat - the matrix
3428 
3429    Output Parameters:
3430 +  m - the number of global rows
3431 -  n - the number of global columns
3432 
3433    Level: beginner
3434 
3435    Concepts: matrices^size
3436 
3437 .seealso: MatGetLocalSize()
3438 @*/
3439 int MatGetSize(Mat mat,int *m,int* n)
3440 {
3441   PetscFunctionBegin;
3442   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3443   if (m) *m = mat->M;
3444   if (n) *n = mat->N;
3445   PetscFunctionReturn(0);
3446 }
3447 
3448 #undef __FUNCT__
3449 #define __FUNCT__ "MatGetLocalSize"
3450 /*@
3451    MatGetLocalSize - Returns the number of rows and columns in a matrix
3452    stored locally.  This information may be implementation dependent, so
3453    use with care.
3454 
3455    Not Collective
3456 
3457    Input Parameters:
3458 .  mat - the matrix
3459 
3460    Output Parameters:
3461 +  m - the number of local rows
3462 -  n - the number of local columns
3463 
3464    Level: beginner
3465 
3466    Concepts: matrices^local size
3467 
3468 .seealso: MatGetSize()
3469 @*/
3470 int MatGetLocalSize(Mat mat,int *m,int* n)
3471 {
3472   PetscFunctionBegin;
3473   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3474   if (m) *m = mat->m;
3475   if (n) *n = mat->n;
3476   PetscFunctionReturn(0);
3477 }
3478 
3479 #undef __FUNCT__
3480 #define __FUNCT__ "MatGetOwnershipRange"
3481 /*@
3482    MatGetOwnershipRange - Returns the range of matrix rows owned by
3483    this processor, assuming that the matrix is laid out with the first
3484    n1 rows on the first processor, the next n2 rows on the second, etc.
3485    For certain parallel layouts this range may not be well defined.
3486 
3487    Not Collective
3488 
3489    Input Parameters:
3490 .  mat - the matrix
3491 
3492    Output Parameters:
3493 +  m - the global index of the first local row
3494 -  n - one more than the global index of the last local row
3495 
3496    Level: beginner
3497 
3498    Concepts: matrices^row ownership
3499 @*/
3500 int MatGetOwnershipRange(Mat mat,int *m,int* n)
3501 {
3502   int ierr;
3503 
3504   PetscFunctionBegin;
3505   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3506   PetscValidType(mat);
3507   MatPreallocated(mat);
3508   if (m) PetscValidIntPointer(m);
3509   if (n) PetscValidIntPointer(n);
3510   ierr = PetscMapGetLocalRange(mat->rmap,m,n);CHKERRQ(ierr);
3511   PetscFunctionReturn(0);
3512 }
3513 
3514 #undef __FUNCT__
3515 #define __FUNCT__ "MatILUFactorSymbolic"
3516 /*@
3517    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
3518    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
3519    to complete the factorization.
3520 
3521    Collective on Mat
3522 
3523    Input Parameters:
3524 +  mat - the matrix
3525 .  row - row permutation
3526 .  column - column permutation
3527 -  info - structure containing
3528 $      levels - number of levels of fill.
3529 $      expected fill - as ratio of original fill.
3530 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
3531                 missing diagonal entries)
3532 
3533    Output Parameters:
3534 .  fact - new matrix that has been symbolically factored
3535 
3536    Notes:
3537    See the users manual for additional information about
3538    choosing the fill factor for better efficiency.
3539 
3540    Most users should employ the simplified SLES interface for linear solvers
3541    instead of working directly with matrix algebra routines such as this.
3542    See, e.g., SLESCreate().
3543 
3544    Level: developer
3545 
3546   Concepts: matrices^symbolic LU factorization
3547   Concepts: matrices^factorization
3548   Concepts: LU^symbolic factorization
3549 
3550 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
3551           MatGetOrdering(), MatILUInfo
3552 
3553 @*/
3554 int MatILUFactorSymbolic(Mat mat,IS row,IS col,MatILUInfo *info,Mat *fact)
3555 {
3556   int ierr;
3557 
3558   PetscFunctionBegin;
3559   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3560   PetscValidType(mat);
3561   MatPreallocated(mat);
3562   PetscValidPointer(fact);
3563   PetscValidHeaderSpecific(row,IS_COOKIE);
3564   PetscValidHeaderSpecific(col,IS_COOKIE);
3565   if (info && info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %d",info->levels);
3566   if (info && info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",info->fill);
3567   if (!mat->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",mat->type_name);
3568   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3569   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3570 
3571   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3572   ierr = (*mat->ops->ilufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
3573   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3574   PetscFunctionReturn(0);
3575 }
3576 
3577 #undef __FUNCT__
3578 #define __FUNCT__ "MatICCFactorSymbolic"
3579 /*@
3580    MatICCFactorSymbolic - Performs symbolic incomplete
3581    Cholesky factorization for a symmetric matrix.  Use
3582    MatCholeskyFactorNumeric() to complete the factorization.
3583 
3584    Collective on Mat
3585 
3586    Input Parameters:
3587 +  mat - the matrix
3588 .  perm - row and column permutation
3589 .  fill - levels of fill
3590 -  f - expected fill as ratio of original fill
3591 
3592    Output Parameter:
3593 .  fact - the factored matrix
3594 
3595    Notes:
3596    Currently only no-fill factorization is supported.
3597 
3598    Most users should employ the simplified SLES interface for linear solvers
3599    instead of working directly with matrix algebra routines such as this.
3600    See, e.g., SLESCreate().
3601 
3602    Level: developer
3603 
3604   Concepts: matrices^symbolic incomplete Cholesky factorization
3605   Concepts: matrices^factorization
3606   Concepts: Cholsky^symbolic factorization
3607 
3608 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor()
3609 @*/
3610 int MatICCFactorSymbolic(Mat mat,IS perm,PetscReal f,int fill,Mat *fact)
3611 {
3612   int ierr;
3613 
3614   PetscFunctionBegin;
3615   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3616   PetscValidType(mat);
3617   MatPreallocated(mat);
3618   PetscValidPointer(fact);
3619   PetscValidHeaderSpecific(perm,IS_COOKIE);
3620   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3621   if (fill < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Fill negative %d",fill);
3622   if (f < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",f);
3623   if (!mat->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",mat->type_name);
3624   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3625 
3626   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3627   ierr = (*mat->ops->iccfactorsymbolic)(mat,perm,f,fill,fact);CHKERRQ(ierr);
3628   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3629   PetscFunctionReturn(0);
3630 }
3631 
3632 #undef __FUNCT__
3633 #define __FUNCT__ "MatGetArray"
3634 /*@C
3635    MatGetArray - Returns a pointer to the element values in the matrix.
3636    The result of this routine is dependent on the underlying matrix data
3637    structure, and may not even work for certain matrix types.  You MUST
3638    call MatRestoreArray() when you no longer need to access the array.
3639 
3640    Not Collective
3641 
3642    Input Parameter:
3643 .  mat - the matrix
3644 
3645    Output Parameter:
3646 .  v - the location of the values
3647 
3648 
3649    Fortran Note:
3650    This routine is used differently from Fortran, e.g.,
3651 .vb
3652         Mat         mat
3653         PetscScalar mat_array(1)
3654         PetscOffset i_mat
3655         int         ierr
3656         call MatGetArray(mat,mat_array,i_mat,ierr)
3657 
3658   C  Access first local entry in matrix; note that array is
3659   C  treated as one dimensional
3660         value = mat_array(i_mat + 1)
3661 
3662         [... other code ...]
3663         call MatRestoreArray(mat,mat_array,i_mat,ierr)
3664 .ve
3665 
3666    See the Fortran chapter of the users manual and
3667    petsc/src/mat/examples/tests for details.
3668 
3669    Level: advanced
3670 
3671    Concepts: matrices^access array
3672 
3673 .seealso: MatRestoreArray(), MatGetArrayF90()
3674 @*/
3675 int MatGetArray(Mat mat,PetscScalar **v)
3676 {
3677   int ierr;
3678 
3679   PetscFunctionBegin;
3680   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3681   PetscValidType(mat);
3682   MatPreallocated(mat);
3683   PetscValidPointer(v);
3684   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3685   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
3686   PetscFunctionReturn(0);
3687 }
3688 
3689 #undef __FUNCT__
3690 #define __FUNCT__ "MatRestoreArray"
3691 /*@C
3692    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
3693 
3694    Not Collective
3695 
3696    Input Parameter:
3697 +  mat - the matrix
3698 -  v - the location of the values
3699 
3700    Fortran Note:
3701    This routine is used differently from Fortran, e.g.,
3702 .vb
3703         Mat         mat
3704         PetscScalar mat_array(1)
3705         PetscOffset i_mat
3706         int         ierr
3707         call MatGetArray(mat,mat_array,i_mat,ierr)
3708 
3709   C  Access first local entry in matrix; note that array is
3710   C  treated as one dimensional
3711         value = mat_array(i_mat + 1)
3712 
3713         [... other code ...]
3714         call MatRestoreArray(mat,mat_array,i_mat,ierr)
3715 .ve
3716 
3717    See the Fortran chapter of the users manual and
3718    petsc/src/mat/examples/tests for details
3719 
3720    Level: advanced
3721 
3722 .seealso: MatGetArray(), MatRestoreArrayF90()
3723 @*/
3724 int MatRestoreArray(Mat mat,PetscScalar **v)
3725 {
3726   int ierr;
3727 
3728   PetscFunctionBegin;
3729   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3730   PetscValidType(mat);
3731   MatPreallocated(mat);
3732   PetscValidPointer(v);
3733   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3734   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
3735   PetscFunctionReturn(0);
3736 }
3737 
3738 #undef __FUNCT__
3739 #define __FUNCT__ "MatGetSubMatrices"
3740 /*@C
3741    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
3742    points to an array of valid matrices, they may be reused to store the new
3743    submatrices.
3744 
3745    Collective on Mat
3746 
3747    Input Parameters:
3748 +  mat - the matrix
3749 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
3750 .  irow, icol - index sets of rows and columns to extract
3751 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
3752 
3753    Output Parameter:
3754 .  submat - the array of submatrices
3755 
3756    Notes:
3757    MatGetSubMatrices() can extract only sequential submatrices
3758    (from both sequential and parallel matrices). Use MatGetSubMatrix()
3759    to extract a parallel submatrix.
3760 
3761    When extracting submatrices from a parallel matrix, each processor can
3762    form a different submatrix by setting the rows and columns of its
3763    individual index sets according to the local submatrix desired.
3764 
3765    When finished using the submatrices, the user should destroy
3766    them with MatDestroyMatrices().
3767 
3768    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
3769    original matrix has not changed from that last call to MatGetSubMatrices().
3770 
3771    This routine creates the matrices submat; you should NOT create them before
3772    calling it.
3773 
3774    Fortran Note:
3775    The Fortran interface is slightly different from that given below; it
3776    requires one to pass in  as submat a Mat (integer) array of size at least m.
3777 
3778    Level: advanced
3779 
3780    Concepts: matrices^accessing submatrices
3781    Concepts: submatrices
3782 
3783 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal()
3784 @*/
3785 int MatGetSubMatrices(Mat mat,int n,IS *irow,IS *icol,MatReuse scall,Mat **submat)
3786 {
3787   int        ierr;
3788 
3789   PetscFunctionBegin;
3790   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3791   PetscValidType(mat);
3792   MatPreallocated(mat);
3793   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3794   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3795 
3796   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
3797   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
3798   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
3799   PetscFunctionReturn(0);
3800 }
3801 
3802 #undef __FUNCT__
3803 #define __FUNCT__ "MatDestroyMatrices"
3804 /*@C
3805    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
3806 
3807    Collective on Mat
3808 
3809    Input Parameters:
3810 +  n - the number of local matrices
3811 -  mat - the matrices
3812 
3813    Level: advanced
3814 
3815     Notes: Frees not only the matrices, but also the array that contains the matrices
3816 
3817 .seealso: MatGetSubMatrices()
3818 @*/
3819 int MatDestroyMatrices(int n,Mat **mat)
3820 {
3821   int ierr,i;
3822 
3823   PetscFunctionBegin;
3824   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %d",n);
3825   PetscValidPointer(mat);
3826   for (i=0; i<n; i++) {
3827     ierr = MatDestroy((*mat)[i]);CHKERRQ(ierr);
3828   }
3829   /* memory is allocated even if n = 0 */
3830   ierr = PetscFree(*mat);CHKERRQ(ierr);
3831   PetscFunctionReturn(0);
3832 }
3833 
3834 #undef __FUNCT__
3835 #define __FUNCT__ "MatIncreaseOverlap"
3836 /*@
3837    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
3838    replaces the index sets by larger ones that represent submatrices with
3839    additional overlap.
3840 
3841    Collective on Mat
3842 
3843    Input Parameters:
3844 +  mat - the matrix
3845 .  n   - the number of index sets
3846 .  is  - the array of pointers to index sets
3847 -  ov  - the additional overlap requested
3848 
3849    Level: developer
3850 
3851    Concepts: overlap
3852    Concepts: ASM^computing overlap
3853 
3854 .seealso: MatGetSubMatrices()
3855 @*/
3856 int MatIncreaseOverlap(Mat mat,int n,IS *is,int ov)
3857 {
3858   int ierr;
3859 
3860   PetscFunctionBegin;
3861   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3862   PetscValidType(mat);
3863   MatPreallocated(mat);
3864   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3865   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3866 
3867   if (!ov) PetscFunctionReturn(0);
3868   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3869   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
3870   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
3871   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
3872   PetscFunctionReturn(0);
3873 }
3874 
3875 #undef __FUNCT__
3876 #define __FUNCT__ "MatPrintHelp"
3877 /*@
3878    MatPrintHelp - Prints all the options for the matrix.
3879 
3880    Collective on Mat
3881 
3882    Input Parameter:
3883 .  mat - the matrix
3884 
3885    Options Database Keys:
3886 +  -help - Prints matrix options
3887 -  -h - Prints matrix options
3888 
3889    Level: developer
3890 
3891 .seealso: MatCreate(), MatCreateXXX()
3892 @*/
3893 int MatPrintHelp(Mat mat)
3894 {
3895   static PetscTruth called = PETSC_FALSE;
3896   int               ierr;
3897   MPI_Comm          comm;
3898 
3899   PetscFunctionBegin;
3900   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3901   PetscValidType(mat);
3902   MatPreallocated(mat);
3903 
3904   comm = mat->comm;
3905   if (!called) {
3906     ierr = (*PetscHelpPrintf)(comm,"General matrix options:\n");CHKERRQ(ierr);
3907     ierr = (*PetscHelpPrintf)(comm,"  -mat_view_info: view basic matrix info during MatAssemblyEnd()\n");CHKERRQ(ierr);
3908     ierr = (*PetscHelpPrintf)(comm,"  -mat_view_info_detailed: view detailed matrix info during MatAssemblyEnd()\n");CHKERRQ(ierr);
3909     ierr = (*PetscHelpPrintf)(comm,"  -mat_view_draw: draw nonzero matrix structure during MatAssemblyEnd()\n");CHKERRQ(ierr);
3910     ierr = (*PetscHelpPrintf)(comm,"      -draw_pause <sec>: set seconds of display pause\n");CHKERRQ(ierr);
3911     ierr = (*PetscHelpPrintf)(comm,"      -display <name>: set alternate display\n");CHKERRQ(ierr);
3912     called = PETSC_TRUE;
3913   }
3914   if (mat->ops->printhelp) {
3915     ierr = (*mat->ops->printhelp)(mat);CHKERRQ(ierr);
3916   }
3917   PetscFunctionReturn(0);
3918 }
3919 
3920 #undef __FUNCT__
3921 #define __FUNCT__ "MatGetBlockSize"
3922 /*@
3923    MatGetBlockSize - Returns the matrix block size; useful especially for the
3924    block row and block diagonal formats.
3925 
3926    Not Collective
3927 
3928    Input Parameter:
3929 .  mat - the matrix
3930 
3931    Output Parameter:
3932 .  bs - block size
3933 
3934    Notes:
3935    Block diagonal formats are MATSEQBDIAG, MATMPIBDIAG.
3936    Block row formats are MATSEQBAIJ, MATMPIBAIJ
3937 
3938    Level: intermediate
3939 
3940    Concepts: matrices^block size
3941 
3942 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatCreateSeqBDiag(), MatCreateMPIBDiag()
3943 @*/
3944 int MatGetBlockSize(Mat mat,int *bs)
3945 {
3946   int ierr;
3947 
3948   PetscFunctionBegin;
3949   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3950   PetscValidType(mat);
3951   MatPreallocated(mat);
3952   PetscValidIntPointer(bs);
3953   if (!mat->ops->getblocksize) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3954   ierr = (*mat->ops->getblocksize)(mat,bs);CHKERRQ(ierr);
3955   PetscFunctionReturn(0);
3956 }
3957 
3958 #undef __FUNCT__
3959 #define __FUNCT__ "MatGetRowIJ"
3960 /*@C
3961     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
3962 
3963    Collective on Mat
3964 
3965     Input Parameters:
3966 +   mat - the matrix
3967 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
3968 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
3969                 symmetrized
3970 
3971     Output Parameters:
3972 +   n - number of rows in the (possibly compressed) matrix
3973 .   ia - the row pointers
3974 .   ja - the column indices
3975 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
3976 
3977     Level: developer
3978 
3979 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
3980 @*/
3981 int MatGetRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
3982 {
3983   int ierr;
3984 
3985   PetscFunctionBegin;
3986   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3987   PetscValidType(mat);
3988   MatPreallocated(mat);
3989   if (ia) PetscValidIntPointer(ia);
3990   if (ja) PetscValidIntPointer(ja);
3991   PetscValidIntPointer(done);
3992   if (!mat->ops->getrowij) *done = PETSC_FALSE;
3993   else {
3994     *done = PETSC_TRUE;
3995     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
3996   }
3997   PetscFunctionReturn(0);
3998 }
3999 
4000 #undef __FUNCT__
4001 #define __FUNCT__ "MatGetColumnIJ"
4002 /*@C
4003     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
4004 
4005     Collective on Mat
4006 
4007     Input Parameters:
4008 +   mat - the matrix
4009 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4010 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4011                 symmetrized
4012 
4013     Output Parameters:
4014 +   n - number of columns in the (possibly compressed) matrix
4015 .   ia - the column pointers
4016 .   ja - the row indices
4017 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
4018 
4019     Level: developer
4020 
4021 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
4022 @*/
4023 int MatGetColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
4024 {
4025   int ierr;
4026 
4027   PetscFunctionBegin;
4028   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4029   PetscValidType(mat);
4030   MatPreallocated(mat);
4031   if (ia) PetscValidIntPointer(ia);
4032   if (ja) PetscValidIntPointer(ja);
4033   PetscValidIntPointer(done);
4034 
4035   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
4036   else {
4037     *done = PETSC_TRUE;
4038     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4039   }
4040   PetscFunctionReturn(0);
4041 }
4042 
4043 #undef __FUNCT__
4044 #define __FUNCT__ "MatRestoreRowIJ"
4045 /*@C
4046     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
4047     MatGetRowIJ().
4048 
4049     Collective on Mat
4050 
4051     Input Parameters:
4052 +   mat - the matrix
4053 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4054 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4055                 symmetrized
4056 
4057     Output Parameters:
4058 +   n - size of (possibly compressed) matrix
4059 .   ia - the row pointers
4060 .   ja - the column indices
4061 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
4062 
4063     Level: developer
4064 
4065 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
4066 @*/
4067 int MatRestoreRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
4068 {
4069   int ierr;
4070 
4071   PetscFunctionBegin;
4072   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4073   PetscValidType(mat);
4074   MatPreallocated(mat);
4075   if (ia) PetscValidIntPointer(ia);
4076   if (ja) PetscValidIntPointer(ja);
4077   PetscValidIntPointer(done);
4078 
4079   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
4080   else {
4081     *done = PETSC_TRUE;
4082     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4083   }
4084   PetscFunctionReturn(0);
4085 }
4086 
4087 #undef __FUNCT__
4088 #define __FUNCT__ "MatRestoreColumnIJ"
4089 /*@C
4090     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
4091     MatGetColumnIJ().
4092 
4093     Collective on Mat
4094 
4095     Input Parameters:
4096 +   mat - the matrix
4097 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4098 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4099                 symmetrized
4100 
4101     Output Parameters:
4102 +   n - size of (possibly compressed) matrix
4103 .   ia - the column pointers
4104 .   ja - the row indices
4105 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
4106 
4107     Level: developer
4108 
4109 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
4110 @*/
4111 int MatRestoreColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
4112 {
4113   int ierr;
4114 
4115   PetscFunctionBegin;
4116   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4117   PetscValidType(mat);
4118   MatPreallocated(mat);
4119   if (ia) PetscValidIntPointer(ia);
4120   if (ja) PetscValidIntPointer(ja);
4121   PetscValidIntPointer(done);
4122 
4123   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
4124   else {
4125     *done = PETSC_TRUE;
4126     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4127   }
4128   PetscFunctionReturn(0);
4129 }
4130 
4131 #undef __FUNCT__
4132 #define __FUNCT__ "MatColoringPatch"
4133 /*@C
4134     MatColoringPatch -Used inside matrix coloring routines that
4135     use MatGetRowIJ() and/or MatGetColumnIJ().
4136 
4137     Collective on Mat
4138 
4139     Input Parameters:
4140 +   mat - the matrix
4141 .   n   - number of colors
4142 -   colorarray - array indicating color for each column
4143 
4144     Output Parameters:
4145 .   iscoloring - coloring generated using colorarray information
4146 
4147     Level: developer
4148 
4149 .seealso: MatGetRowIJ(), MatGetColumnIJ()
4150 
4151 @*/
4152 int MatColoringPatch(Mat mat,int n,int ncolors,int *colorarray,ISColoring *iscoloring)
4153 {
4154   int ierr;
4155 
4156   PetscFunctionBegin;
4157   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4158   PetscValidType(mat);
4159   MatPreallocated(mat);
4160   PetscValidIntPointer(colorarray);
4161 
4162   if (!mat->ops->coloringpatch){
4163     ierr = ISColoringCreate(mat->comm,n,colorarray,iscoloring);CHKERRQ(ierr);
4164   } else {
4165     ierr = (*mat->ops->coloringpatch)(mat,n,ncolors,colorarray,iscoloring);CHKERRQ(ierr);
4166   }
4167   PetscFunctionReturn(0);
4168 }
4169 
4170 
4171 #undef __FUNCT__
4172 #define __FUNCT__ "MatSetUnfactored"
4173 /*@
4174    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
4175 
4176    Collective on Mat
4177 
4178    Input Parameter:
4179 .  mat - the factored matrix to be reset
4180 
4181    Notes:
4182    This routine should be used only with factored matrices formed by in-place
4183    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
4184    format).  This option can save memory, for example, when solving nonlinear
4185    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
4186    ILU(0) preconditioner.
4187 
4188    Note that one can specify in-place ILU(0) factorization by calling
4189 .vb
4190      PCType(pc,PCILU);
4191      PCILUSeUseInPlace(pc);
4192 .ve
4193    or by using the options -pc_type ilu -pc_ilu_in_place
4194 
4195    In-place factorization ILU(0) can also be used as a local
4196    solver for the blocks within the block Jacobi or additive Schwarz
4197    methods (runtime option: -sub_pc_ilu_in_place).  See the discussion
4198    of these preconditioners in the users manual for details on setting
4199    local solver options.
4200 
4201    Most users should employ the simplified SLES interface for linear solvers
4202    instead of working directly with matrix algebra routines such as this.
4203    See, e.g., SLESCreate().
4204 
4205    Level: developer
4206 
4207 .seealso: PCILUSetUseInPlace(), PCLUSetUseInPlace()
4208 
4209    Concepts: matrices^unfactored
4210 
4211 @*/
4212 int MatSetUnfactored(Mat mat)
4213 {
4214   int ierr;
4215 
4216   PetscFunctionBegin;
4217   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4218   PetscValidType(mat);
4219   MatPreallocated(mat);
4220   mat->factor = 0;
4221   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
4222   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
4223   PetscFunctionReturn(0);
4224 }
4225 
4226 /*MC
4227     MatGetArrayF90 - Accesses a matrix array from Fortran90.
4228 
4229     Synopsis:
4230     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
4231 
4232     Not collective
4233 
4234     Input Parameter:
4235 .   x - matrix
4236 
4237     Output Parameters:
4238 +   xx_v - the Fortran90 pointer to the array
4239 -   ierr - error code
4240 
4241     Example of Usage:
4242 .vb
4243       PetscScalar, pointer xx_v(:)
4244       ....
4245       call MatGetArrayF90(x,xx_v,ierr)
4246       a = xx_v(3)
4247       call MatRestoreArrayF90(x,xx_v,ierr)
4248 .ve
4249 
4250     Notes:
4251     Not yet supported for all F90 compilers
4252 
4253     Level: advanced
4254 
4255 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
4256 
4257     Concepts: matrices^accessing array
4258 
4259 M*/
4260 
4261 /*MC
4262     MatRestoreArrayF90 - Restores a matrix array that has been
4263     accessed with MatGetArrayF90().
4264 
4265     Synopsis:
4266     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
4267 
4268     Not collective
4269 
4270     Input Parameters:
4271 +   x - matrix
4272 -   xx_v - the Fortran90 pointer to the array
4273 
4274     Output Parameter:
4275 .   ierr - error code
4276 
4277     Example of Usage:
4278 .vb
4279        PetscScalar, pointer xx_v(:)
4280        ....
4281        call MatGetArrayF90(x,xx_v,ierr)
4282        a = xx_v(3)
4283        call MatRestoreArrayF90(x,xx_v,ierr)
4284 .ve
4285 
4286     Notes:
4287     Not yet supported for all F90 compilers
4288 
4289     Level: advanced
4290 
4291 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
4292 
4293 M*/
4294 
4295 
4296 #undef __FUNCT__
4297 #define __FUNCT__ "MatGetSubMatrix"
4298 /*@
4299     MatGetSubMatrix - Gets a single submatrix on the same number of processors
4300                       as the original matrix.
4301 
4302     Collective on Mat
4303 
4304     Input Parameters:
4305 +   mat - the original matrix
4306 .   isrow - rows this processor should obtain
4307 .   iscol - columns for all processors you wish to keep
4308 .   csize - number of columns "local" to this processor (does nothing for sequential
4309             matrices). This should match the result from VecGetLocalSize(x,...) if you
4310             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
4311 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4312 
4313     Output Parameter:
4314 .   newmat - the new submatrix, of the same type as the old
4315 
4316     Level: advanced
4317 
4318     Notes: the iscol argument MUST be the same on each processor.
4319 
4320       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
4321    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
4322    to this routine with a mat of the same nonzero structure will reuse the matrix
4323    generated the first time.
4324 
4325     Concepts: matrices^submatrices
4326 
4327 .seealso: MatGetSubMatrices()
4328 @*/
4329 int MatGetSubMatrix(Mat mat,IS isrow,IS iscol,int csize,MatReuse cll,Mat *newmat)
4330 {
4331   int     ierr, size;
4332   Mat     *local;
4333 
4334   PetscFunctionBegin;
4335   PetscValidType(mat);
4336   MatPreallocated(mat);
4337   ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr);
4338 
4339   /* if original matrix is on just one processor then use submatrix generated */
4340   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
4341     ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
4342     PetscFunctionReturn(0);
4343   } else if (!mat->ops->getsubmatrix && size == 1) {
4344     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
4345     *newmat = *local;
4346     ierr    = PetscFree(local);CHKERRQ(ierr);
4347     PetscFunctionReturn(0);
4348   }
4349 
4350   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4351   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscol,csize,cll,newmat);CHKERRQ(ierr);
4352   PetscFunctionReturn(0);
4353 }
4354 
4355 #undef __FUNCT__
4356 #define __FUNCT__ "MatGetPetscMaps"
4357 /*@C
4358    MatGetPetscMaps - Returns the maps associated with the matrix.
4359 
4360    Not Collective
4361 
4362    Input Parameter:
4363 .  mat - the matrix
4364 
4365    Output Parameters:
4366 +  rmap - the row (right) map
4367 -  cmap - the column (left) map
4368 
4369    Level: developer
4370 
4371    Concepts: maps^getting from matrix
4372 
4373 @*/
4374 int MatGetPetscMaps(Mat mat,PetscMap *rmap,PetscMap *cmap)
4375 {
4376   int ierr;
4377 
4378   PetscFunctionBegin;
4379   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4380   PetscValidType(mat);
4381   MatPreallocated(mat);
4382   ierr = (*mat->ops->getmaps)(mat,rmap,cmap);CHKERRQ(ierr);
4383   PetscFunctionReturn(0);
4384 }
4385 
4386 /*
4387       Version that works for all PETSc matrices
4388 */
4389 #undef __FUNCT__
4390 #define __FUNCT__ "MatGetPetscMaps_Petsc"
4391 int MatGetPetscMaps_Petsc(Mat mat,PetscMap *rmap,PetscMap *cmap)
4392 {
4393   PetscFunctionBegin;
4394   if (rmap) *rmap = mat->rmap;
4395   if (cmap) *cmap = mat->cmap;
4396   PetscFunctionReturn(0);
4397 }
4398 
4399 #undef __FUNCT__
4400 #define __FUNCT__ "MatSetStashInitialSize"
4401 /*@
4402    MatSetStashInitialSize - sets the sizes of the matrix stash, that is
4403    used during the assembly process to store values that belong to
4404    other processors.
4405 
4406    Not Collective
4407 
4408    Input Parameters:
4409 +  mat   - the matrix
4410 .  size  - the initial size of the stash.
4411 -  bsize - the initial size of the block-stash(if used).
4412 
4413    Options Database Keys:
4414 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
4415 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
4416 
4417    Level: intermediate
4418 
4419    Notes:
4420      The block-stash is used for values set with VecSetValuesBlocked() while
4421      the stash is used for values set with VecSetValues()
4422 
4423      Run with the option -log_info and look for output of the form
4424      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
4425      to determine the appropriate value, MM, to use for size and
4426      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
4427      to determine the value, BMM to use for bsize
4428 
4429    Concepts: stash^setting matrix size
4430    Concepts: matrices^stash
4431 
4432 @*/
4433 int MatSetStashInitialSize(Mat mat,int size, int bsize)
4434 {
4435   int ierr;
4436 
4437   PetscFunctionBegin;
4438   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4439   PetscValidType(mat);
4440   MatPreallocated(mat);
4441   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
4442   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
4443   PetscFunctionReturn(0);
4444 }
4445 
4446 #undef __FUNCT__
4447 #define __FUNCT__ "MatInterpolateAdd"
4448 /*@
4449    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
4450      the matrix
4451 
4452    Collective on Mat
4453 
4454    Input Parameters:
4455 +  mat   - the matrix
4456 .  x,y - the vectors
4457 -  w - where the result is stored
4458 
4459    Level: intermediate
4460 
4461    Notes:
4462     w may be the same vector as y.
4463 
4464     This allows one to use either the restriction or interpolation (its transpose)
4465     matrix to do the interpolation
4466 
4467     Concepts: interpolation
4468 
4469 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
4470 
4471 @*/
4472 int MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
4473 {
4474   int M,N,ierr;
4475 
4476   PetscFunctionBegin;
4477   PetscValidType(A);
4478   MatPreallocated(A);
4479   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4480   if (N > M) {
4481     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
4482   } else {
4483     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
4484   }
4485   PetscFunctionReturn(0);
4486 }
4487 
4488 #undef __FUNCT__
4489 #define __FUNCT__ "MatInterpolate"
4490 /*@
4491    MatInterpolate - y = A*x or A'*x depending on the shape of
4492      the matrix
4493 
4494    Collective on Mat
4495 
4496    Input Parameters:
4497 +  mat   - the matrix
4498 -  x,y - the vectors
4499 
4500    Level: intermediate
4501 
4502    Notes:
4503     This allows one to use either the restriction or interpolation (its transpose)
4504     matrix to do the interpolation
4505 
4506    Concepts: matrices^interpolation
4507 
4508 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
4509 
4510 @*/
4511 int MatInterpolate(Mat A,Vec x,Vec y)
4512 {
4513   int M,N,ierr;
4514 
4515   PetscFunctionBegin;
4516   PetscValidType(A);
4517   MatPreallocated(A);
4518   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4519   if (N > M) {
4520     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
4521   } else {
4522     ierr = MatMult(A,x,y);CHKERRQ(ierr);
4523   }
4524   PetscFunctionReturn(0);
4525 }
4526 
4527 #undef __FUNCT__
4528 #define __FUNCT__ "MatRestrict"
4529 /*@
4530    MatRestrict - y = A*x or A'*x
4531 
4532    Collective on Mat
4533 
4534    Input Parameters:
4535 +  mat   - the matrix
4536 -  x,y - the vectors
4537 
4538    Level: intermediate
4539 
4540    Notes:
4541     This allows one to use either the restriction or interpolation (its transpose)
4542     matrix to do the restriction
4543 
4544    Concepts: matrices^restriction
4545 
4546 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
4547 
4548 @*/
4549 int MatRestrict(Mat A,Vec x,Vec y)
4550 {
4551   int M,N,ierr;
4552 
4553   PetscFunctionBegin;
4554   PetscValidType(A);
4555   MatPreallocated(A);
4556   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4557   if (N > M) {
4558     ierr = MatMult(A,x,y);CHKERRQ(ierr);
4559   } else {
4560     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
4561   }
4562   PetscFunctionReturn(0);
4563 }
4564 
4565 #undef __FUNCT__
4566 #define __FUNCT__ "MatNullSpaceAttach"
4567 /*@C
4568    MatNullSpaceAttach - attaches a null space to a matrix.
4569         This null space will be removed from the resulting vector whenever
4570         MatMult() is called
4571 
4572    Collective on Mat
4573 
4574    Input Parameters:
4575 +  mat - the matrix
4576 -  nullsp - the null space object
4577 
4578    Level: developer
4579 
4580    Notes:
4581       Overwrites any previous null space that may have been attached
4582 
4583    Concepts: null space^attaching to matrix
4584 
4585 .seealso: MatCreate(), MatNullSpaceCreate()
4586 @*/
4587 int MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
4588 {
4589   int ierr;
4590 
4591   PetscFunctionBegin;
4592   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4593   PetscValidType(mat);
4594   MatPreallocated(mat);
4595   PetscValidHeaderSpecific(nullsp,MATNULLSPACE_COOKIE);
4596 
4597   if (mat->nullsp) {
4598     ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr);
4599   }
4600   mat->nullsp = nullsp;
4601   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
4602   PetscFunctionReturn(0);
4603 }
4604 
4605 #undef __FUNCT__
4606 #define __FUNCT__ "MatICCFactor"
4607 /*@
4608    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
4609 
4610    Collective on Mat
4611 
4612    Input Parameters:
4613 +  mat - the matrix
4614 .  row - row/column permutation
4615 .  fill - expected fill factor >= 1.0
4616 -  level - level of fill, for ICC(k)
4617 
4618    Notes:
4619    Probably really in-place only when level of fill is zero, otherwise allocates
4620    new space to store factored matrix and deletes previous memory.
4621 
4622    Most users should employ the simplified SLES interface for linear solvers
4623    instead of working directly with matrix algebra routines such as this.
4624    See, e.g., SLESCreate().
4625 
4626    Level: developer
4627 
4628    Concepts: matrices^incomplete Cholesky factorization
4629    Concepts: Cholesky factorization
4630 
4631 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
4632 @*/
4633 int MatICCFactor(Mat mat,IS row,PetscReal fill,int level)
4634 {
4635   int ierr;
4636 
4637   PetscFunctionBegin;
4638   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4639   PetscValidType(mat);
4640   MatPreallocated(mat);
4641   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
4642   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4643   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4644   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4645   ierr = (*mat->ops->iccfactor)(mat,row,fill,level);CHKERRQ(ierr);
4646   PetscFunctionReturn(0);
4647 }
4648 
4649 #undef __FUNCT__
4650 #define __FUNCT__ "MatSetValuesAdic"
4651 /*@
4652    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
4653 
4654    Not Collective
4655 
4656    Input Parameters:
4657 +  mat - the matrix
4658 -  v - the values compute with ADIC
4659 
4660    Level: developer
4661 
4662    Notes:
4663      Must call MatSetColoring() before using this routine. Also this matrix must already
4664      have its nonzero pattern determined.
4665 
4666 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
4667           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
4668 @*/
4669 int MatSetValuesAdic(Mat mat,void *v)
4670 {
4671   int ierr;
4672 
4673   PetscFunctionBegin;
4674   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4675   PetscValidType(mat);
4676 
4677   if (!mat->assembled) {
4678     SETERRQ(1,"Matrix must be already assembled");
4679   }
4680   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
4681   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4682   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
4683   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
4684   ierr = MatView_Private(mat);CHKERRQ(ierr);
4685   PetscFunctionReturn(0);
4686 }
4687 
4688 
4689 #undef __FUNCT__
4690 #define __FUNCT__ "MatSetColoring"
4691 /*@
4692    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
4693 
4694    Not Collective
4695 
4696    Input Parameters:
4697 +  mat - the matrix
4698 -  coloring - the coloring
4699 
4700    Level: developer
4701 
4702 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
4703           MatSetValues(), MatSetValuesAdic()
4704 @*/
4705 int MatSetColoring(Mat mat,ISColoring coloring)
4706 {
4707   int ierr;
4708 
4709   PetscFunctionBegin;
4710   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4711   PetscValidType(mat);
4712 
4713   if (!mat->assembled) {
4714     SETERRQ(1,"Matrix must be already assembled");
4715   }
4716   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4717   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
4718   PetscFunctionReturn(0);
4719 }
4720 
4721 #undef __FUNCT__
4722 #define __FUNCT__ "MatSetValuesAdifor"
4723 /*@
4724    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
4725 
4726    Not Collective
4727 
4728    Input Parameters:
4729 +  mat - the matrix
4730 .  nl - leading dimension of v
4731 -  v - the values compute with ADIFOR
4732 
4733    Level: developer
4734 
4735    Notes:
4736      Must call MatSetColoring() before using this routine. Also this matrix must already
4737      have its nonzero pattern determined.
4738 
4739 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
4740           MatSetValues(), MatSetColoring()
4741 @*/
4742 int MatSetValuesAdifor(Mat mat,int nl,void *v)
4743 {
4744   int ierr;
4745 
4746   PetscFunctionBegin;
4747   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4748   PetscValidType(mat);
4749 
4750   if (!mat->assembled) {
4751     SETERRQ(1,"Matrix must be already assembled");
4752   }
4753   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
4754   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4755   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
4756   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
4757   PetscFunctionReturn(0);
4758 }
4759