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