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