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