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