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