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