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