xref: /petsc/src/mat/interface/matrix.c (revision c43cb918d3acfb52c00c22a9a03917de7ced9c5a)
1 #ifndef lint
2 static char vcid[] = "$Id: matrix.c,v 1.144 1996/02/22 17:20:22 curfman Exp balay $";
3 #endif
4 
5 /*
6    This is where the abstract matrix operations are defined
7 */
8 
9 #include "petsc.h"
10 #include "matimpl.h"        /*I "mat.h" I*/
11 #include "vec/vecimpl.h"
12 #include "pinclude/pviewer.h"
13 #include "draw.h"
14 
15 /*@C
16    MatGetReordering - Gets a reordering for a matrix to reduce fill or to
17    improve numerical stability of LU factorization.
18 
19    Input Parameters:
20 .  mat - the matrix
21 .  type - type of reordering, one of the following:
22 $      ORDER_NATURAL - Natural
23 $      ORDER_ND - Nested Dissection
24 $      ORDER_1WD - One-way Dissection
25 $      ORDER_RCM - Reverse Cuthill-McGee
26 $      ORDER_QMD - Quotient Minimum Degree
27 
28    Output Parameters:
29 .  rperm - row permutation indices
30 .  cperm - column permutation indices
31 
32    Options Database Keys:
33    To specify the ordering through the options database, use one of
34    the following
35 $    -mat_order natural, -mat_order nd, -mat_order 1wd,
36 $    -mat_order rcm, -mat_order qmd
37 
38    Notes:
39    If the column permutations and row permutations are the same,
40    then MatGetReordering() returns 0 in cperm.
41 
42    The user can define additional orderings; see MatReorderingRegister().
43 
44 .keywords: matrix, set, ordering, factorization, direct, ILU, LU,
45            fill, reordering, natural, Nested Dissection,
46            One-way Dissection, Cholesky, Reverse Cuthill-McGee,
47            Quotient Minimum Degree
48 
49 .seealso:  MatGetReorderingTypeFromOptions(), MatReorderingRegister()
50 @*/
51 int MatGetReordering(Mat mat,MatOrdering type,IS *rperm,IS *cperm)
52 {
53   int         ierr;
54   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
55   if (!mat->assembled) SETERRQ(1,"MatGetReordering:Not for unassembled matrix");
56 
57   if (!mat->ops.getreordering) {*rperm = 0; *cperm = 0; return 0;}
58   PLogEventBegin(MAT_GetReordering,mat,0,0,0);
59   ierr = MatGetReorderingTypeFromOptions(0,&type); CHKERRQ(ierr);
60   ierr = (*mat->ops.getreordering)(mat,type,rperm,cperm); CHKERRQ(ierr);
61   PLogEventEnd(MAT_GetReordering,mat,0,0,0);
62   return 0;
63 }
64 
65 /*@C
66    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
67    for each row that you get to ensure that your application does
68    not bleed memory.
69 
70    Input Parameters:
71 .  mat - the matrix
72 .  row - the row to get
73 
74    Output Parameters:
75 .  ncols -  the number of nonzeros in the row
76 .  cols - if nonzero, the column numbers
77 .  vals - if nonzero, the values
78 
79    Notes:
80    This routine is provided for people who need to have direct access
81    to the structure of a matrix.  We hope that we provide enough
82    high-level matrix routines that few users will need it.
83 
84    For better efficiency, set cols and/or vals to zero if you do not
85    wish to extract these quantities.
86 
87 .keywords: matrix, row, get, extract
88 
89 .seealso: MatRestoreRow()
90 @*/
91 int MatGetRow(Mat mat,int row,int *ncols,int **cols,Scalar **vals)
92 {
93   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
94   if (!mat->assembled) SETERRQ(1,"MatGetRow:Not for unassembled matrix");
95   PLogEventBegin(MAT_GetRow,mat,0,0,0);
96   ierr = (*mat->ops.getrow)(mat,row,ncols,cols,vals); CHKERRQ(ierr);
97   PLogEventEnd(MAT_GetRow,mat,0,0,0);
98   return 0;
99 }
100 
101 /*@C
102    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
103 
104    Input Parameters:
105 .  mat - the matrix
106 .  row - the row to get
107 .  ncols, cols - the number of nonzeros and their columns
108 .  vals - if nonzero the column values
109 
110 .keywords: matrix, row, restore
111 
112 .seealso:  MatGetRow()
113 @*/
114 int MatRestoreRow(Mat mat,int row,int *ncols,int **cols,Scalar **vals)
115 {
116   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
117   if (!mat->assembled) SETERRQ(1,"MatRestoreRow:Not for unassembled matrix");
118   if (!mat->ops.restorerow) return 0;
119   return (*mat->ops.restorerow)(mat,row,ncols,cols,vals);
120 }
121 /*@
122    MatView - Visualizes a matrix object.
123 
124    Input Parameters:
125 .  mat - the matrix
126 .  ptr - visualization context
127 
128    Notes:
129    The available visualization contexts include
130 $     STDOUT_VIEWER_SELF - standard output (default)
131 $     STDOUT_VIEWER_WORLD - synchronized standard
132 $       output where only the first processor opens
133 $       the file.  All other processors send their
134 $       data to the first processor to print.
135 
136    The user can open alternative vistualization contexts with
137 $    ViewerFileOpenASCII() - output to a specified file
138 $    ViewerFileOpenBinary() - output in binary to a
139 $         specified file; corresponding input uses MatLoad()
140 $    DrawOpenX() - output nonzero matrix structure to
141 $         an X window display
142 $    ViewerMatlabOpen() - output matrix to Matlab viewer.
143 $         Currently only the sequential dense and AIJ
144 $         matrix types support the Matlab viewer.
145 
146    The user can call ViewerFileSetFormat() to specify the output
147    format of ASCII printed objects (when using STDOUT_VIEWER_SELF,
148    STDOUT_VIEWER_WORLD and ViewerFileOpenASCII).  Available formats include
149 $    FILE_FORMAT_DEFAULT - default, prints matrix contents
150 $    FILE_FORMAT_MATLAB - Matlab format
151 $    FILE_FORMAT_IMPL - implementation-specific format
152 $      (which is in many cases the same as the default)
153 $    FILE_FORMAT_INFO - basic information about the matrix
154 $      size and structure (not the matrix entries)
155 $    FILE_FORMAT_INFO_DETAILED - more detailed information about the
156 $      matrix structure
157 
158 .keywords: matrix, view, visualize, output, print, write, draw
159 
160 .seealso: ViewerFileSetFormat(), ViewerFileOpenASCII(), DrawOpenX(),
161           ViewerMatlabOpen(), ViewerFileOpenBinary(), MatLoad()
162 @*/
163 int MatView(Mat mat,Viewer ptr)
164 {
165   int          format, ierr, rows, cols,nz, nzalloc, mem;
166   FILE         *fd;
167   char         *cstring;
168   PetscObject  vobj = (PetscObject) ptr;
169 
170   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
171   if (!mat->assembled) SETERRQ(1,"MatView:Not for unassembled matrix");
172 
173   if (!ptr) { /* so that viewers may be used from debuggers */
174     ptr = STDOUT_VIEWER_SELF; vobj = (PetscObject) ptr;
175   }
176   ierr = ViewerFileGetFormat_Private(ptr,&format); CHKERRQ(ierr);
177   ierr = ViewerFileGetPointer(ptr,&fd); CHKERRQ(ierr);
178   if (vobj->cookie == VIEWER_COOKIE &&
179       (format == FILE_FORMAT_INFO || format == FILE_FORMAT_INFO_DETAILED) &&
180       (vobj->type == ASCII_FILE_VIEWER || vobj->type == ASCII_FILES_VIEWER)) {
181     MPIU_fprintf(mat->comm,fd,"Matrix Object:\n");
182     ierr = MatGetType(mat,PETSC_NULL,&cstring); CHKERRQ(ierr);
183     ierr = MatGetSize(mat,&rows,&cols); CHKERRQ(ierr);
184     MPIU_fprintf(mat->comm,fd,"  type=%s, rows=%d, cols=%d\n",cstring,rows,cols);
185     if (mat->ops.getinfo) {
186       ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&nz,&nzalloc,&mem); CHKERRQ(ierr);
187       MPIU_fprintf(mat->comm,fd,"  total: nonzeros=%d, allocated nonzeros=%d\n",nz,nzalloc);
188     }
189   }
190   if (mat->view) {ierr = (*mat->view)((PetscObject)mat,ptr); CHKERRQ(ierr);}
191   return 0;
192 }
193 /*@C
194    MatDestroy - Frees space taken by a matrix.
195 
196    Input Parameter:
197 .  mat - the matrix
198 
199 .keywords: matrix, destroy
200 @*/
201 int MatDestroy(Mat mat)
202 {
203   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
204   return (*mat->destroy)((PetscObject)mat);
205 }
206 /*@
207    MatValidMatrix - Checks whether a matrix object is valid.
208 
209    Input Parameter:
210 .  m - the matrix to check
211 
212    Output Parameter:
213    flg - flag indicating matrix status, either
214 $     1 if matrix is valid;
215 $     0 otherwise.
216 
217 .keywords: matrix, valid
218 @*/
219 int MatValidMatrix(Mat m,int *flg)
220 {
221   if (!m)                           *flg = 0;
222   else if (m->cookie != MAT_COOKIE) *flg = 0;
223   else                              *flg = 1;
224   return 0;
225 }
226 
227 /*@
228    MatSetValues - Inserts or adds a block of values into a matrix.
229    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
230    MUST be called after all calls to MatSetValues() have been completed.
231 
232    Input Parameters:
233 .  mat - the matrix
234 .  v - a logically two-dimensional array of values
235 .  m, indexm - the number of rows and their global indices
236 .  n, indexn - the number of columns and their global indices
237 .  addv - either ADD_VALUES or INSERT_VALUES, where
238 $     ADD_VALUES - adds values to any existing entries
239 $     INSERT_VALUES - replaces existing entries with new values
240 
241    Notes:
242    By default the values, v, are row-oriented and unsorted.
243    See MatSetOptions() for other options.
244 
245    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
246    options cannot be mixed without intervening calls to the assembly
247    routines.
248 
249 .keywords: matrix, insert, add, set, values
250 
251 .seealso: MatSetOptions(), MatAssemblyBegin(), MatAssemblyEnd()
252 @*/
253 int MatSetValues(Mat mat,int m,int *idxm,int n,int *idxn,Scalar *v,
254                                                         InsertMode addv)
255 {
256   int ierr;
257   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
258 
259   if (mat->assembled) {
260     mat->was_assembled = PETSC_TRUE;
261     mat->assembled     = PETSC_FALSE;
262     mat->same_nonzero  = PETSC_TRUE;
263   }
264 
265   PLogEventBegin(MAT_SetValues,mat,0,0,0);
266   ierr = (*mat->ops.setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
267   PLogEventEnd(MAT_SetValues,mat,0,0,0);
268   return 0;
269 }
270 
271 /*@
272    MatGetValues - Gets a block of values from a matrix.
273 
274    Input Parameters:
275 .  mat - the matrix
276 .  v - a logically two-dimensional array for storing the values
277 .  m, indexm - the number of rows and their global indices
278 .  n, indexn - the number of columns and their global indices
279 
280    Notes:
281    The user must allocate space (m*n Scalars) for the values, v.
282    The values, v, are then returned in a row-oriented format,
283    analogous to that used by default in MatSetValues().
284 
285 .keywords: matrix, get, values
286 
287 .seealso: MatGetRow(), MatGetSubmatrix(), MatGetSubmatrices(), MatSetValues()
288 @*/
289 int MatGetValues(Mat mat,int m,int *idxm,int n,int *idxn,Scalar *v)
290 {
291   int ierr;
292 
293   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
294   if (!mat->assembled) SETERRQ(1,"MatGetValues:Not for unassembled matrix");
295 
296   PLogEventBegin(MAT_GetValues,mat,0,0,0);
297   ierr = (*mat->ops.getvalues)(mat,m,idxm,n,idxn,v); CHKERRQ(ierr);
298   PLogEventEnd(MAT_GetValues,mat,0,0,0);
299   return 0;
300 }
301 
302 /* --------------------------------------------------------*/
303 /*@
304    MatMult - Computes matrix-vector product.
305 
306    Input Parameters:
307 .  mat - the matrix
308 .  x   - the vector to be multilplied
309 
310    Output Parameters:
311 .  y - the result
312 
313 .keywords: matrix, multiply, matrix-vector product
314 
315 .seealso: MatMultTrans(), MatMultAdd(), MatMultTransAdd()
316 @*/
317 int MatMult(Mat mat,Vec x,Vec y)
318 {
319   int ierr;
320   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
321   PETSCVALIDHEADERSPECIFIC(x,VEC_COOKIE);PETSCVALIDHEADERSPECIFIC(y,VEC_COOKIE);
322   if (!mat->assembled) SETERRQ(1,"MatMult:Not for unassembled matrix");
323   if (x == y) SETERRQ(1,"MatMult:x and y must be different vectors");
324 
325   PLogEventBegin(MAT_Mult,mat,x,y,0);
326   ierr = (*mat->ops.mult)(mat,x,y); CHKERRQ(ierr);
327   PLogEventEnd(MAT_Mult,mat,x,y,0);
328   return 0;
329 }
330 /*@
331    MatMultTrans - Computes matrix transpose times a vector.
332 
333    Input Parameters:
334 .  mat - the matrix
335 .  x   - the vector to be multilplied
336 
337    Output Parameters:
338 .  y - the result
339 
340 .keywords: matrix, multiply, matrix-vector product, transpose
341 
342 .seealso: MatMult(), MatMultAdd(), MatMultTransAdd()
343 @*/
344 int MatMultTrans(Mat mat,Vec x,Vec y)
345 {
346   int ierr;
347   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
348   PETSCVALIDHEADERSPECIFIC(x,VEC_COOKIE); PETSCVALIDHEADERSPECIFIC(y,VEC_COOKIE);
349   if (!mat->assembled) SETERRQ(1,"MatMultTrans:Not for unassembled matrix");
350   if (x == y) SETERRQ(1,"MatMultTrans:x and y must be different vectors");
351 
352   PLogEventBegin(MAT_MultTrans,mat,x,y,0);
353   ierr = (*mat->ops.multtrans)(mat,x,y); CHKERRQ(ierr);
354   PLogEventEnd(MAT_MultTrans,mat,x,y,0);
355   return 0;
356 }
357 /*@
358     MatMultAdd -  Computes v3 = v2 + A * v1.
359 
360   Input Parameters:
361 .    mat - the matrix
362 .    v1, v2 - the vectors
363 
364   Output Parameters:
365 .    v3 - the result
366 
367 .keywords: matrix, multiply, matrix-vector product, add
368 
369 .seealso: MatMultTrans(), MatMult(), MatMultTransAdd()
370 @*/
371 int MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
372 {
373   int ierr;
374   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);PETSCVALIDHEADERSPECIFIC(v1,VEC_COOKIE);
375   PETSCVALIDHEADERSPECIFIC(v2,VEC_COOKIE); PETSCVALIDHEADERSPECIFIC(v3,VEC_COOKIE);
376   if (!mat->assembled) SETERRQ(1,"MatMultAdd:Not for unassembled matrix");
377 
378   PLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
379   if (v1 == v3) SETERRQ(1,"MatMultAdd:v1 and v3 must be different vectors");
380   ierr = (*mat->ops.multadd)(mat,v1,v2,v3); CHKERRQ(ierr);
381   PLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
382   return 0;
383 }
384 /*@
385     MatMultTransAdd - Computes v3 = v2 + A' * v1.
386 
387   Input Parameters:
388 .    mat - the matrix
389 .    v1, v2 - the vectors
390 
391   Output Parameters:
392 .    v3 - the result
393 
394 .keywords: matrix, multiply, matrix-vector product, transpose, add
395 
396 .seealso: MatMultTrans(), MatMultAdd(), MatMult()
397 @*/
398 int MatMultTransAdd(Mat mat,Vec v1,Vec v2,Vec v3)
399 {
400   int ierr;
401   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE); PETSCVALIDHEADERSPECIFIC(v1,VEC_COOKIE);
402   PETSCVALIDHEADERSPECIFIC(v2,VEC_COOKIE); PETSCVALIDHEADERSPECIFIC(v3,VEC_COOKIE);
403   if (!mat->assembled) SETERRQ(1,"MatMultTransAdd:Not for unassembled matrix");
404   if (!mat->ops.multtransadd) SETERRQ(PETSC_ERR_SUP,"MatMultTransAdd");
405   if (v1 == v3) SETERRQ(1,"MatMultTransAdd:v1 and v2 must be different vectors");
406 
407   PLogEventBegin(MAT_MultTransAdd,mat,v1,v2,v3);
408   ierr = (*mat->ops.multtransadd)(mat,v1,v2,v3); CHKERRQ(ierr);
409   PLogEventEnd(MAT_MultTransAdd,mat,v1,v2,v3);
410   return 0;
411 }
412 /* ------------------------------------------------------------*/
413 /*@
414    MatGetInfo - Returns information about matrix storage (number of
415    nonzeros, memory).
416 
417    Input Parameters:
418 .  mat - the matrix
419 
420    Output Parameters:
421 .  flag - flag indicating the type of parameters to be returned
422 $    flag = MAT_LOCAL: local matrix
423 $    flag = MAT_GLOBAL_MAX: maximum over all processors
424 $    flag = MAT_GLOBAL_SUM: sum over all processors
425 .   nz - the number of nonzeros
426 .   nzalloc - the number of allocated nonzeros
427 .   mem - the memory used (in bytes)
428 
429 .keywords: matrix, get, info, storage, nonzeros, memory
430 @*/
431 int MatGetInfo(Mat mat,MatInfoType flag,int *nz,int *nzalloc,int *mem)
432 {
433   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
434   if (!mat->ops.getinfo) SETERRQ(PETSC_ERR_SUP,"MatGetInfo");
435   return  (*mat->ops.getinfo)(mat,flag,nz,nzalloc,mem);
436 }
437 /* ----------------------------------------------------------*/
438 /*@
439    MatLUFactor - Performs in-place LU factorization of matrix.
440 
441    Input Parameters:
442 .  mat - the matrix
443 .  row - row permutation
444 .  col - column permutation
445 .  f - expected fill as ratio of original fill.
446 
447 .keywords: matrix, factor, LU, in-place
448 
449 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
450 @*/
451 int MatLUFactor(Mat mat,IS row,IS col,double f)
452 {
453   int ierr;
454   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
455   if (!mat->ops.lufactor) SETERRQ(PETSC_ERR_SUP,"MatLUFactor");
456   if (!mat->assembled) SETERRQ(1,"MatLUFactor:Not for unassembled matrix");
457 
458   PLogEventBegin(MAT_LUFactor,mat,row,col,0);
459   ierr = (*mat->ops.lufactor)(mat,row,col,f); CHKERRQ(ierr);
460   PLogEventEnd(MAT_LUFactor,mat,row,col,0);
461   return 0;
462 }
463 /*@
464    MatILUFactor - Performs in-place ILU factorization of matrix.
465 
466    Input Parameters:
467 .  mat - the matrix
468 .  row - row permutation
469 .  col - column permutation
470 .  f - expected fill as ratio of original fill.
471 .  level - number of levels of fill.
472 
473    Note: probably really only in-place when level is zero.
474 .keywords: matrix, factor, ILU, in-place
475 
476 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
477 @*/
478 int MatILUFactor(Mat mat,IS row,IS col,double f,int level)
479 {
480   int ierr;
481   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
482   if (!mat->ops.ilufactor) SETERRQ(PETSC_ERR_SUP,"MatILUFactor");
483   if (!mat->assembled) SETERRQ(1,"MatILUFactor:Not for unassembled matrix");
484 
485   PLogEventBegin(MAT_ILUFactor,mat,row,col,0);
486   ierr = (*mat->ops.ilufactor)(mat,row,col,f,level); CHKERRQ(ierr);
487   PLogEventEnd(MAT_ILUFactor,mat,row,col,0);
488   return 0;
489 }
490 
491 /*@
492    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
493    Call this routine before calling MatLUFactorNumeric().
494 
495    Input Parameters:
496 .  mat - the matrix
497 .  row, col - row and column permutations
498 .  f - expected fill as ratio of the original number of nonzeros,
499        for example 3.0; choosing this parameter well can result in
500        more efficient use of time and space.
501 
502    Output Parameter:
503 .  fact - new matrix that has been symbolically factored
504 
505    Options Database Key:
506 $     -mat_lu_fill <f>, where f is the fill ratio
507 
508    Notes:
509    See the file $(PETSC_DIR)/Performace for additional information about
510    choosing the fill factor for better efficiency.
511 
512 .keywords: matrix, factor, LU, symbolic, fill
513 
514 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor()
515 @*/
516 int MatLUFactorSymbolic(Mat mat,IS row,IS col,double f,Mat *fact)
517 {
518   int ierr,flg;
519   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
520   if (!fact) SETERRQ(1,"MatLUFactorSymbolic:Missing factor matrix argument");
521   if (!mat->ops.lufactorsymbolic) SETERRQ(PETSC_ERR_SUP,"MatLUFactorSymbolic");
522   if (!mat->assembled) SETERRQ(1,"MatLUFactorSymbolic:Not for unassembled matrix");
523 
524   ierr = OptionsGetDouble(PETSC_NULL,"-mat_lu_fill",&f,&flg); CHKERRQ(ierr);
525   PLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
526   ierr = (*mat->ops.lufactorsymbolic)(mat,row,col,f,fact); CHKERRQ(ierr);
527   PLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
528   return 0;
529 }
530 /*@
531    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
532    Call this routine after first calling MatLUFactorSymbolic().
533 
534    Input Parameters:
535 .  mat - the matrix
536 .  row, col - row and  column permutations
537 
538    Output Parameters:
539 .  fact - symbolically factored matrix that must have been generated
540           by MatLUFactorSymbolic()
541 
542    Notes:
543    See MatLUFactor() for in-place factorization.  See
544    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
545 
546 .keywords: matrix, factor, LU, numeric
547 
548 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
549 @*/
550 int MatLUFactorNumeric(Mat mat,Mat *fact)
551 {
552   int ierr,flg;
553 
554   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
555   if (!fact) SETERRQ(1,"MatLUFactorNumeric:Missing factor matrix argument");
556   if (!mat->ops.lufactornumeric) SETERRQ(PETSC_ERR_SUP,"MatLUFactorNumeric");
557   if (!mat->assembled) SETERRQ(1,"MatLUFactorNumeric:Not for unassembled matrix");
558 
559   PLogEventBegin(MAT_LUFactorNumeric,mat,*fact,0,0);
560   ierr = (*mat->ops.lufactornumeric)(mat,fact); CHKERRQ(ierr);
561   PLogEventEnd(MAT_LUFactorNumeric,mat,*fact,0,0);
562   ierr = OptionsHasName(PETSC_NULL,"-mat_view_draw",&flg); CHKERRQ(ierr);
563   if (flg) {
564     Draw    win;
565     ierr = DrawOpenX((*fact)->comm,0,0,0,0,300,300,&win); CHKERRQ(ierr);
566     ierr = MatView(*fact,(Viewer)win); CHKERRQ(ierr);
567     ierr = DrawSyncFlush(win); CHKERRQ(ierr);
568     ierr = DrawDestroy(win); CHKERRQ(ierr);
569   }
570   return 0;
571 }
572 /*@
573    MatCholeskyFactor - Performs in-place Cholesky factorization of a
574    symmetric matrix.
575 
576    Input Parameters:
577 .  mat - the matrix
578 .  perm - row and column permutations
579 .  f - expected fill as ratio of original fill
580 
581    Notes:
582    See MatLUFactor() for the nonsymmetric case.  See also
583    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
584 
585 .keywords: matrix, factor, in-place, Cholesky
586 
587 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
588 @*/
589 int MatCholeskyFactor(Mat mat,IS perm,double f)
590 {
591   int ierr;
592   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
593   if (!mat->ops.choleskyfactor) SETERRQ(PETSC_ERR_SUP,"MatCholeskyFactor");
594   if (!mat->assembled) SETERRQ(1,"MatCholeskyFactor:Not for unassembled matrix");
595 
596   PLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
597   ierr = (*mat->ops.choleskyfactor)(mat,perm,f); CHKERRQ(ierr);
598   PLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
599   return 0;
600 }
601 /*@
602    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
603    of a symmetric matrix.
604 
605    Input Parameters:
606 .  mat - the matrix
607 .  perm - row and column permutations
608 .  f - expected fill as ratio of original
609 
610    Output Parameter:
611 .  fact - the factored matrix
612 
613    Notes:
614    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
615    MatCholeskyFactor() and MatCholeskyFactorNumeric().
616 
617 .keywords: matrix, factor, factorization, symbolic, Cholesky
618 
619 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
620 @*/
621 int MatCholeskyFactorSymbolic(Mat mat,IS perm,double f,Mat *fact)
622 {
623   int ierr;
624   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
625   if (!fact) SETERRQ(1,"MatCholeskyFactorSymbolic:Missing factor matrix argument");
626   if (!mat->ops.choleskyfactorsymbolic)SETERRQ(PETSC_ERR_SUP,"MatCholeskyFactorSymbolic");
627   if (!mat->assembled) SETERRQ(1,"MatCholeskyFactorSymbolic:Not for unassembled matrix");
628 
629   PLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
630   ierr = (*mat->ops.choleskyfactorsymbolic)(mat,perm,f,fact); CHKERRQ(ierr);
631   PLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
632   return 0;
633 }
634 /*@
635    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
636    of a symmetric matrix. Call this routine after first calling
637    MatCholeskyFactorSymbolic().
638 
639    Input Parameter:
640 .  mat - the initial matrix
641 
642    Output Parameter:
643 .  fact - the factored matrix
644 
645 .keywords: matrix, factor, numeric, Cholesky
646 
647 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
648 @*/
649 int MatCholeskyFactorNumeric(Mat mat,Mat *fact)
650 {
651   int ierr;
652   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
653   if (!fact) SETERRQ(1,"MatCholeskyFactorNumeric:Missing factor matrix argument");
654   if (!mat->ops.choleskyfactornumeric) SETERRQ(PETSC_ERR_SUP,"MatCholeskyFactorNumeric");
655   if (!mat->assembled) SETERRQ(1,"MatCholeskyFactorNumeric:Not for unassembled matrix");
656 
657   PLogEventBegin(MAT_CholeskyFactorNumeric,mat,*fact,0,0);
658   ierr = (*mat->ops.choleskyfactornumeric)(mat,fact); CHKERRQ(ierr);
659   PLogEventEnd(MAT_CholeskyFactorNumeric,mat,*fact,0,0);
660   return 0;
661 }
662 /* ----------------------------------------------------------------*/
663 /*@
664    MatSolve - Solves A x = b, given a factored matrix.
665 
666    Input Parameters:
667 .  mat - the factored matrix
668 .  b - the right-hand-side vector
669 
670    Output Parameter:
671 .  x - the result vector
672 
673 .keywords: matrix, linear system, solve, LU, Cholesky, triangular solve
674 
675 .seealso: MatSolveAdd(), MatSolveTrans(), MatSolveTransAdd()
676 @*/
677 int MatSolve(Mat mat,Vec b,Vec x)
678 {
679   int ierr;
680   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
681   PETSCVALIDHEADERSPECIFIC(b,VEC_COOKIE);  PETSCVALIDHEADERSPECIFIC(x,VEC_COOKIE);
682   if (x == b) SETERRQ(1,"MatSolve:x and y must be different vectors");
683   if (!mat->factor) SETERRQ(1,"MatSolve:Unfactored matrix");
684 
685   if (!mat->ops.solve) SETERRQ(PETSC_ERR_SUP,"MatSolve");
686   PLogEventBegin(MAT_Solve,mat,b,x,0);
687   ierr = (*mat->ops.solve)(mat,b,x); CHKERRQ(ierr);
688   PLogEventEnd(MAT_Solve,mat,b,x,0);
689   return 0;
690 }
691 
692 /* @
693    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU.
694 
695    Input Parameters:
696 .  mat - the factored matrix
697 .  b - the right-hand-side vector
698 
699    Output Parameter:
700 .  x - the result vector
701 
702    Notes:
703    MatSolve() should be used for most applications, as it performs
704    a forward solve followed by a backward solve.
705 
706 .keywords: matrix, forward, LU, Cholesky, triangular solve
707 
708 .seealso: MatSolve(), MatBackwardSolve()
709 @ */
710 int MatForwardSolve(Mat mat,Vec b,Vec x)
711 {
712   int ierr;
713   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
714   PETSCVALIDHEADERSPECIFIC(b,VEC_COOKIE);  PETSCVALIDHEADERSPECIFIC(x,VEC_COOKIE);
715   if (x == b) SETERRQ(1,"MatForwardSolve:x and y must be different vectors");
716   if (!mat->factor) SETERRQ(1,"MatForwardSolve:Unfactored matrix");
717   if (!mat->ops.forwardsolve) SETERRQ(PETSC_ERR_SUP,"MatForwardSolve");
718 
719   PLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
720   ierr = (*mat->ops.forwardsolve)(mat,b,x); CHKERRQ(ierr);
721   PLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
722   return 0;
723 }
724 
725 /* @
726    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
727 
728    Input Parameters:
729 .  mat - the factored matrix
730 .  b - the right-hand-side vector
731 
732    Output Parameter:
733 .  x - the result vector
734 
735    Notes:
736    MatSolve() should be used for most applications, as it performs
737    a forward solve followed by a backward solve.
738 
739 .keywords: matrix, backward, LU, Cholesky, triangular solve
740 
741 .seealso: MatSolve(), MatForwardSolve()
742 @ */
743 int MatBackwardSolve(Mat mat,Vec b,Vec x)
744 {
745   int ierr;
746   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
747   PETSCVALIDHEADERSPECIFIC(b,VEC_COOKIE);  PETSCVALIDHEADERSPECIFIC(x,VEC_COOKIE);
748   if (x == b) SETERRQ(1,"MatBackwardSolve:x and b must be different vectors");
749   if (!mat->factor) SETERRQ(1,"MatBackwardSolve:Unfactored matrix");
750   if (!mat->ops.backwardsolve) SETERRQ(PETSC_ERR_SUP,"MatBackwardSolve");
751 
752   PLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
753   ierr = (*mat->ops.backwardsolve)(mat,b,x); CHKERRQ(ierr);
754   PLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
755   return 0;
756 }
757 
758 /*@
759    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
760 
761    Input Parameters:
762 .  mat - the factored matrix
763 .  b - the right-hand-side vector
764 .  y - the vector to be added to
765 
766    Output Parameter:
767 .  x - the result vector
768 
769 .keywords: matrix, linear system, solve, LU, Cholesky, add
770 
771 .seealso: MatSolve(), MatSolveTrans(), MatSolveTransAdd()
772 @*/
773 int MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
774 {
775   Scalar one = 1.0;
776   Vec    tmp;
777   int    ierr;
778   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);PETSCVALIDHEADERSPECIFIC(y,VEC_COOKIE);
779   PETSCVALIDHEADERSPECIFIC(b,VEC_COOKIE);  PETSCVALIDHEADERSPECIFIC(x,VEC_COOKIE);
780   if (x == b) SETERRQ(1,"MatSolveAdd:x and b must be different vectors");
781   if (!mat->factor) SETERRQ(1,"MatSolveAdd:Unfactored matrix");
782 
783   PLogEventBegin(MAT_SolveAdd,mat,b,x,y);
784   if (mat->ops.solveadd)  {
785     ierr = (*mat->ops.solveadd)(mat,b,y,x); CHKERRQ(ierr);
786   }
787   else {
788     /* do the solve then the add manually */
789     if (x != y) {
790       ierr = MatSolve(mat,b,x); CHKERRQ(ierr);
791       ierr = VecAXPY(&one,y,x); CHKERRQ(ierr);
792     }
793     else {
794       ierr = VecDuplicate(x,&tmp); CHKERRQ(ierr);
795       PLogObjectParent(mat,tmp);
796       ierr = VecCopy(x,tmp); CHKERRQ(ierr);
797       ierr = MatSolve(mat,b,x); CHKERRQ(ierr);
798       ierr = VecAXPY(&one,tmp,x); CHKERRQ(ierr);
799       ierr = VecDestroy(tmp); CHKERRQ(ierr);
800     }
801   }
802   PLogEventEnd(MAT_SolveAdd,mat,b,x,y);
803   return 0;
804 }
805 /*@
806    MatSolveTrans - Solves A' x = b, given a factored matrix.
807 
808    Input Parameters:
809 .  mat - the factored matrix
810 .  b - the right-hand-side vector
811 
812    Output Parameter:
813 .  x - the result vector
814 
815 .keywords: matrix, linear system, solve, LU, Cholesky, transpose
816 
817 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransAdd()
818 @*/
819 int MatSolveTrans(Mat mat,Vec b,Vec x)
820 {
821   int ierr;
822   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
823   PETSCVALIDHEADERSPECIFIC(b,VEC_COOKIE);  PETSCVALIDHEADERSPECIFIC(x,VEC_COOKIE);
824   if (!mat->factor) SETERRQ(1,"MatSolveTrans:Unfactored matrix");
825   if (x == b) SETERRQ(1,"MatSolveTrans:x and b must be different vectors");
826   if (!mat->ops.solvetrans) SETERRQ(PETSC_ERR_SUP,"MatSolveTrans");
827 
828   PLogEventBegin(MAT_SolveTrans,mat,b,x,0);
829   ierr = (*mat->ops.solvetrans)(mat,b,x); CHKERRQ(ierr);
830   PLogEventEnd(MAT_SolveTrans,mat,b,x,0);
831   return 0;
832 }
833 /*@
834    MatSolveTransAdd - Computes x = y + inv(trans(A)) b, given a
835                       factored matrix.
836 
837    Input Parameters:
838 .  mat - the factored matrix
839 .  b - the right-hand-side vector
840 .  y - the vector to be added to
841 
842    Output Parameter:
843 .  x - the result vector
844 
845 .keywords: matrix, linear system, solve, LU, Cholesky, transpose, add
846 
847 .seealso: MatSolve(), MatSolveAdd(), MatSolveTrans()
848 @*/
849 int MatSolveTransAdd(Mat mat,Vec b,Vec y,Vec x)
850 {
851   Scalar one = 1.0;
852   int    ierr;
853   Vec    tmp;
854   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);PETSCVALIDHEADERSPECIFIC(y,VEC_COOKIE);
855   PETSCVALIDHEADERSPECIFIC(b,VEC_COOKIE);  PETSCVALIDHEADERSPECIFIC(x,VEC_COOKIE);
856   if (x == b) SETERRQ(1,"MatSolveTransAdd:x and b must be different vectors");
857   if (!mat->factor) SETERRQ(1,"MatSolveTransAdd:Unfactored matrix");
858 
859   PLogEventBegin(MAT_SolveTransAdd,mat,b,x,y);
860   if (mat->ops.solvetransadd) {
861     ierr = (*mat->ops.solvetransadd)(mat,b,y,x); CHKERRQ(ierr);
862   }
863   else {
864     /* do the solve then the add manually */
865     if (x != y) {
866       ierr = MatSolveTrans(mat,b,x); CHKERRQ(ierr);
867       ierr = VecAXPY(&one,y,x); CHKERRQ(ierr);
868     }
869     else {
870       ierr = VecDuplicate(x,&tmp); CHKERRQ(ierr);
871       PLogObjectParent(mat,tmp);
872       ierr = VecCopy(x,tmp); CHKERRQ(ierr);
873       ierr = MatSolveTrans(mat,b,x); CHKERRQ(ierr);
874       ierr = VecAXPY(&one,tmp,x); CHKERRQ(ierr);
875       ierr = VecDestroy(tmp); CHKERRQ(ierr);
876     }
877   }
878   PLogEventEnd(MAT_SolveTransAdd,mat,b,x,y);
879   return 0;
880 }
881 /* ----------------------------------------------------------------*/
882 
883 /*@
884    MatRelax - Computes one relaxation sweep.
885 
886    Input Parameters:
887 .  mat - the matrix
888 .  b - the right hand side
889 .  omega - the relaxation factor
890 .  flag - flag indicating the type of SOR, one of
891 $     SOR_FORWARD_SWEEP
892 $     SOR_BACKWARD_SWEEP
893 $     SOR_SYMMETRIC_SWEEP (SSOR method)
894 $     SOR_LOCAL_FORWARD_SWEEP
895 $     SOR_LOCAL_BACKWARD_SWEEP
896 $     SOR_LOCAL_SYMMETRIC_SWEEP (local SSOR)
897 $     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
898 $       upper/lower triangular part of matrix to
899 $       vector (with omega)
900 $     SOR_ZERO_INITIAL_GUESS - zero initial guess
901 .  shift -  diagonal shift
902 .  its - the number of iterations
903 
904    Output Parameters:
905 .  x - the solution (can contain an initial guess)
906 
907    Notes:
908    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
909    SOR_LOCAL_SYMMETRIC_SWEEP perform seperate independent smoothings
910    on each processor.
911 
912    Application programmers will not generally use MatRelax() directly,
913    but instead will employ the SLES/PC interface.
914 
915    Notes for Advanced Users:
916    The flags are implemented as bitwise inclusive or operations.
917    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
918    to specify a zero initial guess for SSOR.
919 
920 .keywords: matrix, relax, relaxation, sweep
921 @*/
922 int MatRelax(Mat mat,Vec b,double omega,MatSORType flag,double shift,
923              int its,Vec x)
924 {
925   int ierr;
926   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
927   PETSCVALIDHEADERSPECIFIC(b,VEC_COOKIE);  PETSCVALIDHEADERSPECIFIC(x,VEC_COOKIE);
928   if (!mat->ops.relax) SETERRQ(PETSC_ERR_SUP,"MatRelax");
929   if (!mat->assembled) SETERRQ(1,"MatRelax:Not for unassembled matrix");
930 
931   PLogEventBegin(MAT_Relax,mat,b,x,0);
932   ierr =(*mat->ops.relax)(mat,b,omega,flag,shift,its,x); CHKERRQ(ierr);
933   PLogEventEnd(MAT_Relax,mat,b,x,0);
934   return 0;
935 }
936 
937 /*
938       Default matrix copy routine.
939 */
940 int MatCopy_Basic(Mat A,Mat B)
941 {
942   int    ierr,i,rstart,rend,nz,*cwork;
943   Scalar *vwork;
944 
945   ierr = MatZeroEntries(B); CHKERRQ(ierr);
946   ierr = MatGetOwnershipRange(A,&rstart,&rend); CHKERRQ(ierr);
947   for (i=rstart; i<rend; i++) {
948     ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
949     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
950     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
951   }
952   ierr = MatAssemblyBegin(B,FINAL_ASSEMBLY); CHKERRQ(ierr);
953   ierr = MatAssemblyEnd(B,FINAL_ASSEMBLY); CHKERRQ(ierr);
954   return 0;
955 }
956 
957 /*@C
958    MatCopy - Copys a matrix to another matrix.
959 
960    Input Parameters:
961 .  A - the matrix
962 
963    Output Parameter:
964 .  B - where the copy is put
965 
966    Notes:
967    MatCopy() copies the matrix entries of a matrix to another existing
968    matrix (after first zeroing the second matrix).  A related routine is
969    MatConvert(), which first creates a new matrix and then copies the data.
970 
971 .keywords: matrix, copy, convert
972 
973 .seealso: MatConvert()
974 @*/
975 int MatCopy(Mat A,Mat B)
976 {
977   int ierr;
978   PETSCVALIDHEADERSPECIFIC(A,MAT_COOKIE);PETSCVALIDHEADERSPECIFIC(B,MAT_COOKIE);
979   if (!A->assembled) SETERRQ(1,"MatCopy:Not for unassembled matrix");
980 
981   PLogEventBegin(MAT_Copy,A,B,0,0);
982   if (A->ops.copy) {
983     ierr = (*A->ops.copy)(A,B); CHKERRQ(ierr);
984   }
985   else { /* generic conversion */
986     ierr = MatCopy_Basic(A,B); CHKERRQ(ierr);
987   }
988   PLogEventEnd(MAT_Copy,A,B,0,0);
989   return 0;
990 }
991 
992 /*@C
993    MatConvert - Converts a matrix to another matrix, either of the same
994    or different type.
995 
996    Input Parameters:
997 .  mat - the matrix
998 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
999    same type as the original matrix.
1000 
1001    Output Parameter:
1002 .  M - pointer to place new matrix
1003 
1004    Notes:
1005    MatConvert() first creates a new matrix and then copies the data from
1006    the first matrix.  A related routine is MatCopy(), which copies the matrix
1007    entries of one matrix to another already existing matrix context.
1008 
1009 .keywords: matrix, copy, convert
1010 
1011 .seealso: MatCopy()
1012 @*/
1013 int MatConvert(Mat mat,MatType newtype,Mat *M)
1014 {
1015   int ierr;
1016   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
1017   if (!M) SETERRQ(1,"MatConvert:Bad new matrix address");
1018   if (!mat->assembled) SETERRQ(1,"MatConvert:Not for unassembled matrix");
1019 
1020   PLogEventBegin(MAT_Convert,mat,0,0,0);
1021   if (newtype == mat->type || newtype == MATSAME) {
1022     if (mat->ops.convertsametype) { /* customized copy */
1023       ierr = (*mat->ops.convertsametype)(mat,M,COPY_VALUES); CHKERRQ(ierr);
1024     }
1025   }
1026   else if (mat->ops.convert) { /* customized conversion */
1027     ierr = (*mat->ops.convert)(mat,newtype,M); CHKERRQ(ierr);
1028   }
1029   else { /* generic conversion */
1030     ierr = MatConvert_Basic(mat,newtype,M); CHKERRQ(ierr);
1031   }
1032   PLogEventEnd(MAT_Convert,mat,0,0,0);
1033   return 0;
1034 }
1035 
1036 /*@
1037    MatGetDiagonal - Gets the diagonal of a matrix.
1038 
1039    Input Parameters:
1040 .  mat - the matrix
1041 
1042    Output Parameters:
1043 .  v - the vector for storing the diagonal
1044 
1045 .keywords: matrix, get, diagonal
1046 @*/
1047 int MatGetDiagonal(Mat mat,Vec v)
1048 {
1049   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);PETSCVALIDHEADERSPECIFIC(v,VEC_COOKIE);
1050   if (!mat->assembled) SETERRQ(1,"MatGetDiagonal:Not for unassembled matrix");
1051   if (mat->ops.getdiagonal) return (*mat->ops.getdiagonal)(mat,v);
1052   SETERRQ(PETSC_ERR_SUP,"MatGetDiagonal");
1053 }
1054 
1055 /*@C
1056    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
1057 
1058    Input Parameters:
1059 .  mat - the matrix to transpose
1060 
1061    Output Parameters:
1062 .  B - the transpose (or pass in PETSC_NULL for an in-place transpose)
1063 
1064 .keywords: matrix, transpose
1065 @*/
1066 int MatTranspose(Mat mat,Mat *B)
1067 {
1068   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
1069   if (!mat->assembled) SETERRQ(1,"MatTranspose:Not for unassembled matrix");
1070   if (mat->ops.transpose) return (*mat->ops.transpose)(mat,B);
1071   SETERRQ(PETSC_ERR_SUP,"MatTranspose");
1072 }
1073 
1074 /*@
1075    MatEqual - Compares two matrices.  Returns 1 if two matrices are equal.
1076 
1077    Input Parameters:
1078 .  mat1 - the first matrix
1079 .  mat2 - the second matrix
1080 
1081    Output Parameter:
1082 .  flg : 1 if the matrices are equal;
1083          0 otherwise.
1084 
1085 .keywords: matrix, equal, equivalent
1086 @*/
1087 int MatEqual(Mat mat1,Mat mat2,int *flg)
1088 {
1089   PETSCVALIDHEADERSPECIFIC(mat1,MAT_COOKIE); PETSCVALIDHEADERSPECIFIC(mat2,MAT_COOKIE);
1090   if (!mat1->assembled) SETERRQ(1,"MatEqual:Not for unassembled matrix");
1091   if (!mat2->assembled) SETERRQ(1,"MatEqual:Not for unassembled matrix");
1092   if (mat1->ops.equal) return (*mat1->ops.equal)(mat1,mat2, flg);
1093   SETERRQ(PETSC_ERR_SUP,"MatEqual");
1094 }
1095 
1096 /*@
1097    MatDiagonalScale - Scales a matrix on the left and right by diagonal
1098    matrices that are stored as vectors.  Either of the two scaling
1099    matrices can be null.
1100 
1101    Input Parameters:
1102 .  mat - the matrix to be scaled
1103 .  l - the left scaling vector
1104 .  r - the right scaling vector
1105 
1106 .keywords: matrix, scale
1107 @*/
1108 int MatDiagonalScale(Mat mat,Vec l,Vec r)
1109 {
1110   int ierr;
1111   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
1112   if (!mat->ops.scale) SETERRQ(PETSC_ERR_SUP,"MatDiagonalScale");
1113   if (l) PETSCVALIDHEADERSPECIFIC(l,VEC_COOKIE);
1114   if (r) PETSCVALIDHEADERSPECIFIC(r,VEC_COOKIE);
1115   if (!mat->assembled) SETERRQ(1,"MatDiagonalScale:Not for unassembled matrix");
1116 
1117   PLogEventBegin(MAT_Scale,mat,0,0,0);
1118   ierr = (*mat->ops.diagonalscale)(mat,l,r); CHKERRQ(ierr);
1119   PLogEventEnd(MAT_Scale,mat,0,0,0);
1120   return 0;
1121 }
1122 
1123 /*@
1124    MatScale - Scales a matrix by a number.
1125 
1126    Input Parameters:
1127 .  mat - the matrix to be scaled
1128 .   a  - the number
1129 
1130    Note: the name of this routine MUST change.
1131 .keywords: matrix, scale
1132 @*/
1133 int MatScale(Scalar *a,Mat mat)
1134 {
1135   int ierr;
1136   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
1137   if (!mat->ops.scale) SETERRQ(PETSC_ERR_SUP,"MatScale");
1138   if (!mat->assembled) SETERRQ(1,"MatScale:Not for unassembled matrix");
1139 
1140   PLogEventBegin(MAT_Scale,mat,0,0,0);
1141   ierr = (*mat->ops.scale)(a,mat); CHKERRQ(ierr);
1142   PLogEventEnd(MAT_Scale,mat,0,0,0);
1143   return 0;
1144 }
1145 
1146 /*@
1147    MatNorm - Calculates various norms of a matrix.
1148 
1149    Input Parameters:
1150 .  mat - the matrix
1151 .  type - the type of norm, NORM_1, NORM_2, NORM_FROBENIUS, NORM_INFINITY
1152 
1153    Output Parameters:
1154 .  norm - the resulting norm
1155 
1156 .keywords: matrix, norm, Frobenius
1157 @*/
1158 int MatNorm(Mat mat,NormType type,double *norm)
1159 {
1160   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
1161   if (!norm) SETERRQ(1,"MatNorm:bad addess for value");
1162   if (!mat->assembled) SETERRQ(1,"MatNorm:Not for unassembled matrix");
1163   if (mat->ops.norm) return (*mat->ops.norm)(mat,type,norm);
1164   SETERRQ(PETSC_ERR_SUP,"MatNorm:Not for this matrix type");
1165 }
1166 
1167 /*@
1168    MatAssemblyBegin - Begins assembling the matrix.  This routine should
1169    be called after completing all calls to MatSetValues().
1170 
1171    Input Parameters:
1172 .  mat - the matrix
1173 .  type - type of assembly, either FLUSH_ASSEMBLY or FINAL_ASSEMBLY
1174 
1175    Notes:
1176    MatSetValues() generally caches the values.  The matrix is ready to
1177    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
1178    Use FLUSH_ASSEMBLY when switching between ADD_VALUES and SetValues; use
1179    FINAL_ASSEMBLY for the final assembly before the matrix is used.
1180 
1181 .keywords: matrix, assembly, assemble, begin
1182 
1183 .seealso: MatAssemblyEnd(), MatSetValues()
1184 @*/
1185 int MatAssemblyBegin(Mat mat,MatAssemblyType type)
1186 {
1187   int ierr;
1188   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
1189   PLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
1190   if (mat->ops.assemblybegin){ierr = (*mat->ops.assemblybegin)(mat,type);CHKERRQ(ierr);}
1191   PLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
1192   return 0;
1193 }
1194 
1195 /*@
1196    MatAssemblyEnd - Completes assembling the matrix.  This routine should
1197    be called after all calls to MatSetValues() and after MatAssemblyBegin().
1198 
1199    Input Parameters:
1200 .  mat - the matrix
1201 .  type - type of assembly, either FLUSH_ASSEMBLY or FINAL_ASSEMBLY
1202 
1203    Options Database Keys:
1204 $  -mat_view_draw : Draw nonzero structure of matrix at conclusion of MatEndAssembly(),
1205                using MatView() and DrawOpenX().
1206 $  -mat_view_info : Prints info on matrix.
1207 $  -mat_view_info_detailed: More detailed information.
1208 $  -mat_view : Prints matrix out in ascii.
1209 $  -mat_view_matlab : Prints matrix out suitable for Matlab(TM).
1210 $  -display <name> : Set display name (default is host)
1211 $  -draw_pause <sec> : Set number of seconds to pause after display
1212 
1213    Note:
1214    MatSetValues() generally caches the values.  The matrix is ready to
1215    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
1216    Use FLUSH_ASSEMBLY when switching between ADD_VALUES and SetValues; use
1217    FINAL_ASSEMBLY for the final assembly before the matrix is used.
1218 
1219 .keywords: matrix, assembly, assemble, end
1220 
1221 .seealso: MatAssemblyBegin(), MatSetValues()
1222 @*/
1223 int MatAssemblyEnd(Mat mat,MatAssemblyType type)
1224 {
1225   int        ierr,flg;
1226   static int inassm = 0;
1227 
1228   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
1229   inassm++;
1230   PLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
1231   if (mat->ops.assemblyend) {ierr = (*mat->ops.assemblyend)(mat,type); CHKERRQ(ierr);}
1232   mat->assembled = PETSC_TRUE; mat->num_ass++;
1233   PLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
1234 
1235   if (inassm == 1) {
1236     ierr = OptionsHasName(PETSC_NULL,"-mat_view_info",&flg); CHKERRQ(ierr);
1237     if (flg) {
1238       Viewer viewer;
1239       ierr = ViewerFileOpenASCII(mat->comm,"stdout",&viewer);CHKERRQ(ierr);
1240       ierr = ViewerFileSetFormat(viewer,FILE_FORMAT_INFO,0);CHKERRQ(ierr);
1241       ierr = MatView(mat,viewer); CHKERRQ(ierr);
1242       ierr = ViewerDestroy(viewer); CHKERRQ(ierr);
1243     }
1244     ierr = OptionsHasName(PETSC_NULL,"-mat_view_info_detailed",&flg); CHKERRQ(ierr);
1245     if (flg) {
1246       Viewer viewer;
1247       ierr = ViewerFileOpenASCII(mat->comm,"stdout",&viewer);CHKERRQ(ierr);
1248       ierr = ViewerFileSetFormat(viewer,FILE_FORMAT_INFO_DETAILED,0);CHKERRQ(ierr);
1249       ierr = MatView(mat,viewer); CHKERRQ(ierr);
1250       ierr = ViewerDestroy(viewer); CHKERRQ(ierr);
1251     }
1252     ierr = OptionsHasName(PETSC_NULL,"-mat_view",&flg); CHKERRQ(ierr);
1253     if (flg) {
1254       Viewer viewer;
1255       ierr = ViewerFileOpenASCII(mat->comm,"stdout",&viewer);CHKERRQ(ierr);
1256       ierr = MatView(mat,viewer); CHKERRQ(ierr);
1257       ierr = ViewerDestroy(viewer); CHKERRQ(ierr);
1258     }
1259     ierr = OptionsHasName(PETSC_NULL,"-mat_view_matlab",&flg); CHKERRQ(ierr);
1260     if (flg) {
1261       Viewer viewer;
1262       ierr = ViewerFileOpenASCII(mat->comm,"stdout",&viewer);CHKERRQ(ierr);
1263       ierr = ViewerFileSetFormat(viewer,FILE_FORMAT_MATLAB,"M");CHKERRQ(ierr);
1264       ierr = MatView(mat,viewer); CHKERRQ(ierr);
1265       ierr = ViewerDestroy(viewer); CHKERRQ(ierr);
1266     }
1267     ierr = OptionsHasName(PETSC_NULL,"-mat_view_draw",&flg); CHKERRQ(ierr);
1268     if (flg) {
1269       Draw    win;
1270       ierr = DrawOpenX(mat->comm,0,0,0,0,300,300,&win); CHKERRQ(ierr);
1271       ierr = MatView(mat,(Viewer)win); CHKERRQ(ierr);
1272       ierr = DrawSyncFlush(win); CHKERRQ(ierr);
1273       ierr = DrawDestroy(win); CHKERRQ(ierr);
1274     }
1275   }
1276   inassm--;
1277   return 0;
1278 }
1279 
1280 /*@
1281    MatCompress - Tries to store the matrix in as little space as
1282    possible.  May fail if memory is already fully used, since it
1283    tries to allocate new space.
1284 
1285    Input Parameters:
1286 .  mat - the matrix
1287 
1288 .keywords: matrix, compress
1289 @*/
1290 int MatCompress(Mat mat)
1291 {
1292   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
1293   if (mat->ops.compress) return (*mat->ops.compress)(mat);
1294   return 0;
1295 }
1296 /*@
1297    MatSetOption - Sets a parameter option for a matrix. Some options
1298    may be specific to certain storage formats.  Some options
1299    determine how values will be inserted (or added). Sorted,
1300    row-oriented input will generally assemble the fastest. The default
1301    is row-oriented, nonsorted input.
1302 
1303    Input Parameters:
1304 .  mat - the matrix
1305 .  option - the option, one of the following:
1306 $    ROW_ORIENTED
1307 $    COLUMN_ORIENTED,
1308 $    ROWS_SORTED,
1309 $    COLUMNS_SORTED,
1310 $    NO_NEW_NONZERO_LOCATIONS,
1311 $    YES_NEW_NONZERO_LOCATIONS,
1312 $    SYMMETRIC_MATRIX,
1313 $    STRUCTURALLY_SYMMETRIC_MATRIX,
1314 $    NO_NEW_DIAGONALS,
1315 $    YES_NEW_DIAGONALS,
1316 $    and possibly others.
1317 
1318    Notes:
1319    Some options are relevant only for particular matrix types and
1320    are thus ignored by others.  Other options are not supported by
1321    certain matrix types and will generate an error message if set.
1322 
1323    If using a Fortran 77 module to compute a matrix, one may need to
1324    use the column-oriented option (or convert to the row-oriented
1325    format).
1326 
1327    NO_NEW_NONZERO_LOCATIONS indicates that any add or insertion
1328    that will generate a new entry in the nonzero structure is ignored.
1329    What this means is if memory is not allocated for this particular
1330    lot, then the insertion is ignored. For dense matrices, where
1331    the entire array is allocated, no entries are ever ignored.
1332 
1333 .keywords: matrix, option, row-oriented, column-oriented, sorted, nonzero
1334 @*/
1335 int MatSetOption(Mat mat,MatOption op)
1336 {
1337   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
1338   if (mat->ops.setoption) return (*mat->ops.setoption)(mat,op);
1339   return 0;
1340 }
1341 
1342 /*@
1343    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
1344    this routine retains the old nonzero structure.
1345 
1346    Input Parameters:
1347 .  mat - the matrix
1348 
1349 .keywords: matrix, zero, entries
1350 
1351 .seealso: MatZeroRows()
1352 @*/
1353 int MatZeroEntries(Mat mat)
1354 {
1355   int ierr;
1356   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
1357   if (!mat->ops.zeroentries) SETERRQ(PETSC_ERR_SUP,"MatZeroEntries");
1358 
1359   PLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
1360   ierr = (*mat->ops.zeroentries)(mat); CHKERRQ(ierr);
1361   PLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
1362   return 0;
1363 }
1364 
1365 /*@
1366    MatZeroRows - Zeros all entries (except possibly the main diagonal)
1367    of a set of rows of a matrix.
1368 
1369    Input Parameters:
1370 .  mat - the matrix
1371 .  is - index set of rows to remove
1372 .  diag - pointer to value put in all diagonals of eliminated rows.
1373           Note that diag is not a pointer to an array, but merely a
1374           pointer to a single value.
1375 
1376    Notes:
1377    For the AIJ matrix formats this removes the old nonzero structure,
1378    but does not release memory.  For the dense and block diagonal
1379    formats this does not alter the nonzero structure.
1380 
1381    The user can set a value in the diagonal entry (or for the AIJ and
1382    row formats can optionally remove the main diagonal entry from the
1383    nonzero structure as well, by passing a null pointer as the final
1384    argument).
1385 
1386 .keywords: matrix, zero, rows, boundary conditions
1387 
1388 .seealso: MatZeroEntries(), MatGetSubMatrix(), MatGetSubMatrixInPlace()
1389 @*/
1390 int MatZeroRows(Mat mat,IS is, Scalar *diag)
1391 {
1392   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
1393   if (!mat->assembled) SETERRQ(1,"MatZeroRows:Not for unassembled matrix");
1394   if (mat->ops.zerorows) return (*mat->ops.zerorows)(mat,is,diag);
1395   SETERRQ(PETSC_ERR_SUP,"MatZeroRows");
1396 }
1397 
1398 /*@
1399    MatGetSize - Returns the numbers of rows and columns in a matrix.
1400 
1401    Input Parameter:
1402 .  mat - the matrix
1403 
1404    Output Parameters:
1405 .  m - the number of global rows
1406 .  n - the number of global columns
1407 
1408 .keywords: matrix, dimension, size, rows, columns, global, get
1409 
1410 .seealso: MatGetLocalSize()
1411 @*/
1412 int MatGetSize(Mat mat,int *m,int* n)
1413 {
1414   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
1415   if (!m || !n) SETERRQ(1,"MatGetSize:Bad address for result");
1416   return (*mat->ops.getsize)(mat,m,n);
1417 }
1418 
1419 /*@
1420    MatGetLocalSize - Returns the number of rows and columns in a matrix
1421    stored locally.  This information may be implementation dependent, so
1422    use with care.
1423 
1424    Input Parameters:
1425 .  mat - the matrix
1426 
1427    Output Parameters:
1428 .  m - the number of local rows
1429 .  n - the number of local columns
1430 
1431 .keywords: matrix, dimension, size, local, rows, columns, get
1432 
1433 .seealso: MatGetSize()
1434 @*/
1435 int MatGetLocalSize(Mat mat,int *m,int* n)
1436 {
1437   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
1438   if (!m || !n) SETERRQ(1,"MatGetLocalSize:Bad address for result");
1439   return (*mat->ops.getlocalsize)(mat,m,n);
1440 }
1441 
1442 /*@
1443    MatGetOwnershipRange - Returns the range of matrix rows owned by
1444    this processor, assuming that the matrix is laid out with the first
1445    n1 rows on the first processor, the next n2 rows on the second, etc.
1446    For certain parallel layouts this range may not be well-defined.
1447 
1448    Input Parameters:
1449 .  mat - the matrix
1450 
1451    Output Parameters:
1452 .  m - the first local row
1453 .  n - one more then the last local row
1454 
1455 .keywords: matrix, get, range, ownership
1456 @*/
1457 int MatGetOwnershipRange(Mat mat,int *m,int* n)
1458 {
1459   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
1460   if (!m || !n) SETERRQ(1,"MatGetOwnershipRange:Bad address for result");
1461   if (mat->ops.getownershiprange) return (*mat->ops.getownershiprange)(mat,m,n);
1462   SETERRQ(PETSC_ERR_SUP,"MatGetOwnershipRange");
1463 }
1464 
1465 /*@
1466    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
1467    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
1468    to complete the factorization.
1469 
1470    Input Parameters:
1471 .  mat - the matrix
1472 .  row - row permutation
1473 .  column - column permutation
1474 .  fill - number of levels of fill
1475 .  f - expected fill as ratio of the original number of nonzeros,
1476        for example 3.0; choosing this parameter well can result in
1477        more efficient use of time and space.
1478 
1479    Output Parameters:
1480 .  fact - new matrix that has been symbolically factored
1481 
1482    Options Database Key:
1483 $   -mat_ilu_fill <f>, where f is the fill ratio
1484 
1485    Notes:
1486    See the file $(PETSC_DIR)/Performace for additional information about
1487    choosing the fill factor for better efficiency.
1488 
1489 .keywords: matrix, factor, incomplete, ILU, symbolic, fill
1490 
1491 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric()
1492 @*/
1493 int MatILUFactorSymbolic(Mat mat,IS row,IS col,double f,int fill,Mat *fact)
1494 {
1495   int ierr,flg;
1496 
1497   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
1498   if (fill < 0) SETERRQ(1,"MatILUFactorSymbolic:Levels of fill negative");
1499   if (!fact) SETERRQ(1,"MatILUFactorSymbolic:Fact argument is missing");
1500   if (!mat->ops.ilufactorsymbolic) SETERRQ(PETSC_ERR_SUP,"MatILUFactorSymbolic");
1501   if (!mat->assembled) SETERRQ(1,"MatILUFactorSymbolic:Not for unassembled matrix");
1502 
1503   ierr = OptionsGetDouble(PETSC_NULL,"-mat_ilu_fill",&f,&flg); CHKERRQ(ierr);
1504   PLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
1505   ierr = (*mat->ops.ilufactorsymbolic)(mat,row,col,f,fill,fact); CHKERRQ(ierr);
1506   PLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
1507   return 0;
1508 }
1509 
1510 /*@
1511    MatIncompleteCholeskyFactorSymbolic - Performs symbolic incomplete
1512    Cholesky factorization for a symmetric matrix.  Use
1513    MatCholeskyFactorNumeric() to complete the factorization.
1514 
1515    Input Parameters:
1516 .  mat - the matrix
1517 .  perm - row and column permutation
1518 .  fill - levels of fill
1519 .  f - expected fill as ratio of original fill
1520 
1521    Output Parameter:
1522 .  fact - the factored matrix
1523 
1524    Note:  Currently only no-fill factorization is supported.
1525 
1526 .keywords: matrix, factor, incomplete, ICC, Cholesky, symbolic, fill
1527 
1528 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor()
1529 @*/
1530 int MatIncompleteCholeskyFactorSymbolic(Mat mat,IS perm,double f,int fill,
1531                                         Mat *fact)
1532 {
1533   int ierr;
1534   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
1535   if (fill < 0) SETERRQ(1,"MatIncompleteCholeskyFactorSymbolic:Fill negative");
1536   if (!fact) SETERRQ(1,"MatIncompleteCholeskyFactorSymbolic:Missing fact argument");
1537   if (!mat->ops.incompletecholeskyfactorsymbolic)
1538      SETERRQ(PETSC_ERR_SUP,"MatIncompleteCholeskyFactorSymbolic");
1539   if (!mat->assembled)
1540      SETERRQ(1,"MatIncompleteCholeskyFactorSymbolic:Not for unassembled matrix");
1541 
1542   PLogEventBegin(MAT_IncompleteCholeskyFactorSymbolic,mat,perm,0,0);
1543   ierr = (*mat->ops.incompletecholeskyfactorsymbolic)(mat,perm,f,fill,fact);CHKERRQ(ierr);
1544   PLogEventEnd(MAT_IncompleteCholeskyFactorSymbolic,mat,perm,0,0);
1545   return 0;
1546 }
1547 
1548 /*@C
1549    MatGetArray - Returns a pointer to the element values in the matrix.
1550    This routine  is implementation dependent, and may not even work for
1551    certain matrix types.
1552 
1553    Input Parameter:
1554 .  mat - the matrix
1555 
1556    Output Parameter:
1557 .  v - the location of the values
1558 
1559    Fortran Note:
1560    The Fortran interface is slightly different from that given below.
1561    See the users manual and petsc/src/mat/examples for details.
1562 
1563 .keywords: matrix, array, elements, values
1564 @*/
1565 int MatGetArray(Mat mat,Scalar **v)
1566 {
1567   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
1568   if (!v) SETERRQ(1,"MatGetArray:Bad input, array pointer location");
1569   if (!mat->ops.getarray) SETERRQ(PETSC_ERR_SUP,"MatGetArraye");
1570   return (*mat->ops.getarray)(mat,v);
1571 }
1572 
1573 /*@C
1574    MatGetSubMatrix - Extracts a submatrix from a matrix. If submat points
1575                      to a valid matrix, it may be reused.
1576 
1577    Input Parameters:
1578 .  mat - the matrix
1579 .  irow, icol - index sets of rows and columns to extract
1580 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
1581 
1582    Output Parameter:
1583 .  submat - the submatrix
1584 
1585    Notes:
1586    MatGetSubMatrix() can be useful in setting boundary conditions.
1587 
1588    Use MatGetSubMatrices() to extract multiple submatrices.
1589 
1590 .keywords: matrix, get, submatrix, boundary conditions
1591 
1592 .seealso: MatZeroRows(), MatGetSubMatrixInPlace(), MatGetSubMatrices()
1593 @*/
1594 int MatGetSubMatrix(Mat mat,IS irow,IS icol,MatGetSubMatrixCall scall,Mat *submat)
1595 {
1596   int ierr;
1597   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
1598   if (scall == MAT_REUSE_MATRIX) {
1599     PETSCVALIDHEADERSPECIFIC(*submat,MAT_COOKIE);
1600   }
1601   if (!mat->ops.getsubmatrix) SETERRQ(PETSC_ERR_SUP,"MatGetSubMatrix");
1602   if (!mat->assembled) SETERRQ(1,"MatGetSubMatrix:Not for unassembled matrix");
1603 
1604   PLogEventBegin(MAT_GetSubMatrix,mat,irow,icol,0);
1605   ierr = (*mat->ops.getsubmatrix)(mat,irow,icol,scall,submat); CHKERRQ(ierr);
1606   PLogEventEnd(MAT_GetSubMatrix,mat,irow,icol,0);
1607   return 0;
1608 }
1609 
1610 /*@C
1611    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
1612    points to an array of valid matrices, it may be reused.
1613 
1614    Input Parameters:
1615 .  mat - the matrix
1616 .  irow, icol - index sets of rows and columns to extract
1617 
1618    Output Parameter:
1619 .  submat - the submatrices
1620 
1621    Note:
1622    Use MatGetSubMatrix() for extracting a sinble submatrix.
1623 
1624 .keywords: matrix, get, submatrix, submatrices
1625 
1626 .seealso: MatGetSubMatrix()
1627 @*/
1628 int MatGetSubMatrices(Mat mat,int n, IS *irow,IS *icol,MatGetSubMatrixCall scall,
1629                       Mat **submat)
1630 {
1631   int ierr;
1632   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
1633   if (!mat->ops.getsubmatrices) SETERRQ(PETSC_ERR_SUP,"MatGetSubMatrices");
1634   if (!mat->assembled) SETERRQ(1,"MatGetSubMatrices:Not for unassembled matrix");
1635 
1636   PLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
1637   ierr = (*mat->ops.getsubmatrices)(mat,n,irow,icol,scall,submat); CHKERRQ(ierr);
1638   PLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
1639   return 0;
1640 }
1641 
1642 /*@
1643    MatGetSubMatrixInPlace - Extracts a submatrix from a matrix, returning
1644    the submatrix in place of the original matrix.
1645 
1646    Input Parameters:
1647 .  mat - the matrix
1648 .  irow, icol - index sets of rows and columns to extract
1649 
1650 .keywords: matrix, get, submatrix, boundary conditions, in-place
1651 
1652 .seealso: MatZeroRows(), MatGetSubMatrix()
1653 @*/
1654 int MatGetSubMatrixInPlace(Mat mat,IS irow,IS icol)
1655 {
1656   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
1657   if (!mat->assembled) SETERRQ(1,"MatGetSubMatrixInPlace:Not for unassembled matrix");
1658 
1659   if (!mat->ops.getsubmatrixinplace) SETERRQ(PETSC_ERR_SUP,"MatGetSubmatrixInPlace");
1660   return (*mat->ops.getsubmatrixinplace)(mat,irow,icol);
1661 }
1662 
1663 /*@
1664    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
1665    replaces the index by larger ones that represent submatrices with more
1666    overlap.
1667 
1668    Input Parameters:
1669 .  mat - the matrix
1670 .  n   - the number of index sets
1671 .  is  - the array of pointers to index sets
1672 .  ov  - the additional overlap requested
1673 
1674 .keywords: matrix, overlap, Schwarz
1675 
1676 .seealso: MatGetSubMatrices()
1677 @*/
1678 int MatIncreaseOverlap(Mat mat,int n, IS *is, int ov)
1679 {
1680   int ierr;
1681   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
1682   if (!mat->assembled) SETERRQ(1,"MatIncreaseOverlap:Not for unassembled matrix");
1683 
1684   if (ov == 0) return 0;
1685   if (!mat->ops.increaseoverlap) SETERRQ(PETSC_ERR_SUP,"MatIncreaseOverlap");
1686   PLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
1687   ierr = (*mat->ops.increaseoverlap)(mat,n,is,ov); CHKERRQ(ierr);
1688   PLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
1689   return 0;
1690 }
1691 
1692 /*@
1693    MatPrintHelp - Prints all the options for the matrix.
1694 
1695    Input Parameter:
1696 .  mat - the matrix
1697 
1698    Options Database Keys:
1699 $  -help, -h
1700 
1701 .keywords: mat, help
1702 
1703 .seealso: MatCreate(), MatCreateXXX()
1704 @*/
1705 int MatPrintHelp(Mat mat)
1706 {
1707   static int called = 0;
1708   MPI_Comm   comm = mat->comm;
1709 
1710   if (!called) {
1711     MPIU_printf(comm,"General matrix options:\n");
1712     MPIU_printf(comm,"  -mat_view_info : view basic matrix info during MatAssemblyEnd()\n");
1713     MPIU_printf(comm,"  -mat_view_info_detailed : view detailed matrix info during MatAssemblyEnd()\n");
1714     MPIU_printf(comm,"  -mat_view_draw : draw nonzero matrix structure during MatAssemblyEnd()\n");
1715     MPIU_printf(comm,"      -draw_pause <sec> : set seconds of display pause\n");
1716     MPIU_printf(comm,"      -display <name> : set alternate display\n");
1717     called = 1;
1718   }
1719   if (mat->ops.printhelp) (*mat->ops.printhelp)(mat);
1720   return 0;
1721 }
1722 
1723