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