xref: /petsc/src/mat/interface/matrix.c (revision 72c81aad2e5090e191393b9064caca5f4ac415ec)
1 #define PETSCMAT_DLL
2 
3 /*
4    This is where the abstract matrix operations are defined
5 */
6 
7 #include "include/private/matimpl.h"        /*I "petscmat.h" I*/
8 #include "private/vecimpl.h"
9 
10 /* Logging support */
11 PetscCookie PETSCMAT_DLLEXPORT MAT_COOKIE = 0;
12 PetscEvent  MAT_Mult = 0, MAT_Mults = 0, MAT_MultConstrained = 0, MAT_MultAdd = 0, MAT_MultTranspose = 0;
13 PetscEvent  MAT_MultTransposeConstrained = 0, MAT_MultTransposeAdd = 0, MAT_Solve = 0, MAT_Solves = 0, MAT_SolveAdd = 0, MAT_SolveTranspose = 0, MAT_MatSolve = 0;
14 PetscEvent  MAT_SolveTransposeAdd = 0, MAT_Relax = 0, MAT_ForwardSolve = 0, MAT_BackwardSolve = 0, MAT_LUFactor = 0, MAT_LUFactorSymbolic = 0;
15 PetscEvent  MAT_LUFactorNumeric = 0, MAT_CholeskyFactor = 0, MAT_CholeskyFactorSymbolic = 0, MAT_CholeskyFactorNumeric = 0, MAT_ILUFactor = 0;
16 PetscEvent  MAT_ILUFactorSymbolic = 0, MAT_ICCFactorSymbolic = 0, MAT_Copy = 0, MAT_Convert = 0, MAT_Scale = 0, MAT_AssemblyBegin = 0;
17 PetscEvent  MAT_AssemblyEnd = 0, MAT_SetValues = 0, MAT_GetValues = 0, MAT_GetRow = 0, MAT_GetRowIJ = 0, MAT_GetSubMatrices = 0, MAT_GetColoring = 0, MAT_GetOrdering = 0, MAT_GetRedundantMatrix = 0, MAT_GetSeqNonzeroStructure = 0;
18 PetscEvent  MAT_IncreaseOverlap = 0, MAT_Partitioning = 0, MAT_ZeroEntries = 0, MAT_Load = 0, MAT_View = 0, MAT_AXPY = 0, MAT_FDColoringCreate = 0;
19 PetscEvent  MAT_FDColoringApply = 0,MAT_Transpose = 0,MAT_FDColoringFunction = 0;
20 PetscEvent  MAT_MatMult = 0, MAT_MatMultSymbolic = 0, MAT_MatMultNumeric = 0;
21 PetscEvent  MAT_PtAP = 0, MAT_PtAPSymbolic = 0, MAT_PtAPNumeric = 0;
22 PetscEvent  MAT_MatMultTranspose = 0, MAT_MatMultTransposeSymbolic = 0, MAT_MatMultTransposeNumeric = 0;
23 PetscEvent  MAT_Getsymtranspose = 0, MAT_Getsymtransreduced = 0, MAT_Transpose_SeqAIJ = 0, MAT_GetBrowsOfAcols = 0;
24 PetscEvent  MAT_GetBrowsOfAocols = 0, MAT_Getlocalmat = 0, MAT_Getlocalmatcondensed = 0, MAT_Seqstompi = 0, MAT_Seqstompinum = 0, MAT_Seqstompisym = 0;
25 PetscEvent  MAT_Applypapt = 0, MAT_Applypapt_numeric = 0, MAT_Applypapt_symbolic = 0, MAT_GetSequentialNonzeroStructure = 0;
26 
27 /* nasty global values for MatSetValue() */
28 PetscInt    PETSCMAT_DLLEXPORT MatSetValue_Row = 0;
29 PetscInt    PETSCMAT_DLLEXPORT MatSetValue_Column = 0;
30 PetscScalar PETSCMAT_DLLEXPORT MatSetValue_Value = 0.0;
31 
32 #undef __FUNCT__
33 #define __FUNCT__ "MatRealPart"
34 /*@
35    MatRealPart - Zeros out the imaginary part of the matrix
36 
37    Collective on Mat
38 
39    Input Parameters:
40 .  mat - the matrix
41 
42    Level: advanced
43 
44 
45 .seealso: MatImaginaryPart()
46 @*/
47 
48 PetscErrorCode PETSCMAT_DLLEXPORT MatRealPart(Mat mat)
49 {
50   PetscErrorCode ierr;
51 
52   PetscFunctionBegin;
53   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
54   PetscValidType(mat,1);
55   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
56   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
57   if (!mat->ops->realpart) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
58   ierr = MatPreallocated(mat);CHKERRQ(ierr);
59   ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr);
60   PetscFunctionReturn(0);
61 }
62 
63 
64 #undef __FUNCT__
65 #define __FUNCT__ "MatImaginaryPart"
66 /*@
67    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
68 
69    Collective on Mat
70 
71    Input Parameters:
72 .  mat - the matrix
73 
74    Level: advanced
75 
76 
77 .seealso: MatRealPart()
78 @*/
79 
80 PetscErrorCode PETSCMAT_DLLEXPORT MatImaginaryPart(Mat mat)
81 {
82   PetscErrorCode ierr;
83 
84   PetscFunctionBegin;
85   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
86   PetscValidType(mat,1);
87   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
88   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
89   if (!mat->ops->imaginarypart) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
90   ierr = MatPreallocated(mat);CHKERRQ(ierr);
91   ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr);
92   PetscFunctionReturn(0);
93 }
94 
95 #undef __FUNCT__
96 #define __FUNCT__ "MatMissingDiagonal"
97 /*@
98    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
99 
100    Collective on Mat
101 
102    Input Parameter:
103 .  mat - the matrix
104 
105    Output Parameters:
106 +  missing - is any diagonal missing
107 -  dd - first diagonal entry that is missing (optional)
108 
109    Level: advanced
110 
111 
112 .seealso: MatRealPart()
113 @*/
114 
115 PetscErrorCode PETSCMAT_DLLEXPORT MatMissingDiagonal(Mat mat,PetscTruth *missing,PetscInt *dd)
116 {
117   PetscErrorCode ierr;
118 
119   PetscFunctionBegin;
120   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
121   PetscValidType(mat,1);
122   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
123   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
124   if (!mat->ops->missingdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
125   ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr);
126   PetscFunctionReturn(0);
127 }
128 
129 #undef __FUNCT__
130 #define __FUNCT__ "MatGetRow"
131 /*@C
132    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
133    for each row that you get to ensure that your application does
134    not bleed memory.
135 
136    Not Collective
137 
138    Input Parameters:
139 +  mat - the matrix
140 -  row - the row to get
141 
142    Output Parameters:
143 +  ncols -  if not NULL, the number of nonzeros in the row
144 .  cols - if not NULL, the column numbers
145 -  vals - if not NULL, the values
146 
147    Notes:
148    This routine is provided for people who need to have direct access
149    to the structure of a matrix.  We hope that we provide enough
150    high-level matrix routines that few users will need it.
151 
152    MatGetRow() always returns 0-based column indices, regardless of
153    whether the internal representation is 0-based (default) or 1-based.
154 
155    For better efficiency, set cols and/or vals to PETSC_NULL if you do
156    not wish to extract these quantities.
157 
158    The user can only examine the values extracted with MatGetRow();
159    the values cannot be altered.  To change the matrix entries, one
160    must use MatSetValues().
161 
162    You can only have one call to MatGetRow() outstanding for a particular
163    matrix at a time, per processor. MatGetRow() can only obtain rows
164    associated with the given processor, it cannot get rows from the
165    other processors; for that we suggest using MatGetSubMatrices(), then
166    MatGetRow() on the submatrix. The row indix passed to MatGetRows()
167    is in the global number of rows.
168 
169    Fortran Notes:
170    The calling sequence from Fortran is
171 .vb
172    MatGetRow(matrix,row,ncols,cols,values,ierr)
173          Mat     matrix (input)
174          integer row    (input)
175          integer ncols  (output)
176          integer cols(maxcols) (output)
177          double precision (or double complex) values(maxcols) output
178 .ve
179    where maxcols >= maximum nonzeros in any row of the matrix.
180 
181 
182    Caution:
183    Do not try to change the contents of the output arrays (cols and vals).
184    In some cases, this may corrupt the matrix.
185 
186    Level: advanced
187 
188    Concepts: matrices^row access
189 
190 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
191 @*/
192 
193 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
194 {
195   PetscErrorCode ierr;
196   PetscInt       incols;
197 
198   PetscFunctionBegin;
199   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
200   PetscValidType(mat,1);
201   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
202   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
203   if (!mat->ops->getrow) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
204   ierr = MatPreallocated(mat);CHKERRQ(ierr);
205   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
206   ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
207   if (ncols) *ncols = incols;
208   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
209   PetscFunctionReturn(0);
210 }
211 
212 #undef __FUNCT__
213 #define __FUNCT__ "MatConjugate"
214 /*@
215    MatConjugate - replaces the matrix values with their complex conjugates
216 
217    Collective on Mat
218 
219    Input Parameters:
220 .  mat - the matrix
221 
222    Level: advanced
223 
224 .seealso:  VecConjugate()
225 @*/
226 PetscErrorCode PETSCMAT_DLLEXPORT MatConjugate(Mat mat)
227 {
228   PetscErrorCode ierr;
229 
230   PetscFunctionBegin;
231   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
232   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
233   if (!mat->ops->conjugate) SETERRQ(PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
234   ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr);
235   PetscFunctionReturn(0);
236 }
237 
238 #undef __FUNCT__
239 #define __FUNCT__ "MatRestoreRow"
240 /*@C
241    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
242 
243    Not Collective
244 
245    Input Parameters:
246 +  mat - the matrix
247 .  row - the row to get
248 .  ncols, cols - the number of nonzeros and their columns
249 -  vals - if nonzero the column values
250 
251    Notes:
252    This routine should be called after you have finished examining the entries.
253 
254    Fortran Notes:
255    The calling sequence from Fortran is
256 .vb
257    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
258       Mat     matrix (input)
259       integer row    (input)
260       integer ncols  (output)
261       integer cols(maxcols) (output)
262       double precision (or double complex) values(maxcols) output
263 .ve
264    Where maxcols >= maximum nonzeros in any row of the matrix.
265 
266    In Fortran MatRestoreRow() MUST be called after MatGetRow()
267    before another call to MatGetRow() can be made.
268 
269    Level: advanced
270 
271 .seealso:  MatGetRow()
272 @*/
273 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
274 {
275   PetscErrorCode ierr;
276 
277   PetscFunctionBegin;
278   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
279   PetscValidIntPointer(ncols,3);
280   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
281   if (!mat->ops->restorerow) PetscFunctionReturn(0);
282   ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
283   PetscFunctionReturn(0);
284 }
285 
286 #undef __FUNCT__
287 #define __FUNCT__ "MatGetRowUpperTriangular"
288 /*@C
289    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
290    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
291 
292    Not Collective
293 
294    Input Parameters:
295 +  mat - the matrix
296 
297    Notes:
298    The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format.
299 
300    Level: advanced
301 
302    Concepts: matrices^row access
303 
304 .seealso: MatRestoreRowRowUpperTriangular()
305 @*/
306 
307 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowUpperTriangular(Mat mat)
308 {
309   PetscErrorCode ierr;
310 
311   PetscFunctionBegin;
312   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
313   PetscValidType(mat,1);
314   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
315   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
316   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
317   ierr = MatPreallocated(mat);CHKERRQ(ierr);
318   ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr);
319   PetscFunctionReturn(0);
320 }
321 
322 #undef __FUNCT__
323 #define __FUNCT__ "MatRestoreRowUpperTriangular"
324 /*@C
325    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
326 
327    Not Collective
328 
329    Input Parameters:
330 +  mat - the matrix
331 
332    Notes:
333    This routine should be called after you have finished MatGetRow/MatRestoreRow().
334 
335 
336    Level: advanced
337 
338 .seealso:  MatGetRowUpperTriangular()
339 @*/
340 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreRowUpperTriangular(Mat mat)
341 {
342   PetscErrorCode ierr;
343 
344   PetscFunctionBegin;
345   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
346   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
347   if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0);
348   ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr);
349   PetscFunctionReturn(0);
350 }
351 
352 #undef __FUNCT__
353 #define __FUNCT__ "MatSetOptionsPrefix"
354 /*@C
355    MatSetOptionsPrefix - Sets the prefix used for searching for all
356    Mat options in the database.
357 
358    Collective on Mat
359 
360    Input Parameter:
361 +  A - the Mat context
362 -  prefix - the prefix to prepend to all option names
363 
364    Notes:
365    A hyphen (-) must NOT be given at the beginning of the prefix name.
366    The first character of all runtime options is AUTOMATICALLY the hyphen.
367 
368    Level: advanced
369 
370 .keywords: Mat, set, options, prefix, database
371 
372 .seealso: MatSetFromOptions()
373 @*/
374 PetscErrorCode PETSCMAT_DLLEXPORT MatSetOptionsPrefix(Mat A,const char prefix[])
375 {
376   PetscErrorCode ierr;
377 
378   PetscFunctionBegin;
379   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
380   ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
381   PetscFunctionReturn(0);
382 }
383 
384 #undef __FUNCT__
385 #define __FUNCT__ "MatAppendOptionsPrefix"
386 /*@C
387    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
388    Mat options in the database.
389 
390    Collective on Mat
391 
392    Input Parameters:
393 +  A - the Mat context
394 -  prefix - the prefix to prepend to all option names
395 
396    Notes:
397    A hyphen (-) must NOT be given at the beginning of the prefix name.
398    The first character of all runtime options is AUTOMATICALLY the hyphen.
399 
400    Level: advanced
401 
402 .keywords: Mat, append, options, prefix, database
403 
404 .seealso: MatGetOptionsPrefix()
405 @*/
406 PetscErrorCode PETSCMAT_DLLEXPORT MatAppendOptionsPrefix(Mat A,const char prefix[])
407 {
408   PetscErrorCode ierr;
409 
410   PetscFunctionBegin;
411   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
412   ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
413   PetscFunctionReturn(0);
414 }
415 
416 #undef __FUNCT__
417 #define __FUNCT__ "MatGetOptionsPrefix"
418 /*@C
419    MatGetOptionsPrefix - Sets the prefix used for searching for all
420    Mat options in the database.
421 
422    Not Collective
423 
424    Input Parameter:
425 .  A - the Mat context
426 
427    Output Parameter:
428 .  prefix - pointer to the prefix string used
429 
430    Notes: On the fortran side, the user should pass in a string 'prefix' of
431    sufficient length to hold the prefix.
432 
433    Level: advanced
434 
435 .keywords: Mat, get, options, prefix, database
436 
437 .seealso: MatAppendOptionsPrefix()
438 @*/
439 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOptionsPrefix(Mat A,const char *prefix[])
440 {
441   PetscErrorCode ierr;
442 
443   PetscFunctionBegin;
444   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
445   ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
446   PetscFunctionReturn(0);
447 }
448 
449 #undef __FUNCT__
450 #define __FUNCT__ "MatSetUp"
451 /*@
452    MatSetUp - Sets up the internal matrix data structures for the later use.
453 
454    Collective on Mat
455 
456    Input Parameters:
457 .  A - the Mat context
458 
459    Notes:
460    For basic use of the Mat classes the user need not explicitly call
461    MatSetUp(), since these actions will happen automatically.
462 
463    Level: advanced
464 
465 .keywords: Mat, setup
466 
467 .seealso: MatCreate(), MatDestroy()
468 @*/
469 PetscErrorCode PETSCMAT_DLLEXPORT MatSetUp(Mat A)
470 {
471   PetscMPIInt    size;
472   PetscErrorCode ierr;
473 
474   PetscFunctionBegin;
475   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
476   if (!((PetscObject)A)->type_name) {
477     ierr = MPI_Comm_size(((PetscObject)A)->comm, &size);CHKERRQ(ierr);
478     if (size == 1) {
479       ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr);
480     } else {
481       ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr);
482     }
483   }
484   ierr = MatSetUpPreallocation(A);CHKERRQ(ierr);
485   PetscFunctionReturn(0);
486 }
487 
488 #undef __FUNCT__
489 #define __FUNCT__ "MatView"
490 /*@C
491    MatView - Visualizes a matrix object.
492 
493    Collective on Mat
494 
495    Input Parameters:
496 +  mat - the matrix
497 -  viewer - visualization context
498 
499   Notes:
500   The available visualization contexts include
501 +    PETSC_VIEWER_STDOUT_SELF - standard output (default)
502 .    PETSC_VIEWER_STDOUT_WORLD - synchronized standard
503         output where only the first processor opens
504         the file.  All other processors send their
505         data to the first processor to print.
506 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
507 
508    The user can open alternative visualization contexts with
509 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
510 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
511          specified file; corresponding input uses MatLoad()
512 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
513          an X window display
514 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
515          Currently only the sequential dense and AIJ
516          matrix types support the Socket viewer.
517 
518    The user can call PetscViewerSetFormat() to specify the output
519    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
520    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
521 +    PETSC_VIEWER_ASCII_DEFAULT - default, prints matrix contents
522 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
523 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
524 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
525          format common among all matrix types
526 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
527          format (which is in many cases the same as the default)
528 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
529          size and structure (not the matrix entries)
530 .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
531          the matrix structure
532 
533    Options Database Keys:
534 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
535 .  -mat_view_info_detailed - Prints more detailed info
536 .  -mat_view - Prints matrix in ASCII format
537 .  -mat_view_matlab - Prints matrix in Matlab format
538 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
539 .  -display <name> - Sets display name (default is host)
540 .  -draw_pause <sec> - Sets number of seconds to pause after display
541 .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
542 .  -viewer_socket_machine <machine>
543 .  -viewer_socket_port <port>
544 .  -mat_view_binary - save matrix to file in binary format
545 -  -viewer_binary_filename <name>
546    Level: beginner
547 
548    Concepts: matrices^viewing
549    Concepts: matrices^plotting
550    Concepts: matrices^printing
551 
552 .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
553           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
554 @*/
555 PetscErrorCode PETSCMAT_DLLEXPORT MatView(Mat mat,PetscViewer viewer)
556 {
557   PetscErrorCode    ierr;
558   PetscInt          rows,cols;
559   PetscTruth        iascii;
560   const char        *cstr;
561   PetscViewerFormat format;
562 
563   PetscFunctionBegin;
564   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
565   PetscValidType(mat,1);
566   if (!viewer) {
567     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
568   }
569   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,2);
570   PetscCheckSameComm(mat,1,viewer,2);
571   if (!mat->assembled) SETERRQ(PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
572   ierr = MatPreallocated(mat);CHKERRQ(ierr);
573 
574   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
575   if (iascii) {
576     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
577     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
578       if (((PetscObject)mat)->prefix) {
579         ierr = PetscViewerASCIIPrintf(viewer,"Matrix Object:(%s)\n",((PetscObject)mat)->prefix);CHKERRQ(ierr);
580       } else {
581         ierr = PetscViewerASCIIPrintf(viewer,"Matrix Object:\n");CHKERRQ(ierr);
582       }
583       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
584       ierr = MatGetType(mat,&cstr);CHKERRQ(ierr);
585       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
586       ierr = PetscViewerASCIIPrintf(viewer,"type=%s, rows=%D, cols=%D\n",cstr,rows,cols);CHKERRQ(ierr);
587       if (mat->ops->getinfo) {
588         MatInfo info;
589         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
590         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%D, allocated nonzeros=%D\n",
591                           (PetscInt)info.nz_used,(PetscInt)info.nz_allocated);CHKERRQ(ierr);
592       }
593     }
594   }
595   if (mat->ops->view) {
596     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
597     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
598     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
599   } else if (!iascii) {
600     SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported",((PetscObject)viewer)->type_name);
601   }
602   if (iascii) {
603     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
604     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
605       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
606     }
607   }
608   PetscFunctionReturn(0);
609 }
610 
611 #undef __FUNCT__
612 #define __FUNCT__ "MatScaleSystem"
613 /*@
614    MatScaleSystem - Scale a vector solution and right hand side to
615    match the scaling of a scaled matrix.
616 
617    Collective on Mat
618 
619    Input Parameter:
620 +  mat - the matrix
621 .  b - right hand side vector (or PETSC_NULL)
622 -  x - solution vector (or PETSC_NULL)
623 
624 
625    Notes:
626    For AIJ, and BAIJ matrix formats, the matrices are not
627    internally scaled, so this does nothing. For MPIROWBS it
628    permutes and diagonally scales.
629 
630    The KSP methods automatically call this routine when required
631    (via PCPreSolve()) so it is rarely used directly.
632 
633    Level: Developer
634 
635    Concepts: matrices^scaling
636 
637 .seealso: MatUseScaledForm(), MatUnScaleSystem()
638 @*/
639 PetscErrorCode PETSCMAT_DLLEXPORT MatScaleSystem(Mat mat,Vec b,Vec x)
640 {
641   PetscErrorCode ierr;
642 
643   PetscFunctionBegin;
644   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
645   PetscValidType(mat,1);
646   ierr = MatPreallocated(mat);CHKERRQ(ierr);
647   if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE,2);PetscCheckSameComm(mat,1,x,2);}
648   if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE,3);PetscCheckSameComm(mat,1,b,3);}
649 
650   if (mat->ops->scalesystem) {
651     ierr = (*mat->ops->scalesystem)(mat,b,x);CHKERRQ(ierr);
652   }
653   PetscFunctionReturn(0);
654 }
655 
656 #undef __FUNCT__
657 #define __FUNCT__ "MatUnScaleSystem"
658 /*@
659    MatUnScaleSystem - Unscales a vector solution and right hand side to
660    match the original scaling of a scaled matrix.
661 
662    Collective on Mat
663 
664    Input Parameter:
665 +  mat - the matrix
666 .  b - right hand side vector (or PETSC_NULL)
667 -  x - solution vector (or PETSC_NULL)
668 
669 
670    Notes:
671    For AIJ and BAIJ matrix formats, the matrices are not
672    internally scaled, so this does nothing. For MPIROWBS it
673    permutes and diagonally scales.
674 
675    The KSP methods automatically call this routine when required
676    (via PCPreSolve()) so it is rarely used directly.
677 
678    Level: Developer
679 
680 .seealso: MatUseScaledForm(), MatScaleSystem()
681 @*/
682 PetscErrorCode PETSCMAT_DLLEXPORT MatUnScaleSystem(Mat mat,Vec b,Vec x)
683 {
684   PetscErrorCode ierr;
685 
686   PetscFunctionBegin;
687   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
688   PetscValidType(mat,1);
689   ierr = MatPreallocated(mat);CHKERRQ(ierr);
690   if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE,2);PetscCheckSameComm(mat,1,x,2);}
691   if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE,3);PetscCheckSameComm(mat,1,b,3);}
692   if (mat->ops->unscalesystem) {
693     ierr = (*mat->ops->unscalesystem)(mat,b,x);CHKERRQ(ierr);
694   }
695   PetscFunctionReturn(0);
696 }
697 
698 #undef __FUNCT__
699 #define __FUNCT__ "MatUseScaledForm"
700 /*@
701    MatUseScaledForm - For matrix storage formats that scale the
702    matrix (for example MPIRowBS matrices are diagonally scaled on
703    assembly) indicates matrix operations (MatMult() etc) are
704    applied using the scaled matrix.
705 
706    Collective on Mat
707 
708    Input Parameter:
709 +  mat - the matrix
710 -  scaled - PETSC_TRUE for applying the scaled, PETSC_FALSE for
711             applying the original matrix
712 
713    Notes:
714    For scaled matrix formats, applying the original, unscaled matrix
715    will be slightly more expensive
716 
717    Level: Developer
718 
719 .seealso: MatScaleSystem(), MatUnScaleSystem()
720 @*/
721 PetscErrorCode PETSCMAT_DLLEXPORT MatUseScaledForm(Mat mat,PetscTruth scaled)
722 {
723   PetscErrorCode ierr;
724 
725   PetscFunctionBegin;
726   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
727   PetscValidType(mat,1);
728   ierr = MatPreallocated(mat);CHKERRQ(ierr);
729   if (mat->ops->usescaledform) {
730     ierr = (*mat->ops->usescaledform)(mat,scaled);CHKERRQ(ierr);
731   }
732   PetscFunctionReturn(0);
733 }
734 
735 #undef __FUNCT__
736 #define __FUNCT__ "MatDestroy"
737 /*@
738    MatDestroy - Frees space taken by a matrix.
739 
740    Collective on Mat
741 
742    Input Parameter:
743 .  A - the matrix
744 
745    Level: beginner
746 
747 @*/
748 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroy(Mat A)
749 {
750   PetscErrorCode ierr;
751   PetscFunctionBegin;
752   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
753   if (--((PetscObject)A)->refct > 0) PetscFunctionReturn(0);
754   ierr = MatPreallocated(A);CHKERRQ(ierr);
755   /* if memory was published with AMS then destroy it */
756   ierr = PetscObjectDepublish(A);CHKERRQ(ierr);
757   if (A->ops->destroy) {
758     ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
759   }
760   if (A->mapping) {
761     ierr = ISLocalToGlobalMappingDestroy(A->mapping);CHKERRQ(ierr);
762   }
763   if (A->bmapping) {
764     ierr = ISLocalToGlobalMappingDestroy(A->bmapping);CHKERRQ(ierr);
765   }
766   ierr = PetscFree(A->rmap.range);CHKERRQ(ierr);
767   ierr = PetscFree(A->cmap.range);CHKERRQ(ierr);
768   if (A->spptr){ierr = PetscFree(A->spptr);CHKERRQ(ierr);}
769   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
770   PetscFunctionReturn(0);
771 }
772 
773 #undef __FUNCT__
774 #define __FUNCT__ "MatValid"
775 /*@
776    MatValid - Checks whether a matrix object is valid.
777 
778    Collective on Mat
779 
780    Input Parameter:
781 .  m - the matrix to check
782 
783    Output Parameter:
784    flg - flag indicating matrix status, either
785    PETSC_TRUE if matrix is valid, or PETSC_FALSE otherwise.
786 
787    Level: developer
788 
789    Concepts: matrices^validity
790 @*/
791 PetscErrorCode PETSCMAT_DLLEXPORT MatValid(Mat m,PetscTruth *flg)
792 {
793   PetscFunctionBegin;
794   PetscValidIntPointer(flg,1);
795   if (!m)                                          *flg = PETSC_FALSE;
796   else if (((PetscObject)m)->cookie != MAT_COOKIE) *flg = PETSC_FALSE;
797   else                                             *flg = PETSC_TRUE;
798   PetscFunctionReturn(0);
799 }
800 
801 #undef __FUNCT__
802 #define __FUNCT__ "MatSetValues"
803 /*@
804    MatSetValues - Inserts or adds a block of values into a matrix.
805    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
806    MUST be called after all calls to MatSetValues() have been completed.
807 
808    Not Collective
809 
810    Input Parameters:
811 +  mat - the matrix
812 .  v - a logically two-dimensional array of values
813 .  m, idxm - the number of rows and their global indices
814 .  n, idxn - the number of columns and their global indices
815 -  addv - either ADD_VALUES or INSERT_VALUES, where
816    ADD_VALUES adds values to any existing entries, and
817    INSERT_VALUES replaces existing entries with new values
818 
819    Notes:
820    By default the values, v, are row-oriented and unsorted.
821    See MatSetOption() for other options.
822 
823    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
824    options cannot be mixed without intervening calls to the assembly
825    routines.
826 
827    MatSetValues() uses 0-based row and column numbers in Fortran
828    as well as in C.
829 
830    Negative indices may be passed in idxm and idxn, these rows and columns are
831    simply ignored. This allows easily inserting element stiffness matrices
832    with homogeneous Dirchlet boundary conditions that you don't want represented
833    in the matrix.
834 
835    Efficiency Alert:
836    The routine MatSetValuesBlocked() may offer much better efficiency
837    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
838 
839    Level: beginner
840 
841    Concepts: matrices^putting entries in
842 
843 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
844           InsertMode, INSERT_VALUES, ADD_VALUES
845 @*/
846 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
847 {
848   PetscErrorCode ierr;
849 
850   PetscFunctionBegin;
851   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
852   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
853   PetscValidType(mat,1);
854   PetscValidIntPointer(idxm,3);
855   PetscValidIntPointer(idxn,5);
856   PetscValidScalarPointer(v,6);
857   ierr = MatPreallocated(mat);CHKERRQ(ierr);
858   if (mat->insertmode == NOT_SET_VALUES) {
859     mat->insertmode = addv;
860   }
861 #if defined(PETSC_USE_DEBUG)
862   else if (mat->insertmode != addv) {
863     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
864   }
865   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
866 #endif
867 
868   if (mat->assembled) {
869     mat->was_assembled = PETSC_TRUE;
870     mat->assembled     = PETSC_FALSE;
871   }
872   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
873   if (!mat->ops->setvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
874   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
875   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
876   PetscFunctionReturn(0);
877 }
878 
879 
880 #undef __FUNCT__
881 #define __FUNCT__ "MatSetValuesRowLocal"
882 /*@
883    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
884         values into a matrix
885 
886    Not Collective
887 
888    Input Parameters:
889 +  mat - the matrix
890 .  row - the (block) row to set
891 -  v - a logically two-dimensional array of values
892 
893    Notes:
894    By the values, v, are column-oriented (for the block version) and sorted
895 
896    All the nonzeros in the row must be provided
897 
898    The matrix must have previously had its column indices set
899 
900    The row must belong to this process
901 
902    Level: intermediate
903 
904    Concepts: matrices^putting entries in
905 
906 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
907           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
908 @*/
909 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
910 {
911   PetscErrorCode ierr;
912 
913   PetscFunctionBegin;
914   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
915   PetscValidType(mat,1);
916   PetscValidScalarPointer(v,2);
917   ierr = MatSetValuesRow(mat, mat->mapping->indices[row],v);CHKERRQ(ierr);
918   PetscFunctionReturn(0);
919 }
920 
921 #undef __FUNCT__
922 #define __FUNCT__ "MatSetValuesRow"
923 /*@
924    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
925         values into a matrix
926 
927    Not Collective
928 
929    Input Parameters:
930 +  mat - the matrix
931 .  row - the (block) row to set
932 -  v - a logically two-dimensional array of values
933 
934    Notes:
935    By the values, v, are column-oriented (for the block version) and sorted
936 
937    All the nonzeros in the row must be provided
938 
939    The matrix must have previously had its column indices set
940 
941    The row must belong to this process
942 
943    Level: intermediate
944 
945    Concepts: matrices^putting entries in
946 
947 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
948           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
949 @*/
950 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
951 {
952   PetscErrorCode ierr;
953 
954   PetscFunctionBegin;
955   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
956   PetscValidType(mat,1);
957   PetscValidScalarPointer(v,2);
958 #if defined(PETSC_USE_DEBUG)
959   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
960   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
961 #endif
962   mat->insertmode = INSERT_VALUES;
963 
964   if (mat->assembled) {
965     mat->was_assembled = PETSC_TRUE;
966     mat->assembled     = PETSC_FALSE;
967   }
968   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
969   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
970   ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
971   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
972   PetscFunctionReturn(0);
973 }
974 
975 #undef __FUNCT__
976 #define __FUNCT__ "MatSetValuesStencil"
977 /*@
978    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
979      Using structured grid indexing
980 
981    Not Collective
982 
983    Input Parameters:
984 +  mat - the matrix
985 .  v - a logically two-dimensional array of values
986 .  m - number of rows being entered
987 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
988 .  n - number of columns being entered
989 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
990 -  addv - either ADD_VALUES or INSERT_VALUES, where
991    ADD_VALUES adds values to any existing entries, and
992    INSERT_VALUES replaces existing entries with new values
993 
994    Notes:
995    By default the values, v, are row-oriented and unsorted.
996    See MatSetOption() for other options.
997 
998    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
999    options cannot be mixed without intervening calls to the assembly
1000    routines.
1001 
1002    The grid coordinates are across the entire grid, not just the local portion
1003 
1004    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1005    as well as in C.
1006 
1007    For setting/accessing vector values via array coordinates you can use the DAVecGetArray() routine
1008 
1009    In order to use this routine you must either obtain the matrix with DAGetMatrix()
1010    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1011 
1012    The columns and rows in the stencil passed in MUST be contained within the
1013    ghost region of the given process as set with DACreateXXX() or MatSetStencil(). For example,
1014    if you create a DA with an overlap of one grid level and on a particular process its first
1015    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1016    first i index you can use in your column and row indices in MatSetStencil() is 5.
1017 
1018    In Fortran idxm and idxn should be declared as
1019 $     MatStencil idxm(4,m),idxn(4,n)
1020    and the values inserted using
1021 $    idxm(MatStencil_i,1) = i
1022 $    idxm(MatStencil_j,1) = j
1023 $    idxm(MatStencil_k,1) = k
1024 $    idxm(MatStencil_c,1) = c
1025    etc
1026 
1027    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1028    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1029    etc to obtain values that obtained by wrapping the values from the left edge.
1030 
1031    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
1032    a single value per point) you can skip filling those indices.
1033 
1034    Inspired by the structured grid interface to the HYPRE package
1035    (http://www.llnl.gov/CASC/hypre)
1036 
1037    Efficiency Alert:
1038    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1039    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1040 
1041    Level: beginner
1042 
1043    Concepts: matrices^putting entries in
1044 
1045 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1046           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DAGetMatrix(), DAVecGetArray(), MatStencil
1047 @*/
1048 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1049 {
1050   PetscErrorCode ierr;
1051   PetscInt       j,i,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1052   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1053 
1054   PetscFunctionBegin;
1055   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1056   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1057   PetscValidType(mat,1);
1058   PetscValidIntPointer(idxm,3);
1059   PetscValidIntPointer(idxn,5);
1060   PetscValidScalarPointer(v,6);
1061 
1062   if (m > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 128 rows at a time; trying to set %D",m);
1063   if (n > 256) SETERRQ1(PETSC_ERR_SUP,"Can only set 256 columns at a time; trying to set %D",n);
1064 
1065   for (i=0; i<m; i++) {
1066     for (j=0; j<3-sdim; j++) dxm++;
1067     tmp = *dxm++ - starts[0];
1068     for (j=0; j<dim-1; j++) {
1069       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1070       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1071     }
1072     if (mat->stencil.noc) dxm++;
1073     jdxm[i] = tmp;
1074   }
1075   for (i=0; i<n; i++) {
1076     for (j=0; j<3-sdim; j++) dxn++;
1077     tmp = *dxn++ - starts[0];
1078     for (j=0; j<dim-1; j++) {
1079       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1080       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1081     }
1082     if (mat->stencil.noc) dxn++;
1083     jdxn[i] = tmp;
1084   }
1085   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1086   PetscFunctionReturn(0);
1087 }
1088 
1089 #undef __FUNCT__
1090 #define __FUNCT__ "MatSetValuesBlockedStencil"
1091 /*@C
1092    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1093      Using structured grid indexing
1094 
1095    Not Collective
1096 
1097    Input Parameters:
1098 +  mat - the matrix
1099 .  v - a logically two-dimensional array of values
1100 .  m - number of rows being entered
1101 .  idxm - grid coordinates for matrix rows being entered
1102 .  n - number of columns being entered
1103 .  idxn - grid coordinates for matrix columns being entered
1104 -  addv - either ADD_VALUES or INSERT_VALUES, where
1105    ADD_VALUES adds values to any existing entries, and
1106    INSERT_VALUES replaces existing entries with new values
1107 
1108    Notes:
1109    By default the values, v, are row-oriented and unsorted.
1110    See MatSetOption() for other options.
1111 
1112    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1113    options cannot be mixed without intervening calls to the assembly
1114    routines.
1115 
1116    The grid coordinates are across the entire grid, not just the local portion
1117 
1118    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1119    as well as in C.
1120 
1121    For setting/accessing vector values via array coordinates you can use the DAVecGetArray() routine
1122 
1123    In order to use this routine you must either obtain the matrix with DAGetMatrix()
1124    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1125 
1126    The columns and rows in the stencil passed in MUST be contained within the
1127    ghost region of the given process as set with DACreateXXX() or MatSetStencil(). For example,
1128    if you create a DA with an overlap of one grid level and on a particular process its first
1129    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1130    first i index you can use in your column and row indices in MatSetStencil() is 5.
1131 
1132    In Fortran idxm and idxn should be declared as
1133 $     MatStencil idxm(4,m),idxn(4,n)
1134    and the values inserted using
1135 $    idxm(MatStencil_i,1) = i
1136 $    idxm(MatStencil_j,1) = j
1137 $    idxm(MatStencil_k,1) = k
1138    etc
1139 
1140    Negative indices may be passed in idxm and idxn, these rows and columns are
1141    simply ignored. This allows easily inserting element stiffness matrices
1142    with homogeneous Dirchlet boundary conditions that you don't want represented
1143    in the matrix.
1144 
1145    Inspired by the structured grid interface to the HYPRE package
1146    (http://www.llnl.gov/CASC/hypre)
1147 
1148    Level: beginner
1149 
1150    Concepts: matrices^putting entries in
1151 
1152 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1153           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DAGetMatrix(), DAVecGetArray(), MatStencil
1154 @*/
1155 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1156 {
1157   PetscErrorCode ierr;
1158   PetscInt       j,i,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1159   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1160 
1161   PetscFunctionBegin;
1162   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1163   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1164   PetscValidType(mat,1);
1165   PetscValidIntPointer(idxm,3);
1166   PetscValidIntPointer(idxn,5);
1167   PetscValidScalarPointer(v,6);
1168 
1169   if (m > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 128 rows at a time; trying to set %D",m);
1170   if (n > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 256 columns at a time; trying to set %D",n);
1171 
1172   for (i=0; i<m; i++) {
1173     for (j=0; j<3-sdim; j++) dxm++;
1174     tmp = *dxm++ - starts[0];
1175     for (j=0; j<sdim-1; j++) {
1176       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1177       else                                      tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1178     }
1179     dxm++;
1180     jdxm[i] = tmp;
1181   }
1182   for (i=0; i<n; i++) {
1183     for (j=0; j<3-sdim; j++) dxn++;
1184     tmp = *dxn++ - starts[0];
1185     for (j=0; j<sdim-1; j++) {
1186       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1187       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1188     }
1189     dxn++;
1190     jdxn[i] = tmp;
1191   }
1192   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1193   PetscFunctionReturn(0);
1194 }
1195 
1196 #undef __FUNCT__
1197 #define __FUNCT__ "MatSetStencil"
1198 /*@
1199    MatSetStencil - Sets the grid information for setting values into a matrix via
1200         MatSetValuesStencil()
1201 
1202    Not Collective
1203 
1204    Input Parameters:
1205 +  mat - the matrix
1206 .  dim - dimension of the grid 1, 2, or 3
1207 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1208 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1209 -  dof - number of degrees of freedom per node
1210 
1211 
1212    Inspired by the structured grid interface to the HYPRE package
1213    (www.llnl.gov/CASC/hyper)
1214 
1215    For matrices generated with DAGetMatrix() this routine is automatically called and so not needed by the
1216    user.
1217 
1218    Level: beginner
1219 
1220    Concepts: matrices^putting entries in
1221 
1222 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1223           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1224 @*/
1225 PetscErrorCode PETSCMAT_DLLEXPORT MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1226 {
1227   PetscInt i;
1228 
1229   PetscFunctionBegin;
1230   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1231   PetscValidIntPointer(dims,3);
1232   PetscValidIntPointer(starts,4);
1233 
1234   mat->stencil.dim = dim + (dof > 1);
1235   for (i=0; i<dim; i++) {
1236     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1237     mat->stencil.starts[i] = starts[dim-i-1];
1238   }
1239   mat->stencil.dims[dim]   = dof;
1240   mat->stencil.starts[dim] = 0;
1241   mat->stencil.noc         = (PetscTruth)(dof == 1);
1242   PetscFunctionReturn(0);
1243 }
1244 
1245 #undef __FUNCT__
1246 #define __FUNCT__ "MatSetValuesBlocked"
1247 /*@
1248    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1249 
1250    Not Collective
1251 
1252    Input Parameters:
1253 +  mat - the matrix
1254 .  v - a logically two-dimensional array of values
1255 .  m, idxm - the number of block rows and their global block indices
1256 .  n, idxn - the number of block columns and their global block indices
1257 -  addv - either ADD_VALUES or INSERT_VALUES, where
1258    ADD_VALUES adds values to any existing entries, and
1259    INSERT_VALUES replaces existing entries with new values
1260 
1261    Notes:
1262    The m and n count the NUMBER of blocks in the row direction and column direction,
1263    NOT the total number of rows/columns; for example, if the block size is 2 and
1264    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1265 
1266    By default the values, v, are row-oriented and unsorted. So the layout of
1267    v is the same as for MatSetValues(). See MatSetOption() for other options.
1268 
1269    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1270    options cannot be mixed without intervening calls to the assembly
1271    routines.
1272 
1273    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1274    as well as in C.
1275 
1276    Negative indices may be passed in idxm and idxn, these rows and columns are
1277    simply ignored. This allows easily inserting element stiffness matrices
1278    with homogeneous Dirchlet boundary conditions that you don't want represented
1279    in the matrix.
1280 
1281    Each time an entry is set within a sparse matrix via MatSetValues(),
1282    internal searching must be done to determine where to place the the
1283    data in the matrix storage space.  By instead inserting blocks of
1284    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1285    reduced.
1286 
1287    Example:
1288 $   Suppose m=n=2 and block size(bs) = 2 The matrix is
1289 $
1290 $   1  2  | 3  4
1291 $   5  6  | 7  8
1292 $   - - - | - - -
1293 $   9  10 | 11 12
1294 $   13 14 | 15 16
1295 $
1296 $   v[] should be passed in like
1297 $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1298 
1299    Level: intermediate
1300 
1301    Concepts: matrices^putting entries in blocked
1302 
1303 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1304 @*/
1305 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1306 {
1307   PetscErrorCode ierr;
1308 
1309   PetscFunctionBegin;
1310   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1311   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1312   PetscValidType(mat,1);
1313   PetscValidIntPointer(idxm,3);
1314   PetscValidIntPointer(idxn,5);
1315   PetscValidScalarPointer(v,6);
1316   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1317   if (mat->insertmode == NOT_SET_VALUES) {
1318     mat->insertmode = addv;
1319   }
1320 #if defined(PETSC_USE_DEBUG)
1321   else if (mat->insertmode != addv) {
1322     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1323   }
1324   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1325 #endif
1326 
1327   if (mat->assembled) {
1328     mat->was_assembled = PETSC_TRUE;
1329     mat->assembled     = PETSC_FALSE;
1330   }
1331   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1332   if (mat->ops->setvaluesblocked) {
1333     ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1334   } else {
1335     PetscInt i,j,*iidxm,*iidxn,bs = mat->rmap.bs;
1336     ierr = PetscMalloc2(m*bs,PetscInt,&iidxm,n*bs,PetscInt,&iidxn);CHKERRQ(ierr);
1337     for (i=0; i<m; i++) {
1338       for (j=0; j<bs; j++) {
1339 	iidxm[i*bs+j] = bs*idxm[i] + j;
1340       }
1341     }
1342     for (i=0; i<n; i++) {
1343       for (j=0; j<bs; j++) {
1344 	iidxn[i*bs+j] = bs*idxn[i] + j;
1345       }
1346     }
1347     ierr = MatSetValues(mat,bs*m,iidxm,bs*n,iidxn,v,addv);CHKERRQ(ierr);
1348     ierr = PetscFree2(iidxm,iidxn);CHKERRQ(ierr);
1349   }
1350   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1351   PetscFunctionReturn(0);
1352 }
1353 
1354 #undef __FUNCT__
1355 #define __FUNCT__ "MatGetValues"
1356 /*@
1357    MatGetValues - Gets a block of values from a matrix.
1358 
1359    Not Collective; currently only returns a local block
1360 
1361    Input Parameters:
1362 +  mat - the matrix
1363 .  v - a logically two-dimensional array for storing the values
1364 .  m, idxm - the number of rows and their global indices
1365 -  n, idxn - the number of columns and their global indices
1366 
1367    Notes:
1368    The user must allocate space (m*n PetscScalars) for the values, v.
1369    The values, v, are then returned in a row-oriented format,
1370    analogous to that used by default in MatSetValues().
1371 
1372    MatGetValues() uses 0-based row and column numbers in
1373    Fortran as well as in C.
1374 
1375    MatGetValues() requires that the matrix has been assembled
1376    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1377    MatSetValues() and MatGetValues() CANNOT be made in succession
1378    without intermediate matrix assembly.
1379 
1380    Negative row or column indices will be ignored and those locations in v[] will be
1381    left unchanged.
1382 
1383    Level: advanced
1384 
1385    Concepts: matrices^accessing values
1386 
1387 .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1388 @*/
1389 PetscErrorCode PETSCMAT_DLLEXPORT MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1390 {
1391   PetscErrorCode ierr;
1392 
1393   PetscFunctionBegin;
1394   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1395   PetscValidType(mat,1);
1396   PetscValidIntPointer(idxm,3);
1397   PetscValidIntPointer(idxn,5);
1398   PetscValidScalarPointer(v,6);
1399   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1400   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1401   if (!mat->ops->getvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1402   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1403 
1404   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1405   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1406   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1407   PetscFunctionReturn(0);
1408 }
1409 
1410 #undef __FUNCT__
1411 #define __FUNCT__ "MatSetLocalToGlobalMapping"
1412 /*@
1413    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1414    the routine MatSetValuesLocal() to allow users to insert matrix entries
1415    using a local (per-processor) numbering.
1416 
1417    Not Collective
1418 
1419    Input Parameters:
1420 +  x - the matrix
1421 -  mapping - mapping created with ISLocalToGlobalMappingCreate()
1422              or ISLocalToGlobalMappingCreateIS()
1423 
1424    Level: intermediate
1425 
1426    Concepts: matrices^local to global mapping
1427    Concepts: local to global mapping^for matrices
1428 
1429 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1430 @*/
1431 PetscErrorCode PETSCMAT_DLLEXPORT MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping mapping)
1432 {
1433   PetscErrorCode ierr;
1434   PetscFunctionBegin;
1435   PetscValidHeaderSpecific(x,MAT_COOKIE,1);
1436   PetscValidType(x,1);
1437   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE,2);
1438   if (x->mapping) {
1439     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1440   }
1441   ierr = MatPreallocated(x);CHKERRQ(ierr);
1442 
1443   if (x->ops->setlocaltoglobalmapping) {
1444     ierr = (*x->ops->setlocaltoglobalmapping)(x,mapping);CHKERRQ(ierr);
1445   } else {
1446     ierr = PetscObjectReference((PetscObject)mapping);CHKERRQ(ierr);
1447     if (x->mapping) { ierr = ISLocalToGlobalMappingDestroy(x->mapping);CHKERRQ(ierr); }
1448     x->mapping = mapping;
1449   }
1450   PetscFunctionReturn(0);
1451 }
1452 
1453 #undef __FUNCT__
1454 #define __FUNCT__ "MatSetLocalToGlobalMappingBlock"
1455 /*@
1456    MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
1457    by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
1458    entries using a local (per-processor) numbering.
1459 
1460    Not Collective
1461 
1462    Input Parameters:
1463 +  x - the matrix
1464 -  mapping - mapping created with ISLocalToGlobalMappingCreate() or
1465              ISLocalToGlobalMappingCreateIS()
1466 
1467    Level: intermediate
1468 
1469    Concepts: matrices^local to global mapping blocked
1470    Concepts: local to global mapping^for matrices, blocked
1471 
1472 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1473            MatSetValuesBlocked(), MatSetValuesLocal()
1474 @*/
1475 PetscErrorCode PETSCMAT_DLLEXPORT MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping mapping)
1476 {
1477   PetscErrorCode ierr;
1478   PetscFunctionBegin;
1479   PetscValidHeaderSpecific(x,MAT_COOKIE,1);
1480   PetscValidType(x,1);
1481   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE,2);
1482   if (x->bmapping) {
1483     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1484   }
1485   ierr = PetscObjectReference((PetscObject)mapping);CHKERRQ(ierr);
1486   if (x->bmapping) { ierr = ISLocalToGlobalMappingDestroy(x->mapping);CHKERRQ(ierr); }
1487   x->bmapping = mapping;
1488   PetscFunctionReturn(0);
1489 }
1490 
1491 #undef __FUNCT__
1492 #define __FUNCT__ "MatSetValuesLocal"
1493 /*@
1494    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1495    using a local ordering of the nodes.
1496 
1497    Not Collective
1498 
1499    Input Parameters:
1500 +  x - the matrix
1501 .  nrow, irow - number of rows and their local indices
1502 .  ncol, icol - number of columns and their local indices
1503 .  y -  a logically two-dimensional array of values
1504 -  addv - either INSERT_VALUES or ADD_VALUES, where
1505    ADD_VALUES adds values to any existing entries, and
1506    INSERT_VALUES replaces existing entries with new values
1507 
1508    Notes:
1509    Before calling MatSetValuesLocal(), the user must first set the
1510    local-to-global mapping by calling MatSetLocalToGlobalMapping().
1511 
1512    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
1513    options cannot be mixed without intervening calls to the assembly
1514    routines.
1515 
1516    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1517    MUST be called after all calls to MatSetValuesLocal() have been completed.
1518 
1519    Level: intermediate
1520 
1521    Concepts: matrices^putting entries in with local numbering
1522 
1523 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1524            MatSetValueLocal()
1525 @*/
1526 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1527 {
1528   PetscErrorCode ierr;
1529   PetscInt       irowm[2048],icolm[2048];
1530 
1531   PetscFunctionBegin;
1532   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1533   PetscValidType(mat,1);
1534   PetscValidIntPointer(irow,3);
1535   PetscValidIntPointer(icol,5);
1536   PetscValidScalarPointer(y,6);
1537   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1538   if (mat->insertmode == NOT_SET_VALUES) {
1539     mat->insertmode = addv;
1540   }
1541 #if defined(PETSC_USE_DEBUG)
1542   else if (mat->insertmode != addv) {
1543     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1544   }
1545   if (!mat->ops->setvalueslocal && (nrow > 2048 || ncol > 2048)) {
1546     SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %D %D",nrow,ncol);
1547   }
1548   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1549 #endif
1550 
1551   if (mat->assembled) {
1552     mat->was_assembled = PETSC_TRUE;
1553     mat->assembled     = PETSC_FALSE;
1554   }
1555   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1556   if (!mat->ops->setvalueslocal) {
1557     ierr = ISLocalToGlobalMappingApply(mat->mapping,nrow,irow,irowm);CHKERRQ(ierr);
1558     ierr = ISLocalToGlobalMappingApply(mat->mapping,ncol,icol,icolm);CHKERRQ(ierr);
1559     ierr = (*mat->ops->setvalues)(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
1560   } else {
1561     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
1562   }
1563   mat->same_nonzero = PETSC_FALSE;
1564   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1565   PetscFunctionReturn(0);
1566 }
1567 
1568 #undef __FUNCT__
1569 #define __FUNCT__ "MatSetValuesBlockedLocal"
1570 /*@
1571    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
1572    using a local ordering of the nodes a block at a time.
1573 
1574    Not Collective
1575 
1576    Input Parameters:
1577 +  x - the matrix
1578 .  nrow, irow - number of rows and their local indices
1579 .  ncol, icol - number of columns and their local indices
1580 .  y -  a logically two-dimensional array of values
1581 -  addv - either INSERT_VALUES or ADD_VALUES, where
1582    ADD_VALUES adds values to any existing entries, and
1583    INSERT_VALUES replaces existing entries with new values
1584 
1585    Notes:
1586    Before calling MatSetValuesBlockedLocal(), the user must first set the
1587    local-to-global mapping by calling MatSetLocalToGlobalMappingBlock(),
1588    where the mapping MUST be set for matrix blocks, not for matrix elements.
1589 
1590    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
1591    options cannot be mixed without intervening calls to the assembly
1592    routines.
1593 
1594    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1595    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
1596 
1597    Level: intermediate
1598 
1599    Concepts: matrices^putting blocked values in with local numbering
1600 
1601 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
1602 @*/
1603 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1604 {
1605   PetscErrorCode ierr;
1606   PetscInt       irowm[2048],icolm[2048];
1607 
1608   PetscFunctionBegin;
1609   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1610   PetscValidType(mat,1);
1611   PetscValidIntPointer(irow,3);
1612   PetscValidIntPointer(icol,5);
1613   PetscValidScalarPointer(y,6);
1614   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1615   if (mat->insertmode == NOT_SET_VALUES) {
1616     mat->insertmode = addv;
1617   }
1618 #if defined(PETSC_USE_DEBUG)
1619   else if (mat->insertmode != addv) {
1620     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1621   }
1622   if (!mat->bmapping) {
1623     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with MatSetLocalToGlobalMappingBlock()");
1624   }
1625   if (nrow > 2048 || ncol > 2048) {
1626     SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %D %D",nrow,ncol);
1627   }
1628   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1629 #endif
1630 
1631   if (mat->assembled) {
1632     mat->was_assembled = PETSC_TRUE;
1633     mat->assembled     = PETSC_FALSE;
1634   }
1635   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1636   ierr = ISLocalToGlobalMappingApply(mat->bmapping,nrow,irow,irowm);CHKERRQ(ierr);
1637   ierr = ISLocalToGlobalMappingApply(mat->bmapping,ncol,icol,icolm);CHKERRQ(ierr);
1638   if (mat->ops->setvaluesblocked) {
1639   ierr = (*mat->ops->setvaluesblocked)(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
1640   } else {
1641     PetscInt i,j,*iirowm,*iicolm,bs = mat->rmap.bs;
1642     ierr = PetscMalloc2(nrow*bs,PetscInt,&iirowm,ncol*bs,PetscInt,&iicolm);CHKERRQ(ierr);
1643     for (i=0; i<nrow; i++) {
1644       for (j=0; j<bs; j++) {
1645 	iirowm[i*bs+j] = bs*irowm[i] + j;
1646       }
1647     }
1648     for (i=0; i<ncol; i++) {
1649       for (j=0; j<bs; j++) {
1650 	iicolm[i*bs+j] = bs*icolm[i] + j;
1651       }
1652     }
1653     ierr = MatSetValues(mat,bs*nrow,iirowm,bs*ncol,iicolm,y,addv);CHKERRQ(ierr);
1654     ierr = PetscFree2(iirowm,iicolm);CHKERRQ(ierr);
1655 
1656   }
1657   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1658   PetscFunctionReturn(0);
1659 }
1660 
1661 /* --------------------------------------------------------*/
1662 #undef __FUNCT__
1663 #define __FUNCT__ "MatMult"
1664 /*@
1665    MatMult - Computes the matrix-vector product, y = Ax.
1666 
1667    Collective on Mat and Vec
1668 
1669    Input Parameters:
1670 +  mat - the matrix
1671 -  x   - the vector to be multiplied
1672 
1673    Output Parameters:
1674 .  y - the result
1675 
1676    Notes:
1677    The vectors x and y cannot be the same.  I.e., one cannot
1678    call MatMult(A,y,y).
1679 
1680    Level: beginner
1681 
1682    Concepts: matrix-vector product
1683 
1684 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
1685 @*/
1686 PetscErrorCode PETSCMAT_DLLEXPORT MatMult(Mat mat,Vec x,Vec y)
1687 {
1688   PetscErrorCode ierr;
1689 
1690   PetscFunctionBegin;
1691   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1692   PetscValidType(mat,1);
1693   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1694   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1695 
1696   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1697   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1698   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1699 #ifndef PETSC_HAVE_CONSTRAINTS
1700   if (mat->cmap.N != x->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap.N,x->map.N);
1701   if (mat->rmap.N != y->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap.N,y->map.N);
1702   if (mat->rmap.n != y->map.n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap.n,y->map.n);
1703 #endif
1704   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1705 
1706   if (mat->nullsp) {
1707     ierr = MatNullSpaceRemove(mat->nullsp,x,&x);CHKERRQ(ierr);
1708   }
1709 
1710   if (!mat->ops->mult) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
1711   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
1712   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
1713   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
1714 
1715   if (mat->nullsp) {
1716     ierr = MatNullSpaceRemove(mat->nullsp,y,PETSC_NULL);CHKERRQ(ierr);
1717   }
1718   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
1719   PetscFunctionReturn(0);
1720 }
1721 
1722 #undef __FUNCT__
1723 #define __FUNCT__ "MatMultTranspose"
1724 /*@
1725    MatMultTranspose - Computes matrix transpose times a vector.
1726 
1727    Collective on Mat and Vec
1728 
1729    Input Parameters:
1730 +  mat - the matrix
1731 -  x   - the vector to be multilplied
1732 
1733    Output Parameters:
1734 .  y - the result
1735 
1736    Notes:
1737    The vectors x and y cannot be the same.  I.e., one cannot
1738    call MatMultTranspose(A,y,y).
1739 
1740    Level: beginner
1741 
1742    Concepts: matrix vector product^transpose
1743 
1744 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd()
1745 @*/
1746 PetscErrorCode PETSCMAT_DLLEXPORT MatMultTranspose(Mat mat,Vec x,Vec y)
1747 {
1748   PetscErrorCode ierr;
1749 
1750   PetscFunctionBegin;
1751   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1752   PetscValidType(mat,1);
1753   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1754   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1755 
1756   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1757   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1758   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1759 #ifndef PETSC_HAVE_CONSTRAINTS
1760   if (mat->rmap.N != x->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap.N,x->map.N);
1761   if (mat->cmap.N != y->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap.N,y->map.N);
1762 #endif
1763   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1764 
1765   if (!mat->ops->multtranspose) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
1766   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
1767   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
1768   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
1769   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
1770   PetscFunctionReturn(0);
1771 }
1772 
1773 #undef __FUNCT__
1774 #define __FUNCT__ "MatMultAdd"
1775 /*@
1776     MatMultAdd -  Computes v3 = v2 + A * v1.
1777 
1778     Collective on Mat and Vec
1779 
1780     Input Parameters:
1781 +   mat - the matrix
1782 -   v1, v2 - the vectors
1783 
1784     Output Parameters:
1785 .   v3 - the result
1786 
1787     Notes:
1788     The vectors v1 and v3 cannot be the same.  I.e., one cannot
1789     call MatMultAdd(A,v1,v2,v1).
1790 
1791     Level: beginner
1792 
1793     Concepts: matrix vector product^addition
1794 
1795 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
1796 @*/
1797 PetscErrorCode PETSCMAT_DLLEXPORT MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1798 {
1799   PetscErrorCode ierr;
1800 
1801   PetscFunctionBegin;
1802   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1803   PetscValidType(mat,1);
1804   PetscValidHeaderSpecific(v1,VEC_COOKIE,2);
1805   PetscValidHeaderSpecific(v2,VEC_COOKIE,3);
1806   PetscValidHeaderSpecific(v3,VEC_COOKIE,4);
1807 
1808   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1809   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1810   if (mat->cmap.N != v1->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap.N,v1->map.N);
1811   if (mat->rmap.N != v2->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->rmap.N,v2->map.N);
1812   if (mat->rmap.N != v3->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->rmap.N,v3->map.N);
1813   if (mat->rmap.n != v3->map.n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %D %D",mat->rmap.n,v3->map.n);
1814   if (mat->rmap.n != v2->map.n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %D %D",mat->rmap.n,v2->map.n);
1815   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1816   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1817 
1818   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1819   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
1820   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1821   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
1822   PetscFunctionReturn(0);
1823 }
1824 
1825 #undef __FUNCT__
1826 #define __FUNCT__ "MatMultTransposeAdd"
1827 /*@
1828    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
1829 
1830    Collective on Mat and Vec
1831 
1832    Input Parameters:
1833 +  mat - the matrix
1834 -  v1, v2 - the vectors
1835 
1836    Output Parameters:
1837 .  v3 - the result
1838 
1839    Notes:
1840    The vectors v1 and v3 cannot be the same.  I.e., one cannot
1841    call MatMultTransposeAdd(A,v1,v2,v1).
1842 
1843    Level: beginner
1844 
1845    Concepts: matrix vector product^transpose and addition
1846 
1847 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
1848 @*/
1849 PetscErrorCode PETSCMAT_DLLEXPORT MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1850 {
1851   PetscErrorCode ierr;
1852 
1853   PetscFunctionBegin;
1854   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1855   PetscValidType(mat,1);
1856   PetscValidHeaderSpecific(v1,VEC_COOKIE,2);
1857   PetscValidHeaderSpecific(v2,VEC_COOKIE,3);
1858   PetscValidHeaderSpecific(v3,VEC_COOKIE,4);
1859 
1860   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1861   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1862   if (!mat->ops->multtransposeadd) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1863   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1864   if (mat->rmap.N != v1->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap.N,v1->map.N);
1865   if (mat->cmap.N != v2->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap.N,v2->map.N);
1866   if (mat->cmap.N != v3->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap.N,v3->map.N);
1867   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1868 
1869   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1870   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
1871   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1872   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
1873   PetscFunctionReturn(0);
1874 }
1875 
1876 #undef __FUNCT__
1877 #define __FUNCT__ "MatMultConstrained"
1878 /*@
1879    MatMultConstrained - The inner multiplication routine for a
1880    constrained matrix P^T A P.
1881 
1882    Collective on Mat and Vec
1883 
1884    Input Parameters:
1885 +  mat - the matrix
1886 -  x   - the vector to be multilplied
1887 
1888    Output Parameters:
1889 .  y - the result
1890 
1891    Notes:
1892    The vectors x and y cannot be the same.  I.e., one cannot
1893    call MatMult(A,y,y).
1894 
1895    Level: beginner
1896 
1897 .keywords: matrix, multiply, matrix-vector product, constraint
1898 .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1899 @*/
1900 PetscErrorCode PETSCMAT_DLLEXPORT MatMultConstrained(Mat mat,Vec x,Vec y)
1901 {
1902   PetscErrorCode ierr;
1903 
1904   PetscFunctionBegin;
1905   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1906   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1907   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1908   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1909   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1910   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1911   if (mat->cmap.N != x->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap.N,x->map.N);
1912   if (mat->rmap.N != y->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap.N,y->map.N);
1913   if (mat->rmap.n != y->map.n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap.n,y->map.n);
1914 
1915   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1916   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
1917   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1918   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
1919 
1920   PetscFunctionReturn(0);
1921 }
1922 
1923 #undef __FUNCT__
1924 #define __FUNCT__ "MatMultTransposeConstrained"
1925 /*@
1926    MatMultTransposeConstrained - The inner multiplication routine for a
1927    constrained matrix P^T A^T P.
1928 
1929    Collective on Mat and Vec
1930 
1931    Input Parameters:
1932 +  mat - the matrix
1933 -  x   - the vector to be multilplied
1934 
1935    Output Parameters:
1936 .  y - the result
1937 
1938    Notes:
1939    The vectors x and y cannot be the same.  I.e., one cannot
1940    call MatMult(A,y,y).
1941 
1942    Level: beginner
1943 
1944 .keywords: matrix, multiply, matrix-vector product, constraint
1945 .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1946 @*/
1947 PetscErrorCode PETSCMAT_DLLEXPORT MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
1948 {
1949   PetscErrorCode ierr;
1950 
1951   PetscFunctionBegin;
1952   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1953   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1954   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1955   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1956   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1957   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1958   if (mat->rmap.N != x->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap.N,x->map.N);
1959   if (mat->cmap.N != y->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap.N,y->map.N);
1960 
1961   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1962   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
1963   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1964   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
1965 
1966   PetscFunctionReturn(0);
1967 }
1968 /* ------------------------------------------------------------*/
1969 #undef __FUNCT__
1970 #define __FUNCT__ "MatGetInfo"
1971 /*@
1972    MatGetInfo - Returns information about matrix storage (number of
1973    nonzeros, memory, etc.).
1974 
1975    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used
1976    as the flag
1977 
1978    Input Parameters:
1979 .  mat - the matrix
1980 
1981    Output Parameters:
1982 +  flag - flag indicating the type of parameters to be returned
1983    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
1984    MAT_GLOBAL_SUM - sum over all processors)
1985 -  info - matrix information context
1986 
1987    Notes:
1988    The MatInfo context contains a variety of matrix data, including
1989    number of nonzeros allocated and used, number of mallocs during
1990    matrix assembly, etc.  Additional information for factored matrices
1991    is provided (such as the fill ratio, number of mallocs during
1992    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
1993    when using the runtime options
1994 $       -info -mat_view_info
1995 
1996    Example for C/C++ Users:
1997    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
1998    data within the MatInfo context.  For example,
1999 .vb
2000       MatInfo info;
2001       Mat     A;
2002       double  mal, nz_a, nz_u;
2003 
2004       MatGetInfo(A,MAT_LOCAL,&info);
2005       mal  = info.mallocs;
2006       nz_a = info.nz_allocated;
2007 .ve
2008 
2009    Example for Fortran Users:
2010    Fortran users should declare info as a double precision
2011    array of dimension MAT_INFO_SIZE, and then extract the parameters
2012    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
2013    a complete list of parameter names.
2014 .vb
2015       double  precision info(MAT_INFO_SIZE)
2016       double  precision mal, nz_a
2017       Mat     A
2018       integer ierr
2019 
2020       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2021       mal = info(MAT_INFO_MALLOCS)
2022       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2023 .ve
2024 
2025     Level: intermediate
2026 
2027     Concepts: matrices^getting information on
2028 
2029 @*/
2030 PetscErrorCode PETSCMAT_DLLEXPORT MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2031 {
2032   PetscErrorCode ierr;
2033 
2034   PetscFunctionBegin;
2035   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2036   PetscValidType(mat,1);
2037   PetscValidPointer(info,3);
2038   if (!mat->ops->getinfo) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2039   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2040   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2041   PetscFunctionReturn(0);
2042 }
2043 
2044 /* ----------------------------------------------------------*/
2045 #undef __FUNCT__
2046 #define __FUNCT__ "MatILUDTFactor"
2047 /*@C
2048    MatILUDTFactor - Performs a drop tolerance ILU factorization.
2049 
2050    Collective on Mat
2051 
2052    Input Parameters:
2053 +  mat - the matrix
2054 .  row - row permutation
2055 .  col - column permutation
2056 -  info - information about the factorization to be done
2057 
2058    Output Parameters:
2059 .  fact - the factored matrix
2060 
2061    Level: developer
2062 
2063    Notes:
2064    Most users should employ the simplified KSP interface for linear solvers
2065    instead of working directly with matrix algebra routines such as this.
2066    See, e.g., KSPCreate().
2067 
2068    This is currently only supported for the SeqAIJ matrix format using code
2069    from Yousef Saad's SPARSEKIT2  package (translated to C with f2c) and/or
2070    Matlab. SPARSEKIT2 is copyrighted by Yousef Saad with the GNU copyright
2071    and thus can be distributed with PETSc.
2072 
2073     Concepts: matrices^ILUDT factorization
2074 
2075 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2076 @*/
2077 PetscErrorCode PETSCMAT_DLLEXPORT MatILUDTFactor(Mat mat,IS row,IS col,MatFactorInfo *info,Mat *fact)
2078 {
2079   PetscErrorCode ierr;
2080 
2081   PetscFunctionBegin;
2082   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2083   PetscValidType(mat,1);
2084   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
2085   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
2086   PetscValidPointer(info,4);
2087   PetscValidPointer(fact,5);
2088   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2089   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2090   if (!mat->ops->iludtfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2091   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2092   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2093   ierr = (*mat->ops->iludtfactor)(mat,row,col,info,fact);CHKERRQ(ierr);
2094   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2095   ierr = PetscObjectStateIncrease((PetscObject)*fact);CHKERRQ(ierr);
2096 
2097   PetscFunctionReturn(0);
2098 }
2099 
2100 #undef __FUNCT__
2101 #define __FUNCT__ "MatLUFactor"
2102 /*@
2103    MatLUFactor - Performs in-place LU factorization of matrix.
2104 
2105    Collective on Mat
2106 
2107    Input Parameters:
2108 +  mat - the matrix
2109 .  row - row permutation
2110 .  col - column permutation
2111 -  info - options for factorization, includes
2112 $          fill - expected fill as ratio of original fill.
2113 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2114 $                   Run with the option -info to determine an optimal value to use
2115 
2116    Notes:
2117    Most users should employ the simplified KSP interface for linear solvers
2118    instead of working directly with matrix algebra routines such as this.
2119    See, e.g., KSPCreate().
2120 
2121    This changes the state of the matrix to a factored matrix; it cannot be used
2122    for example with MatSetValues() unless one first calls MatSetUnfactored().
2123 
2124    Level: developer
2125 
2126    Concepts: matrices^LU factorization
2127 
2128 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2129           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo
2130 
2131 @*/
2132 PetscErrorCode PETSCMAT_DLLEXPORT MatLUFactor(Mat mat,IS row,IS col,MatFactorInfo *info)
2133 {
2134   PetscErrorCode ierr;
2135 
2136   PetscFunctionBegin;
2137   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2138   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
2139   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
2140   PetscValidPointer(info,4);
2141   PetscValidType(mat,1);
2142   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2143   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2144   if (!mat->ops->lufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2145   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2146 
2147   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2148   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
2149   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2150   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2151   PetscFunctionReturn(0);
2152 }
2153 
2154 #undef __FUNCT__
2155 #define __FUNCT__ "MatILUFactor"
2156 /*@
2157    MatILUFactor - Performs in-place ILU factorization of matrix.
2158 
2159    Collective on Mat
2160 
2161    Input Parameters:
2162 +  mat - the matrix
2163 .  row - row permutation
2164 .  col - column permutation
2165 -  info - structure containing
2166 $      levels - number of levels of fill.
2167 $      expected fill - as ratio of original fill.
2168 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2169                 missing diagonal entries)
2170 
2171    Notes:
2172    Probably really in-place only when level of fill is zero, otherwise allocates
2173    new space to store factored matrix and deletes previous memory.
2174 
2175    Most users should employ the simplified KSP interface for linear solvers
2176    instead of working directly with matrix algebra routines such as this.
2177    See, e.g., KSPCreate().
2178 
2179    Level: developer
2180 
2181    Concepts: matrices^ILU factorization
2182 
2183 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2184 @*/
2185 PetscErrorCode PETSCMAT_DLLEXPORT MatILUFactor(Mat mat,IS row,IS col,MatFactorInfo *info)
2186 {
2187   PetscErrorCode ierr;
2188 
2189   PetscFunctionBegin;
2190   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2191   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
2192   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
2193   PetscValidPointer(info,4);
2194   PetscValidType(mat,1);
2195   if (mat->rmap.N != mat->cmap.N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
2196   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2197   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2198   if (!mat->ops->ilufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2199   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2200 
2201   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2202   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
2203   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2204   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2205   PetscFunctionReturn(0);
2206 }
2207 
2208 #undef __FUNCT__
2209 #define __FUNCT__ "MatLUFactorSymbolic"
2210 /*@
2211    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2212    Call this routine before calling MatLUFactorNumeric().
2213 
2214    Collective on Mat
2215 
2216    Input Parameters:
2217 +  mat - the matrix
2218 .  row, col - row and column permutations
2219 -  info - options for factorization, includes
2220 $          fill - expected fill as ratio of original fill.
2221 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2222 $                   Run with the option -info to determine an optimal value to use
2223 
2224    Output Parameter:
2225 .  fact - new matrix that has been symbolically factored
2226 
2227    Notes:
2228    See the users manual for additional information about
2229    choosing the fill factor for better efficiency.
2230 
2231    Most users should employ the simplified KSP interface for linear solvers
2232    instead of working directly with matrix algebra routines such as this.
2233    See, e.g., KSPCreate().
2234 
2235    Level: developer
2236 
2237    Concepts: matrices^LU symbolic factorization
2238 
2239 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2240 @*/
2241 PetscErrorCode PETSCMAT_DLLEXPORT MatLUFactorSymbolic(Mat mat,IS row,IS col,MatFactorInfo *info,Mat *fact)
2242 {
2243   PetscErrorCode ierr;
2244 
2245   PetscFunctionBegin;
2246   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2247   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
2248   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
2249   PetscValidPointer(info,4);
2250   PetscValidType(mat,1);
2251   PetscValidPointer(fact,5);
2252   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2253   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2254   if (!mat->ops->lufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic LU",((PetscObject)mat)->type_name);
2255   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2256 
2257   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
2258   ierr = (*mat->ops->lufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
2259   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
2260   ierr = PetscObjectStateIncrease((PetscObject)*fact);CHKERRQ(ierr);
2261   PetscFunctionReturn(0);
2262 }
2263 
2264 #undef __FUNCT__
2265 #define __FUNCT__ "MatLUFactorNumeric"
2266 /*@
2267    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2268    Call this routine after first calling MatLUFactorSymbolic().
2269 
2270    Collective on Mat
2271 
2272    Input Parameters:
2273 +  mat - the matrix
2274 .  info - options for factorization
2275 -  fact - the matrix generated for the factor, from MatLUFactorSymbolic()
2276 
2277    Notes:
2278    See MatLUFactor() for in-place factorization.  See
2279    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
2280 
2281    Most users should employ the simplified KSP interface for linear solvers
2282    instead of working directly with matrix algebra routines such as this.
2283    See, e.g., KSPCreate().
2284 
2285    Level: developer
2286 
2287    Concepts: matrices^LU numeric factorization
2288 
2289 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
2290 @*/
2291 PetscErrorCode PETSCMAT_DLLEXPORT MatLUFactorNumeric(Mat mat,MatFactorInfo *info,Mat *fact)
2292 {
2293   PetscErrorCode ierr;
2294 
2295   PetscFunctionBegin;
2296   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2297   PetscValidType(mat,1);
2298   PetscValidPointer(fact,2);
2299   PetscValidHeaderSpecific(*fact,MAT_COOKIE,2);
2300   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2301   if (mat->rmap.N != (*fact)->rmap.N || mat->cmap.N != (*fact)->cmap.N) {
2302     SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat *fact: global dimensions are different %D should = %D %D should = %D",mat->rmap.N,(*fact)->rmap.N,mat->cmap.N,(*fact)->cmap.N);
2303   }
2304   if (!(*fact)->ops->lufactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2305   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2306   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
2307   ierr = (*(*fact)->ops->lufactornumeric)(mat,info,fact);CHKERRQ(ierr);
2308   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
2309 
2310   ierr = MatView_Private(*fact);CHKERRQ(ierr);
2311   ierr = PetscObjectStateIncrease((PetscObject)*fact);CHKERRQ(ierr);
2312   PetscFunctionReturn(0);
2313 }
2314 
2315 #undef __FUNCT__
2316 #define __FUNCT__ "MatCholeskyFactor"
2317 /*@
2318    MatCholeskyFactor - Performs in-place Cholesky factorization of a
2319    symmetric matrix.
2320 
2321    Collective on Mat
2322 
2323    Input Parameters:
2324 +  mat - the matrix
2325 .  perm - row and column permutations
2326 -  f - expected fill as ratio of original fill
2327 
2328    Notes:
2329    See MatLUFactor() for the nonsymmetric case.  See also
2330    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
2331 
2332    Most users should employ the simplified KSP interface for linear solvers
2333    instead of working directly with matrix algebra routines such as this.
2334    See, e.g., KSPCreate().
2335 
2336    Level: developer
2337 
2338    Concepts: matrices^Cholesky factorization
2339 
2340 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2341           MatGetOrdering()
2342 
2343 @*/
2344 PetscErrorCode PETSCMAT_DLLEXPORT MatCholeskyFactor(Mat mat,IS perm,MatFactorInfo *info)
2345 {
2346   PetscErrorCode ierr;
2347 
2348   PetscFunctionBegin;
2349   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2350   PetscValidType(mat,1);
2351   PetscValidHeaderSpecific(perm,IS_COOKIE,2);
2352   PetscValidPointer(info,3);
2353   if (mat->rmap.N != mat->cmap.N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
2354   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2355   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2356   if (!mat->ops->choleskyfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2357   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2358 
2359   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
2360   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
2361   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
2362   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2363   PetscFunctionReturn(0);
2364 }
2365 
2366 #undef __FUNCT__
2367 #define __FUNCT__ "MatCholeskyFactorSymbolic"
2368 /*@
2369    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2370    of a symmetric matrix.
2371 
2372    Collective on Mat
2373 
2374    Input Parameters:
2375 +  mat - the matrix
2376 .  perm - row and column permutations
2377 -  info - options for factorization, includes
2378 $          fill - expected fill as ratio of original fill.
2379 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2380 $                   Run with the option -info to determine an optimal value to use
2381 
2382    Output Parameter:
2383 .  fact - the factored matrix
2384 
2385    Notes:
2386    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
2387    MatCholeskyFactor() and MatCholeskyFactorNumeric().
2388 
2389    Most users should employ the simplified KSP interface for linear solvers
2390    instead of working directly with matrix algebra routines such as this.
2391    See, e.g., KSPCreate().
2392 
2393    Level: developer
2394 
2395    Concepts: matrices^Cholesky symbolic factorization
2396 
2397 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2398           MatGetOrdering()
2399 
2400 @*/
2401 PetscErrorCode PETSCMAT_DLLEXPORT MatCholeskyFactorSymbolic(Mat mat,IS perm,MatFactorInfo *info,Mat *fact)
2402 {
2403   PetscErrorCode ierr;
2404 
2405   PetscFunctionBegin;
2406   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2407   PetscValidType(mat,1);
2408   if (perm) PetscValidHeaderSpecific(perm,IS_COOKIE,2);
2409   PetscValidPointer(info,3);
2410   PetscValidPointer(fact,4);
2411   if (mat->rmap.N != mat->cmap.N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
2412   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2413   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2414   if (!mat->ops->choleskyfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2415   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2416 
2417   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
2418   ierr = (*mat->ops->choleskyfactorsymbolic)(mat,perm,info,fact);CHKERRQ(ierr);
2419   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
2420   ierr = PetscObjectStateIncrease((PetscObject)*fact);CHKERRQ(ierr);
2421   PetscFunctionReturn(0);
2422 }
2423 
2424 #undef __FUNCT__
2425 #define __FUNCT__ "MatCholeskyFactorNumeric"
2426 /*@
2427    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
2428    of a symmetric matrix. Call this routine after first calling
2429    MatCholeskyFactorSymbolic().
2430 
2431    Collective on Mat
2432 
2433    Input Parameter:
2434 .  mat - the initial matrix
2435 .  info - options for factorization
2436 -  fact - the symbolic factor of mat
2437 
2438    Output Parameter:
2439 .  fact - the factored matrix
2440 
2441    Notes:
2442    Most users should employ the simplified KSP interface for linear solvers
2443    instead of working directly with matrix algebra routines such as this.
2444    See, e.g., KSPCreate().
2445 
2446    Level: developer
2447 
2448    Concepts: matrices^Cholesky numeric factorization
2449 
2450 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
2451 @*/
2452 PetscErrorCode PETSCMAT_DLLEXPORT MatCholeskyFactorNumeric(Mat mat,MatFactorInfo *info,Mat *fact)
2453 {
2454   PetscErrorCode ierr;
2455 
2456   PetscFunctionBegin;
2457   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2458   PetscValidType(mat,1);
2459   PetscValidPointer(fact,2);
2460   PetscValidHeaderSpecific(*fact,MAT_COOKIE,2);
2461   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2462   if (!(*fact)->ops->choleskyfactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2463   if (mat->rmap.N != (*fact)->rmap.N || mat->cmap.N != (*fact)->cmap.N) {
2464     SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat *fact: global dim %D should = %D %D should = %D",mat->rmap.N,(*fact)->rmap.N,mat->cmap.N,(*fact)->cmap.N);
2465   }
2466   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2467 
2468   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
2469   ierr = (*(*fact)->ops->choleskyfactornumeric)(mat,info,fact);CHKERRQ(ierr);
2470   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
2471 
2472   ierr = MatView_Private(*fact);CHKERRQ(ierr);
2473   ierr = PetscObjectStateIncrease((PetscObject)*fact);CHKERRQ(ierr);
2474   PetscFunctionReturn(0);
2475 }
2476 
2477 /* ----------------------------------------------------------------*/
2478 #undef __FUNCT__
2479 #define __FUNCT__ "MatSolve"
2480 /*@
2481    MatSolve - Solves A x = b, given a factored matrix.
2482 
2483    Collective on Mat and Vec
2484 
2485    Input Parameters:
2486 +  mat - the factored matrix
2487 -  b - the right-hand-side vector
2488 
2489    Output Parameter:
2490 .  x - the result vector
2491 
2492    Notes:
2493    The vectors b and x cannot be the same.  I.e., one cannot
2494    call MatSolve(A,x,x).
2495 
2496    Notes:
2497    Most users should employ the simplified KSP interface for linear solvers
2498    instead of working directly with matrix algebra routines such as this.
2499    See, e.g., KSPCreate().
2500 
2501    Level: developer
2502 
2503    Concepts: matrices^triangular solves
2504 
2505 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
2506 @*/
2507 PetscErrorCode PETSCMAT_DLLEXPORT MatSolve(Mat mat,Vec b,Vec x)
2508 {
2509   PetscErrorCode ierr;
2510 
2511   PetscFunctionBegin;
2512   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2513   PetscValidType(mat,1);
2514   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2515   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2516   PetscCheckSameComm(mat,1,b,2);
2517   PetscCheckSameComm(mat,1,x,3);
2518   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2519   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2520   if (mat->cmap.N != x->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap.N,x->map.N);
2521   if (mat->rmap.N != b->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap.N,b->map.N);
2522   if (mat->rmap.n != b->map.n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap.n,b->map.n);
2523   if (!mat->rmap.N && !mat->cmap.N) PetscFunctionReturn(0);
2524   if (!mat->ops->solve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2525   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2526 
2527   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
2528   ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
2529   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
2530   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2531   PetscFunctionReturn(0);
2532 }
2533 
2534 #undef __FUNCT__
2535 #define __FUNCT__ "MatMatSolve_Basic"
2536 PetscErrorCode PETSCMAT_DLLEXPORT MatMatSolve_Basic(Mat A,Mat B,Mat X)
2537 {
2538   PetscErrorCode ierr;
2539   Vec            b,x;
2540   PetscInt       m,N,i;
2541   PetscScalar    *bb,*xx;
2542 
2543   PetscFunctionBegin;
2544   ierr = MatGetArray(B,&bb);CHKERRQ(ierr);
2545   ierr = MatGetArray(X,&xx);CHKERRQ(ierr);
2546   ierr = MatGetLocalSize(B,&m,PETSC_NULL);CHKERRQ(ierr);  /* number local rows */
2547   ierr = MatGetSize(B,PETSC_NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
2548   ierr = VecCreateMPIWithArray(A->hdr.comm,m,PETSC_DETERMINE,PETSC_NULL,&b);CHKERRQ(ierr);
2549   ierr = VecCreateMPIWithArray(A->hdr.comm,m,PETSC_DETERMINE,PETSC_NULL,&x);CHKERRQ(ierr);
2550   for (i=0; i<N; i++) {
2551     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
2552     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
2553     ierr = MatSolve(A,b,x);CHKERRQ(ierr);
2554     ierr = VecResetArray(x);CHKERRQ(ierr);
2555     ierr = VecResetArray(b);CHKERRQ(ierr);
2556   }
2557   ierr = VecDestroy(b);CHKERRQ(ierr);
2558   ierr = VecDestroy(x);CHKERRQ(ierr);
2559   ierr = MatRestoreArray(B,&bb);CHKERRQ(ierr);
2560   ierr = MatRestoreArray(X,&xx);CHKERRQ(ierr);
2561   PetscFunctionReturn(0);
2562 }
2563 
2564 #undef __FUNCT__
2565 #define __FUNCT__ "MatMatSolve"
2566 /*@
2567    MatMatSolve - Solves A X = B, given a factored matrix.
2568 
2569    Collective on Mat
2570 
2571    Input Parameters:
2572 +  mat - the factored matrix
2573 -  B - the right-hand-side matrix  (dense matrix)
2574 
2575    Output Parameter:
2576 .  B - the result matrix (dense matrix)
2577 
2578    Notes:
2579    The matrices b and x cannot be the same.  I.e., one cannot
2580    call MatMatSolve(A,x,x).
2581 
2582    Notes:
2583    Most users should usually employ the simplified KSP interface for linear solvers
2584    instead of working directly with matrix algebra routines such as this.
2585    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
2586    at a time.
2587 
2588    Level: developer
2589 
2590    Concepts: matrices^triangular solves
2591 
2592 .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
2593 @*/
2594 PetscErrorCode PETSCMAT_DLLEXPORT MatMatSolve(Mat A,Mat B,Mat X)
2595 {
2596   PetscErrorCode ierr;
2597 
2598   PetscFunctionBegin;
2599   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
2600   PetscValidType(A,1);
2601   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
2602   PetscValidHeaderSpecific(X,MAT_COOKIE,3);
2603   PetscCheckSameComm(A,1,B,2);
2604   PetscCheckSameComm(A,1,X,3);
2605   if (X == B) SETERRQ(PETSC_ERR_ARG_IDN,"X and B must be different matrices");
2606   if (!A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2607   if (A->cmap.N != X->rmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap.N,X->rmap.N);
2608   if (A->rmap.N != B->rmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap.N,B->rmap.N);
2609   if (A->rmap.n != B->rmap.n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %D %D",A->rmap.n,B->rmap.n);
2610   if (!A->rmap.N && !A->cmap.N) PetscFunctionReturn(0);
2611   ierr = MatPreallocated(A);CHKERRQ(ierr);
2612 
2613   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
2614   if (!A->ops->matsolve) {
2615     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);CHKERRQ(ierr);
2616     ierr = MatMatSolve_Basic(A,B,X);CHKERRQ(ierr);
2617   } else {
2618     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
2619   }
2620   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
2621   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
2622   PetscFunctionReturn(0);
2623 }
2624 
2625 
2626 #undef __FUNCT__
2627 #define __FUNCT__ "MatForwardSolve"
2628 /* @
2629    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
2630                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
2631 
2632    Collective on Mat and Vec
2633 
2634    Input Parameters:
2635 +  mat - the factored matrix
2636 -  b - the right-hand-side vector
2637 
2638    Output Parameter:
2639 .  x - the result vector
2640 
2641    Notes:
2642    MatSolve() should be used for most applications, as it performs
2643    a forward solve followed by a backward solve.
2644 
2645    The vectors b and x cannot be the same,  i.e., one cannot
2646    call MatForwardSolve(A,x,x).
2647 
2648    For matrix in seqsbaij format with block size larger than 1,
2649    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
2650    MatForwardSolve() solves U^T*D y = b, and
2651    MatBackwardSolve() solves U x = y.
2652    Thus they do not provide a symmetric preconditioner.
2653 
2654    Most users should employ the simplified KSP interface for linear solvers
2655    instead of working directly with matrix algebra routines such as this.
2656    See, e.g., KSPCreate().
2657 
2658    Level: developer
2659 
2660    Concepts: matrices^forward solves
2661 
2662 .seealso: MatSolve(), MatBackwardSolve()
2663 @ */
2664 PetscErrorCode PETSCMAT_DLLEXPORT MatForwardSolve(Mat mat,Vec b,Vec x)
2665 {
2666   PetscErrorCode ierr;
2667 
2668   PetscFunctionBegin;
2669   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2670   PetscValidType(mat,1);
2671   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2672   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2673   PetscCheckSameComm(mat,1,b,2);
2674   PetscCheckSameComm(mat,1,x,3);
2675   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2676   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2677   if (!mat->ops->forwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2678   if (mat->cmap.N != x->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap.N,x->map.N);
2679   if (mat->rmap.N != b->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap.N,b->map.N);
2680   if (mat->rmap.n != b->map.n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap.n,b->map.n);
2681   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2682   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
2683   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
2684   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
2685   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2686   PetscFunctionReturn(0);
2687 }
2688 
2689 #undef __FUNCT__
2690 #define __FUNCT__ "MatBackwardSolve"
2691 /* @
2692    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
2693                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
2694 
2695    Collective on Mat and Vec
2696 
2697    Input Parameters:
2698 +  mat - the factored matrix
2699 -  b - the right-hand-side vector
2700 
2701    Output Parameter:
2702 .  x - the result vector
2703 
2704    Notes:
2705    MatSolve() should be used for most applications, as it performs
2706    a forward solve followed by a backward solve.
2707 
2708    The vectors b and x cannot be the same.  I.e., one cannot
2709    call MatBackwardSolve(A,x,x).
2710 
2711    For matrix in seqsbaij format with block size larger than 1,
2712    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
2713    MatForwardSolve() solves U^T*D y = b, and
2714    MatBackwardSolve() solves U x = y.
2715    Thus they do not provide a symmetric preconditioner.
2716 
2717    Most users should employ the simplified KSP interface for linear solvers
2718    instead of working directly with matrix algebra routines such as this.
2719    See, e.g., KSPCreate().
2720 
2721    Level: developer
2722 
2723    Concepts: matrices^backward solves
2724 
2725 .seealso: MatSolve(), MatForwardSolve()
2726 @ */
2727 PetscErrorCode PETSCMAT_DLLEXPORT MatBackwardSolve(Mat mat,Vec b,Vec x)
2728 {
2729   PetscErrorCode ierr;
2730 
2731   PetscFunctionBegin;
2732   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2733   PetscValidType(mat,1);
2734   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2735   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2736   PetscCheckSameComm(mat,1,b,2);
2737   PetscCheckSameComm(mat,1,x,3);
2738   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2739   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2740   if (!mat->ops->backwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2741   if (mat->cmap.N != x->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap.N,x->map.N);
2742   if (mat->rmap.N != b->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap.N,b->map.N);
2743   if (mat->rmap.n != b->map.n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap.n,b->map.n);
2744   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2745 
2746   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
2747   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
2748   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
2749   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2750   PetscFunctionReturn(0);
2751 }
2752 
2753 #undef __FUNCT__
2754 #define __FUNCT__ "MatSolveAdd"
2755 /*@
2756    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
2757 
2758    Collective on Mat and Vec
2759 
2760    Input Parameters:
2761 +  mat - the factored matrix
2762 .  b - the right-hand-side vector
2763 -  y - the vector to be added to
2764 
2765    Output Parameter:
2766 .  x - the result vector
2767 
2768    Notes:
2769    The vectors b and x cannot be the same.  I.e., one cannot
2770    call MatSolveAdd(A,x,y,x).
2771 
2772    Most users should employ the simplified KSP interface for linear solvers
2773    instead of working directly with matrix algebra routines such as this.
2774    See, e.g., KSPCreate().
2775 
2776    Level: developer
2777 
2778    Concepts: matrices^triangular solves
2779 
2780 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
2781 @*/
2782 PetscErrorCode PETSCMAT_DLLEXPORT MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
2783 {
2784   PetscScalar    one = 1.0;
2785   Vec            tmp;
2786   PetscErrorCode ierr;
2787 
2788   PetscFunctionBegin;
2789   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2790   PetscValidType(mat,1);
2791   PetscValidHeaderSpecific(y,VEC_COOKIE,2);
2792   PetscValidHeaderSpecific(b,VEC_COOKIE,3);
2793   PetscValidHeaderSpecific(x,VEC_COOKIE,4);
2794   PetscCheckSameComm(mat,1,b,2);
2795   PetscCheckSameComm(mat,1,y,2);
2796   PetscCheckSameComm(mat,1,x,3);
2797   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2798   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2799   if (mat->cmap.N != x->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap.N,x->map.N);
2800   if (mat->rmap.N != b->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap.N,b->map.N);
2801   if (mat->rmap.N != y->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap.N,y->map.N);
2802   if (mat->rmap.n != b->map.n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap.n,b->map.n);
2803   if (x->map.n != y->map.n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map.n,y->map.n);
2804   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2805 
2806   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
2807   if (mat->ops->solveadd)  {
2808     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
2809   } else {
2810     /* do the solve then the add manually */
2811     if (x != y) {
2812       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
2813       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
2814     } else {
2815       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
2816       ierr = PetscLogObjectParent(mat,tmp);CHKERRQ(ierr);
2817       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
2818       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
2819       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
2820       ierr = VecDestroy(tmp);CHKERRQ(ierr);
2821     }
2822   }
2823   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
2824   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2825   PetscFunctionReturn(0);
2826 }
2827 
2828 #undef __FUNCT__
2829 #define __FUNCT__ "MatSolveTranspose"
2830 /*@
2831    MatSolveTranspose - Solves A' x = b, given a factored matrix.
2832 
2833    Collective on Mat and Vec
2834 
2835    Input Parameters:
2836 +  mat - the factored matrix
2837 -  b - the right-hand-side vector
2838 
2839    Output Parameter:
2840 .  x - the result vector
2841 
2842    Notes:
2843    The vectors b and x cannot be the same.  I.e., one cannot
2844    call MatSolveTranspose(A,x,x).
2845 
2846    Most users should employ the simplified KSP interface for linear solvers
2847    instead of working directly with matrix algebra routines such as this.
2848    See, e.g., KSPCreate().
2849 
2850    Level: developer
2851 
2852    Concepts: matrices^triangular solves
2853 
2854 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
2855 @*/
2856 PetscErrorCode PETSCMAT_DLLEXPORT MatSolveTranspose(Mat mat,Vec b,Vec x)
2857 {
2858   PetscErrorCode ierr;
2859 
2860   PetscFunctionBegin;
2861   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2862   PetscValidType(mat,1);
2863   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2864   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2865   PetscCheckSameComm(mat,1,b,2);
2866   PetscCheckSameComm(mat,1,x,3);
2867   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2868   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2869   if (!mat->ops->solvetranspose) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
2870   if (mat->rmap.N != x->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap.N,x->map.N);
2871   if (mat->cmap.N != b->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap.N,b->map.N);
2872   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2873   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
2874   ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
2875   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
2876   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2877   PetscFunctionReturn(0);
2878 }
2879 
2880 #undef __FUNCT__
2881 #define __FUNCT__ "MatSolveTransposeAdd"
2882 /*@
2883    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
2884                       factored matrix.
2885 
2886    Collective on Mat and Vec
2887 
2888    Input Parameters:
2889 +  mat - the factored matrix
2890 .  b - the right-hand-side vector
2891 -  y - the vector to be added to
2892 
2893    Output Parameter:
2894 .  x - the result vector
2895 
2896    Notes:
2897    The vectors b and x cannot be the same.  I.e., one cannot
2898    call MatSolveTransposeAdd(A,x,y,x).
2899 
2900    Most users should employ the simplified KSP interface for linear solvers
2901    instead of working directly with matrix algebra routines such as this.
2902    See, e.g., KSPCreate().
2903 
2904    Level: developer
2905 
2906    Concepts: matrices^triangular solves
2907 
2908 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
2909 @*/
2910 PetscErrorCode PETSCMAT_DLLEXPORT MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
2911 {
2912   PetscScalar    one = 1.0;
2913   PetscErrorCode ierr;
2914   Vec            tmp;
2915 
2916   PetscFunctionBegin;
2917   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2918   PetscValidType(mat,1);
2919   PetscValidHeaderSpecific(y,VEC_COOKIE,2);
2920   PetscValidHeaderSpecific(b,VEC_COOKIE,3);
2921   PetscValidHeaderSpecific(x,VEC_COOKIE,4);
2922   PetscCheckSameComm(mat,1,b,2);
2923   PetscCheckSameComm(mat,1,y,3);
2924   PetscCheckSameComm(mat,1,x,4);
2925   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2926   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2927   if (mat->rmap.N != x->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap.N,x->map.N);
2928   if (mat->cmap.N != b->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap.N,b->map.N);
2929   if (mat->cmap.N != y->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap.N,y->map.N);
2930   if (x->map.n != y->map.n)   SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map.n,y->map.n);
2931   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2932 
2933   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
2934   if (mat->ops->solvetransposeadd) {
2935     ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
2936   } else {
2937     /* do the solve then the add manually */
2938     if (x != y) {
2939       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
2940       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
2941     } else {
2942       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
2943       ierr = PetscLogObjectParent(mat,tmp);CHKERRQ(ierr);
2944       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
2945       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
2946       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
2947       ierr = VecDestroy(tmp);CHKERRQ(ierr);
2948     }
2949   }
2950   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
2951   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2952   PetscFunctionReturn(0);
2953 }
2954 /* ----------------------------------------------------------------*/
2955 
2956 #undef __FUNCT__
2957 #define __FUNCT__ "MatRelax"
2958 /*@
2959    MatRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.
2960 
2961    Collective on Mat and Vec
2962 
2963    Input Parameters:
2964 +  mat - the matrix
2965 .  b - the right hand side
2966 .  omega - the relaxation factor
2967 .  flag - flag indicating the type of SOR (see below)
2968 .  shift -  diagonal shift
2969 .  its - the number of iterations
2970 -  lits - the number of local iterations
2971 
2972    Output Parameters:
2973 .  x - the solution (can contain an initial guess)
2974 
2975    SOR Flags:
2976 .     SOR_FORWARD_SWEEP - forward SOR
2977 .     SOR_BACKWARD_SWEEP - backward SOR
2978 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
2979 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
2980 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
2981 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
2982 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
2983          upper/lower triangular part of matrix to
2984          vector (with omega)
2985 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
2986 
2987    Notes:
2988    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
2989    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
2990    on each processor.
2991 
2992    Application programmers will not generally use MatRelax() directly,
2993    but instead will employ the KSP/PC interface.
2994 
2995    Notes for Advanced Users:
2996    The flags are implemented as bitwise inclusive or operations.
2997    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
2998    to specify a zero initial guess for SSOR.
2999 
3000    Most users should employ the simplified KSP interface for linear solvers
3001    instead of working directly with matrix algebra routines such as this.
3002    See, e.g., KSPCreate().
3003 
3004    See also, MatPBRelax(). This routine will automatically call the point block
3005    version if the point version is not available.
3006 
3007    Level: developer
3008 
3009    Concepts: matrices^relaxation
3010    Concepts: matrices^SOR
3011    Concepts: matrices^Gauss-Seidel
3012 
3013 @*/
3014 PetscErrorCode PETSCMAT_DLLEXPORT MatRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3015 {
3016   PetscErrorCode ierr;
3017 
3018   PetscFunctionBegin;
3019   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3020   PetscValidType(mat,1);
3021   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
3022   PetscValidHeaderSpecific(x,VEC_COOKIE,8);
3023   PetscCheckSameComm(mat,1,b,2);
3024   PetscCheckSameComm(mat,1,x,8);
3025   if (!mat->ops->relax && !mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3026   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3027   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3028   if (mat->cmap.N != x->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap.N,x->map.N);
3029   if (mat->rmap.N != b->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap.N,b->map.N);
3030   if (mat->rmap.n != b->map.n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap.n,b->map.n);
3031   if (its <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3032   if (lits <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3033 
3034   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3035   ierr = PetscLogEventBegin(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
3036   if (mat->ops->relax) {
3037     ierr =(*mat->ops->relax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
3038   } else {
3039     ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
3040   }
3041   ierr = PetscLogEventEnd(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
3042   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3043   PetscFunctionReturn(0);
3044 }
3045 
3046 #undef __FUNCT__
3047 #define __FUNCT__ "MatPBRelax"
3048 /*@
3049    MatPBRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3050 
3051    Collective on Mat and Vec
3052 
3053    See MatRelax() for usage
3054 
3055    For multi-component PDEs where the Jacobian is stored in a point block format
3056    (with the PETSc BAIJ matrix formats) the relaxation is done one point block at
3057    a time. That is, the small (for example, 4 by 4) blocks along the diagonal are solved
3058    simultaneously (that is a 4 by 4 linear solve is done) to update all the values at a point.
3059 
3060    Level: developer
3061 
3062 @*/
3063 PetscErrorCode PETSCMAT_DLLEXPORT MatPBRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3064 {
3065   PetscErrorCode ierr;
3066 
3067   PetscFunctionBegin;
3068   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3069   PetscValidType(mat,1);
3070   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
3071   PetscValidHeaderSpecific(x,VEC_COOKIE,8);
3072   PetscCheckSameComm(mat,1,b,2);
3073   PetscCheckSameComm(mat,1,x,8);
3074   if (!mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3075   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3076   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3077   if (mat->cmap.N != x->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap.N,x->map.N);
3078   if (mat->rmap.N != b->map.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap.N,b->map.N);
3079   if (mat->rmap.n != b->map.n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap.n,b->map.n);
3080   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3081 
3082   ierr = PetscLogEventBegin(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
3083   ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
3084   ierr = PetscLogEventEnd(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
3085   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3086   PetscFunctionReturn(0);
3087 }
3088 
3089 #undef __FUNCT__
3090 #define __FUNCT__ "MatCopy_Basic"
3091 /*
3092       Default matrix copy routine.
3093 */
3094 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3095 {
3096   PetscErrorCode    ierr;
3097   PetscInt          i,rstart,rend,nz;
3098   const PetscInt    *cwork;
3099   const PetscScalar *vwork;
3100 
3101   PetscFunctionBegin;
3102   if (B->assembled) {
3103     ierr = MatZeroEntries(B);CHKERRQ(ierr);
3104   }
3105   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
3106   for (i=rstart; i<rend; i++) {
3107     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3108     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
3109     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3110   }
3111   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3112   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3113   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3114   PetscFunctionReturn(0);
3115 }
3116 
3117 #undef __FUNCT__
3118 #define __FUNCT__ "MatCopy"
3119 /*@
3120    MatCopy - Copys a matrix to another matrix.
3121 
3122    Collective on Mat
3123 
3124    Input Parameters:
3125 +  A - the matrix
3126 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3127 
3128    Output Parameter:
3129 .  B - where the copy is put
3130 
3131    Notes:
3132    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3133    same nonzero pattern or the routine will crash.
3134 
3135    MatCopy() copies the matrix entries of a matrix to another existing
3136    matrix (after first zeroing the second matrix).  A related routine is
3137    MatConvert(), which first creates a new matrix and then copies the data.
3138 
3139    Level: intermediate
3140 
3141    Concepts: matrices^copying
3142 
3143 .seealso: MatConvert(), MatDuplicate()
3144 
3145 @*/
3146 PetscErrorCode PETSCMAT_DLLEXPORT MatCopy(Mat A,Mat B,MatStructure str)
3147 {
3148   PetscErrorCode ierr;
3149 
3150   PetscFunctionBegin;
3151   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
3152   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
3153   PetscValidType(A,1);
3154   PetscValidType(B,2);
3155   MatPreallocated(B);
3156   PetscCheckSameComm(A,1,B,2);
3157   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3158   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3159   if (A->rmap.N != B->rmap.N || A->cmap.N != B->cmap.N) SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%D,%D) (%D,%D)",A->rmap.N,B->rmap.N,A->cmap.N,B->cmap.N);
3160   ierr = MatPreallocated(A);CHKERRQ(ierr);
3161 
3162   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3163   if (A->ops->copy) {
3164     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
3165   } else { /* generic conversion */
3166     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
3167   }
3168   if (A->mapping) {
3169     if (B->mapping) {ierr = ISLocalToGlobalMappingDestroy(B->mapping);CHKERRQ(ierr);B->mapping = 0;}
3170     ierr = MatSetLocalToGlobalMapping(B,A->mapping);CHKERRQ(ierr);
3171   }
3172   if (A->bmapping) {
3173     if (B->bmapping) {ierr = ISLocalToGlobalMappingDestroy(B->bmapping);CHKERRQ(ierr);B->bmapping = 0;}
3174     ierr = MatSetLocalToGlobalMappingBlock(B,A->mapping);CHKERRQ(ierr);
3175   }
3176   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3177   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3178   PetscFunctionReturn(0);
3179 }
3180 
3181 #undef __FUNCT__
3182 #define __FUNCT__ "MatConvert"
3183 /*@C
3184    MatConvert - Converts a matrix to another matrix, either of the same
3185    or different type.
3186 
3187    Collective on Mat
3188 
3189    Input Parameters:
3190 +  mat - the matrix
3191 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3192    same type as the original matrix.
3193 -  reuse - denotes if the destination matrix is to be created or reused.  Currently
3194    MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3195    MAT_INITIAL_MATRIX.
3196 
3197    Output Parameter:
3198 .  M - pointer to place new matrix
3199 
3200    Notes:
3201    MatConvert() first creates a new matrix and then copies the data from
3202    the first matrix.  A related routine is MatCopy(), which copies the matrix
3203    entries of one matrix to another already existing matrix context.
3204 
3205    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3206    the MPI communicator of the generated matrix is always the same as the communicator
3207    of the input matrix.
3208 
3209    Level: intermediate
3210 
3211    Concepts: matrices^converting between storage formats
3212 
3213 .seealso: MatCopy(), MatDuplicate()
3214 @*/
3215 PetscErrorCode PETSCMAT_DLLEXPORT MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3216 {
3217   PetscErrorCode         ierr;
3218   PetscTruth             sametype,issame,flg;
3219   char                   convname[256],mtype[256];
3220   Mat                    B;
3221 
3222   PetscFunctionBegin;
3223   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3224   PetscValidType(mat,1);
3225   PetscValidPointer(M,3);
3226   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3227   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3228   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3229 
3230   ierr = PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
3231   if (flg) {
3232     newtype = mtype;
3233   }
3234   ierr = PetscTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
3235   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
3236   if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) {
3237     SETERRQ(PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3238   }
3239 
3240   if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0);
3241 
3242   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3243     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
3244   } else {
3245     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=PETSC_NULL;
3246     const char     *prefix[3] = {"seq","mpi",""};
3247     PetscInt       i;
3248     /*
3249        Order of precedence:
3250        1) See if a specialized converter is known to the current matrix.
3251        2) See if a specialized converter is known to the desired matrix class.
3252        3) See if a good general converter is registered for the desired class
3253           (as of 6/27/03 only MATMPIADJ falls into this category).
3254        4) See if a good general converter is known for the current matrix.
3255        5) Use a really basic converter.
3256     */
3257 
3258     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3259     for (i=0; i<3; i++) {
3260       ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
3261       ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr);
3262       ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3263       ierr = PetscStrcat(convname,prefix[i]);CHKERRQ(ierr);
3264       ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
3265       ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3266       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3267       if (conv) goto foundconv;
3268     }
3269 
3270     /* 2)  See if a specialized converter is known to the desired matrix class. */
3271     ierr = MatCreate(((PetscObject)mat)->comm,&B);CHKERRQ(ierr);
3272     ierr = MatSetSizes(B,mat->rmap.n,mat->cmap.n,mat->rmap.N,mat->cmap.N);CHKERRQ(ierr);
3273     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
3274     for (i=0; i<3; i++) {
3275       ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
3276       ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr);
3277       ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3278       ierr = PetscStrcat(convname,prefix[i]);CHKERRQ(ierr);
3279       ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
3280       ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3281       ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3282       if (conv) {
3283         ierr = MatDestroy(B);CHKERRQ(ierr);
3284         goto foundconv;
3285       }
3286     }
3287 
3288     /* 3) See if a good general converter is registered for the desired class */
3289     conv = B->ops->convertfrom;
3290     ierr = MatDestroy(B);CHKERRQ(ierr);
3291     if (conv) goto foundconv;
3292 
3293     /* 4) See if a good general converter is known for the current matrix */
3294     if (mat->ops->convert) {
3295       conv = mat->ops->convert;
3296     }
3297     if (conv) goto foundconv;
3298 
3299     /* 5) Use a really basic converter. */
3300     conv = MatConvert_Basic;
3301 
3302     foundconv:
3303     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3304     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
3305     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3306   }
3307   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
3308   PetscFunctionReturn(0);
3309 }
3310 
3311 #undef __FUNCT__
3312 #define __FUNCT__ "MatGetSolverType"
3313 /*@C
3314    MatGetSolverType - Gets the type of LU or Cholesky factorization/solver routines that are used
3315 
3316    Collective on Mat
3317 
3318    Input Parameters:
3319 .  mat - the matrix
3320 
3321    Output Parameters:
3322 .  type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3323 
3324 
3325    Notes:
3326       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3327      such as superlu, mumps, spooles etc.
3328 
3329       PETSc must have been config/configure.py to use the external solver, using the option --download-package
3330 
3331    Level: intermediate
3332 
3333 
3334 .seealso: MatCopy(), MatDuplicate(), MatSetSolverType()
3335 @*/
3336 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSolverType(Mat mat, MatSolverType *type)
3337 {
3338   PetscErrorCode         ierr;
3339 
3340   PetscFunctionBegin;
3341   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3342   PetscValidType(mat,1);
3343   *type = mat->solvertype;
3344   PetscFunctionReturn(0);
3345 }
3346 
3347 #undef __FUNCT__
3348 #define __FUNCT__ "MatSetSolverType"
3349 /*@C
3350    MatSetSolverType - Sets the type of LU or Cholesky factorization/solver routines that are used
3351    or different type.
3352 
3353    Collective on Mat
3354 
3355    Input Parameters:
3356 +  mat - the matrix
3357 -  type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3358 
3359 
3360    Notes:
3361       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3362      such as superlu, mumps, spooles etc.
3363 
3364       PETSc must have been config/configure.py to use the external solver, using the option --download-package
3365 
3366    Level: intermediate
3367 
3368 
3369 .seealso: MatCopy(), MatDuplicate(), MatGetSolverType()
3370 @*/
3371 PetscErrorCode PETSCMAT_DLLEXPORT MatSetSolverType(Mat mat, MatSolverType type)
3372 {
3373   PetscErrorCode         ierr;
3374   char                   convname[256];
3375   PetscErrorCode         (*conv)(Mat,const char *);
3376 
3377   PetscFunctionBegin;
3378   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3379   PetscValidType(mat,1);
3380 
3381   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3382   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3383 
3384   ierr = PetscStrcpy(convname,"MatSetSolverType_");CHKERRQ(ierr);
3385   ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr);
3386   ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3387   ierr = PetscStrcat(convname,type);CHKERRQ(ierr);
3388   ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3389   ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3390   if (!conv) {
3391     PetscTruth flag;
3392     ierr = PetscStrcasecmp("petsc",type,&flag);CHKERRQ(ierr);
3393     if (flag) {
3394       SETERRQ1(PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc solver",mat->hdr.type_name);
3395     } else {
3396       SETERRQ3(PETSC_ERR_SUP,"Matrix format %s does not have a solver %d. Perhaps you must config/configure.py with --download-%s",mat->hdr.type_name,type,type);
3397     }
3398   }
3399   if (mat->ops->destroysolver) {
3400     ierr = (*mat->ops->destroysolver)(mat);CHKERRQ(ierr);
3401   }
3402   ierr = (*conv)(mat,type);CHKERRQ(ierr);
3403   ierr = PetscStrfree(mat->solvertype);CHKERRQ(ierr);
3404   ierr = PetscStrallocpy(type,&mat->solvertype);CHKERRQ(ierr);
3405   PetscFunctionReturn(0);
3406 }
3407 
3408 
3409 #undef __FUNCT__
3410 #define __FUNCT__ "MatDuplicate"
3411 /*@
3412    MatDuplicate - Duplicates a matrix including the non-zero structure.
3413 
3414    Collective on Mat
3415 
3416    Input Parameters:
3417 +  mat - the matrix
3418 -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
3419         values as well or not
3420 
3421    Output Parameter:
3422 .  M - pointer to place new matrix
3423 
3424    Level: intermediate
3425 
3426    Concepts: matrices^duplicating
3427 
3428 .seealso: MatCopy(), MatConvert()
3429 @*/
3430 PetscErrorCode PETSCMAT_DLLEXPORT MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
3431 {
3432   PetscErrorCode ierr;
3433   Mat            B;
3434 
3435   PetscFunctionBegin;
3436   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3437   PetscValidType(mat,1);
3438   PetscValidPointer(M,3);
3439   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3440   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3441   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3442 
3443   *M  = 0;
3444   if (!mat->ops->duplicate) {
3445     SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type");
3446   }
3447   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3448   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
3449   B = *M;
3450   if (mat->mapping) {
3451     ierr = MatSetLocalToGlobalMapping(B,mat->mapping);CHKERRQ(ierr);
3452   }
3453   if (mat->bmapping) {
3454     ierr = MatSetLocalToGlobalMappingBlock(B,mat->bmapping);CHKERRQ(ierr);
3455   }
3456   ierr = PetscMapCopy(((PetscObject)mat)->comm,&mat->rmap,&B->rmap);CHKERRQ(ierr);
3457   ierr = PetscMapCopy(((PetscObject)mat)->comm,&mat->cmap,&B->cmap);CHKERRQ(ierr);
3458 
3459   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3460   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3461   PetscFunctionReturn(0);
3462 }
3463 
3464 #undef __FUNCT__
3465 #define __FUNCT__ "MatGetDiagonal"
3466 /*@
3467    MatGetDiagonal - Gets the diagonal of a matrix.
3468 
3469    Collective on Mat and Vec
3470 
3471    Input Parameters:
3472 +  mat - the matrix
3473 -  v - the vector for storing the diagonal
3474 
3475    Output Parameter:
3476 .  v - the diagonal of the matrix
3477 
3478    Notes: The result of this call are the same as if one converted the matrix to dense format
3479       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
3480 
3481    Level: intermediate
3482 
3483    Concepts: matrices^accessing diagonals
3484 
3485 .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
3486 @*/
3487 PetscErrorCode PETSCMAT_DLLEXPORT MatGetDiagonal(Mat mat,Vec v)
3488 {
3489   PetscErrorCode ierr;
3490 
3491   PetscFunctionBegin;
3492   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3493   PetscValidType(mat,1);
3494   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3495   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3496   if (!mat->ops->getdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3497   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3498 
3499   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
3500   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3501   PetscFunctionReturn(0);
3502 }
3503 
3504 #undef __FUNCT__
3505 #define __FUNCT__ "MatGetRowMin"
3506 /*@
3507    MatGetRowMin - Gets the minimum value (of the real part) of each
3508         row of the matrix
3509 
3510    Collective on Mat and Vec
3511 
3512    Input Parameters:
3513 .  mat - the matrix
3514 
3515    Output Parameter:
3516 +  v - the vector for storing the maximums
3517 -  idx - the indices of the column found for each row (optional)
3518 
3519    Level: intermediate
3520 
3521    Notes: The result of this call are the same as if one converted the matrix to dense format
3522       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
3523 
3524     This code is only implemented for a couple of matrix formats.
3525 
3526    Concepts: matrices^getting row maximums
3527 
3528 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
3529           MatGetRowMax()
3530 @*/
3531 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
3532 {
3533   PetscErrorCode ierr;
3534 
3535   PetscFunctionBegin;
3536   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3537   PetscValidType(mat,1);
3538   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3539   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3540   if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3541   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3542 
3543   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
3544   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3545   PetscFunctionReturn(0);
3546 }
3547 
3548 #undef __FUNCT__
3549 #define __FUNCT__ "MatGetRowMax"
3550 /*@
3551    MatGetRowMax - Gets the maximum value (of the real part) of each
3552         row of the matrix
3553 
3554    Collective on Mat and Vec
3555 
3556    Input Parameters:
3557 .  mat - the matrix
3558 
3559    Output Parameter:
3560 +  v - the vector for storing the maximums
3561 -  idx - the indices of the column found for each row (optional)
3562 
3563    Level: intermediate
3564 
3565    Notes: The result of this call are the same as if one converted the matrix to dense format
3566       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
3567 
3568     This code is only implemented for a couple of matrix formats.
3569 
3570    Concepts: matrices^getting row maximums
3571 
3572 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
3573 @*/
3574 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
3575 {
3576   PetscErrorCode ierr;
3577 
3578   PetscFunctionBegin;
3579   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3580   PetscValidType(mat,1);
3581   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3582   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3583   if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3584   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3585 
3586   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
3587   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3588   PetscFunctionReturn(0);
3589 }
3590 
3591 #undef __FUNCT__
3592 #define __FUNCT__ "MatGetRowMaxAbs"
3593 /*@
3594    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
3595         row of the matrix
3596 
3597    Collective on Mat and Vec
3598 
3599    Input Parameters:
3600 .  mat - the matrix
3601 
3602    Output Parameter:
3603 +  v - the vector for storing the maximums
3604 -  idx - the indices of the column found for each row (optional)
3605 
3606    Level: intermediate
3607 
3608    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
3609     row is 0 (the first column).
3610 
3611     This code is only implemented for a couple of matrix formats.
3612 
3613    Concepts: matrices^getting row maximums
3614 
3615 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3616 @*/
3617 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
3618 {
3619   PetscErrorCode ierr;
3620 
3621   PetscFunctionBegin;
3622   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3623   PetscValidType(mat,1);
3624   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3625   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3626   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3627   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3628   if (idx) {ierr = PetscMemzero(idx,mat->rmap.n*sizeof(PetscInt));CHKERRQ(ierr);}
3629 
3630   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
3631   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3632   PetscFunctionReturn(0);
3633 }
3634 
3635 #undef __FUNCT__
3636 #define __FUNCT__ "MatGetRowSum"
3637 /*@
3638    MatGetRowSum - Gets the sum of each row of the matrix
3639 
3640    Collective on Mat and Vec
3641 
3642    Input Parameters:
3643 .  mat - the matrix
3644 
3645    Output Parameter:
3646 .  v - the vector for storing the maximums
3647 
3648    Level: intermediate
3649 
3650    Notes: This code is slow since it is not currently specialized for different formats
3651 
3652    Concepts: matrices^getting row sums
3653 
3654 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3655 @*/
3656 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowSum(Mat mat, Vec v)
3657 {
3658   PetscInt       start, end, row;
3659   PetscScalar   *array;
3660   PetscErrorCode ierr;
3661 
3662   PetscFunctionBegin;
3663   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3664   PetscValidType(mat,1);
3665   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3666   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3667   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3668   ierr = MatGetOwnershipRange(mat, &start, &end);CHKERRQ(ierr);
3669   ierr = VecGetArray(v, &array);CHKERRQ(ierr);
3670   for(row = start; row < end; ++row) {
3671     PetscInt           ncols, col;
3672     const PetscInt    *cols;
3673     const PetscScalar *vals;
3674 
3675     array[row - start] = 0.0;
3676     ierr = MatGetRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr);
3677     for(col = 0; col < ncols; col++) {
3678       array[row - start] += vals[col];
3679     }
3680     ierr = MatRestoreRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr);
3681   }
3682   ierr = VecRestoreArray(v, &array);CHKERRQ(ierr);
3683   ierr = PetscObjectStateIncrease((PetscObject) v);CHKERRQ(ierr);
3684   PetscFunctionReturn(0);
3685 }
3686 
3687 #undef __FUNCT__
3688 #define __FUNCT__ "MatTranspose"
3689 /*@
3690    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
3691 
3692    Collective on Mat
3693 
3694    Input Parameter:
3695 +  mat - the matrix to transpose
3696 -  reuse - store the transpose matrix in the provided B
3697 
3698    Output Parameters:
3699 .  B - the transpose
3700 
3701    Notes:
3702      If you  pass in &mat for B the matrix will be done in place
3703 
3704    Level: intermediate
3705 
3706    Concepts: matrices^transposing
3707 
3708 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose()
3709 @*/
3710 PetscErrorCode PETSCMAT_DLLEXPORT MatTranspose(Mat mat,MatReuse reuse,Mat *B)
3711 {
3712   PetscErrorCode ierr;
3713 
3714   PetscFunctionBegin;
3715   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3716   PetscValidType(mat,1);
3717   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3718   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3719   if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3720   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3721 
3722   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
3723   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
3724   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
3725   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
3726   PetscFunctionReturn(0);
3727 }
3728 
3729 #undef __FUNCT__
3730 #define __FUNCT__ "MatIsTranspose"
3731 /*@
3732    MatIsTranspose - Test whether a matrix is another one's transpose,
3733         or its own, in which case it tests symmetry.
3734 
3735    Collective on Mat
3736 
3737    Input Parameter:
3738 +  A - the matrix to test
3739 -  B - the matrix to test against, this can equal the first parameter
3740 
3741    Output Parameters:
3742 .  flg - the result
3743 
3744    Notes:
3745    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
3746    has a running time of the order of the number of nonzeros; the parallel
3747    test involves parallel copies of the block-offdiagonal parts of the matrix.
3748 
3749    Level: intermediate
3750 
3751    Concepts: matrices^transposing, matrix^symmetry
3752 
3753 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
3754 @*/
3755 PetscErrorCode PETSCMAT_DLLEXPORT MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
3756 {
3757   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);
3758 
3759   PetscFunctionBegin;
3760   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
3761   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
3762   PetscValidPointer(flg,3);
3763   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
3764   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
3765   if (f && g) {
3766     if (f==g) {
3767       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
3768     } else {
3769       SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
3770     }
3771   }
3772   PetscFunctionReturn(0);
3773 }
3774 
3775 #undef __FUNCT__
3776 #define __FUNCT__ "MatIsHermitianTranspose"
3777 /*@
3778    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
3779 
3780    Collective on Mat
3781 
3782    Input Parameter:
3783 +  A - the matrix to test
3784 -  B - the matrix to test against, this can equal the first parameter
3785 
3786    Output Parameters:
3787 .  flg - the result
3788 
3789    Notes:
3790    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
3791    has a running time of the order of the number of nonzeros; the parallel
3792    test involves parallel copies of the block-offdiagonal parts of the matrix.
3793 
3794    Level: intermediate
3795 
3796    Concepts: matrices^transposing, matrix^symmetry
3797 
3798 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
3799 @*/
3800 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
3801 {
3802   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);
3803 
3804   PetscFunctionBegin;
3805   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
3806   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
3807   PetscValidPointer(flg,3);
3808   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
3809   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
3810   if (f && g) {
3811     if (f==g) {
3812       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
3813     } else {
3814       SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
3815     }
3816   }
3817   PetscFunctionReturn(0);
3818 }
3819 
3820 #undef __FUNCT__
3821 #define __FUNCT__ "MatPermute"
3822 /*@
3823    MatPermute - Creates a new matrix with rows and columns permuted from the
3824    original.
3825 
3826    Collective on Mat
3827 
3828    Input Parameters:
3829 +  mat - the matrix to permute
3830 .  row - row permutation, each processor supplies only the permutation for its rows
3831 -  col - column permutation, each processor needs the entire column permutation, that is
3832          this is the same size as the total number of columns in the matrix
3833 
3834    Output Parameters:
3835 .  B - the permuted matrix
3836 
3837    Level: advanced
3838 
3839    Concepts: matrices^permuting
3840 
3841 .seealso: MatGetOrdering()
3842 @*/
3843 PetscErrorCode PETSCMAT_DLLEXPORT MatPermute(Mat mat,IS row,IS col,Mat *B)
3844 {
3845   PetscErrorCode ierr;
3846 
3847   PetscFunctionBegin;
3848   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3849   PetscValidType(mat,1);
3850   PetscValidHeaderSpecific(row,IS_COOKIE,2);
3851   PetscValidHeaderSpecific(col,IS_COOKIE,3);
3852   PetscValidPointer(B,4);
3853   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3854   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3855   if (!mat->ops->permute) SETERRQ1(PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
3856   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3857 
3858   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
3859   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
3860   PetscFunctionReturn(0);
3861 }
3862 
3863 #undef __FUNCT__
3864 #define __FUNCT__ "MatPermuteSparsify"
3865 /*@
3866   MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the
3867   original and sparsified to the prescribed tolerance.
3868 
3869   Collective on Mat
3870 
3871   Input Parameters:
3872 + A    - The matrix to permute
3873 . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
3874 . frac - The half-bandwidth as a fraction of the total size, or 0.0
3875 . tol  - The drop tolerance
3876 . rowp - The row permutation
3877 - colp - The column permutation
3878 
3879   Output Parameter:
3880 . B    - The permuted, sparsified matrix
3881 
3882   Level: advanced
3883 
3884   Note:
3885   The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
3886   restrict the half-bandwidth of the resulting matrix to 5% of the
3887   total matrix size.
3888 
3889 .keywords: matrix, permute, sparsify
3890 
3891 .seealso: MatGetOrdering(), MatPermute()
3892 @*/
3893 PetscErrorCode PETSCMAT_DLLEXPORT MatPermuteSparsify(Mat A, PetscInt band, PetscReal frac, PetscReal tol, IS rowp, IS colp, Mat *B)
3894 {
3895   IS                irowp, icolp;
3896   PetscInt          *rows, *cols;
3897   PetscInt          M, N, locRowStart, locRowEnd;
3898   PetscInt          nz, newNz;
3899   const PetscInt    *cwork;
3900   PetscInt          *cnew;
3901   const PetscScalar *vwork;
3902   PetscScalar       *vnew;
3903   PetscInt          bw, issize;
3904   PetscInt          row, locRow, newRow, col, newCol;
3905   PetscErrorCode    ierr;
3906 
3907   PetscFunctionBegin;
3908   PetscValidHeaderSpecific(A,    MAT_COOKIE,1);
3909   PetscValidHeaderSpecific(rowp, IS_COOKIE,5);
3910   PetscValidHeaderSpecific(colp, IS_COOKIE,6);
3911   PetscValidPointer(B,7);
3912   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
3913   if (A->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
3914   if (!A->ops->permutesparsify) {
3915     ierr = MatGetSize(A, &M, &N);CHKERRQ(ierr);
3916     ierr = MatGetOwnershipRange(A, &locRowStart, &locRowEnd);CHKERRQ(ierr);
3917     ierr = ISGetSize(rowp, &issize);CHKERRQ(ierr);
3918     if (issize != M) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for row permutation, should be %D", issize, M);
3919     ierr = ISGetSize(colp, &issize);CHKERRQ(ierr);
3920     if (issize != N) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for column permutation, should be %D", issize, N);
3921     ierr = ISInvertPermutation(rowp, 0, &irowp);CHKERRQ(ierr);
3922     ierr = ISGetIndices(irowp, &rows);CHKERRQ(ierr);
3923     ierr = ISInvertPermutation(colp, 0, &icolp);CHKERRQ(ierr);
3924     ierr = ISGetIndices(icolp, &cols);CHKERRQ(ierr);
3925     ierr = PetscMalloc(N * sizeof(PetscInt),         &cnew);CHKERRQ(ierr);
3926     ierr = PetscMalloc(N * sizeof(PetscScalar), &vnew);CHKERRQ(ierr);
3927 
3928     /* Setup bandwidth to include */
3929     if (band == PETSC_DECIDE) {
3930       if (frac <= 0.0)
3931         bw = (PetscInt) (M * 0.05);
3932       else
3933         bw = (PetscInt) (M * frac);
3934     } else {
3935       if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
3936       bw = band;
3937     }
3938 
3939     /* Put values into new matrix */
3940     ierr = MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B);CHKERRQ(ierr);
3941     for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) {
3942       ierr = MatGetRow(A, row, &nz, &cwork, &vwork);CHKERRQ(ierr);
3943       newRow   = rows[locRow]+locRowStart;
3944       for(col = 0, newNz = 0; col < nz; col++) {
3945         newCol = cols[cwork[col]];
3946         if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (PetscAbsScalar(vwork[col]) >= tol)) {
3947           cnew[newNz] = newCol;
3948           vnew[newNz] = vwork[col];
3949           newNz++;
3950         }
3951       }
3952       ierr = MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES);CHKERRQ(ierr);
3953       ierr = MatRestoreRow(A, row, &nz, &cwork, &vwork);CHKERRQ(ierr);
3954     }
3955     ierr = PetscFree(cnew);CHKERRQ(ierr);
3956     ierr = PetscFree(vnew);CHKERRQ(ierr);
3957     ierr = MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3958     ierr = MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3959     ierr = ISRestoreIndices(irowp, &rows);CHKERRQ(ierr);
3960     ierr = ISRestoreIndices(icolp, &cols);CHKERRQ(ierr);
3961     ierr = ISDestroy(irowp);CHKERRQ(ierr);
3962     ierr = ISDestroy(icolp);CHKERRQ(ierr);
3963   } else {
3964     ierr = (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B);CHKERRQ(ierr);
3965   }
3966   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
3967   PetscFunctionReturn(0);
3968 }
3969 
3970 #undef __FUNCT__
3971 #define __FUNCT__ "MatEqual"
3972 /*@
3973    MatEqual - Compares two matrices.
3974 
3975    Collective on Mat
3976 
3977    Input Parameters:
3978 +  A - the first matrix
3979 -  B - the second matrix
3980 
3981    Output Parameter:
3982 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
3983 
3984    Level: intermediate
3985 
3986    Concepts: matrices^equality between
3987 @*/
3988 PetscErrorCode PETSCMAT_DLLEXPORT MatEqual(Mat A,Mat B,PetscTruth *flg)
3989 {
3990   PetscErrorCode ierr;
3991 
3992   PetscFunctionBegin;
3993   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
3994   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
3995   PetscValidType(A,1);
3996   PetscValidType(B,2);
3997   MatPreallocated(B);
3998   PetscValidIntPointer(flg,3);
3999   PetscCheckSameComm(A,1,B,2);
4000   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4001   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4002   if (A->rmap.N != B->rmap.N || A->cmap.N != B->cmap.N) SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D %D %D",A->rmap.N,B->rmap.N,A->cmap.N,B->cmap.N);
4003   if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4004   if (!B->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4005   if (A->ops->equal != B->ops->equal) SETERRQ2(PETSC_ERR_ARG_INCOMP,"A is type: %s\nB is type: %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
4006   ierr = MatPreallocated(A);CHKERRQ(ierr);
4007 
4008   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
4009   PetscFunctionReturn(0);
4010 }
4011 
4012 #undef __FUNCT__
4013 #define __FUNCT__ "MatDiagonalScale"
4014 /*@
4015    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4016    matrices that are stored as vectors.  Either of the two scaling
4017    matrices can be PETSC_NULL.
4018 
4019    Collective on Mat
4020 
4021    Input Parameters:
4022 +  mat - the matrix to be scaled
4023 .  l - the left scaling vector (or PETSC_NULL)
4024 -  r - the right scaling vector (or PETSC_NULL)
4025 
4026    Notes:
4027    MatDiagonalScale() computes A = LAR, where
4028    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4029 
4030    Level: intermediate
4031 
4032    Concepts: matrices^diagonal scaling
4033    Concepts: diagonal scaling of matrices
4034 
4035 .seealso: MatScale()
4036 @*/
4037 PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalScale(Mat mat,Vec l,Vec r)
4038 {
4039   PetscErrorCode ierr;
4040 
4041   PetscFunctionBegin;
4042   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4043   PetscValidType(mat,1);
4044   if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4045   if (l) {PetscValidHeaderSpecific(l,VEC_COOKIE,2);PetscCheckSameComm(mat,1,l,2);}
4046   if (r) {PetscValidHeaderSpecific(r,VEC_COOKIE,3);PetscCheckSameComm(mat,1,r,3);}
4047   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4048   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4049   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4050 
4051   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4052   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
4053   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4054   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4055   PetscFunctionReturn(0);
4056 }
4057 
4058 #undef __FUNCT__
4059 #define __FUNCT__ "MatScale"
4060 /*@
4061     MatScale - Scales all elements of a matrix by a given number.
4062 
4063     Collective on Mat
4064 
4065     Input Parameters:
4066 +   mat - the matrix to be scaled
4067 -   a  - the scaling value
4068 
4069     Output Parameter:
4070 .   mat - the scaled matrix
4071 
4072     Level: intermediate
4073 
4074     Concepts: matrices^scaling all entries
4075 
4076 .seealso: MatDiagonalScale()
4077 @*/
4078 PetscErrorCode PETSCMAT_DLLEXPORT MatScale(Mat mat,PetscScalar a)
4079 {
4080   PetscErrorCode ierr;
4081 
4082   PetscFunctionBegin;
4083   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4084   PetscValidType(mat,1);
4085   if (!mat->ops->scale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4086   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4087   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4088   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4089 
4090   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4091   ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
4092   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4093   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4094   PetscFunctionReturn(0);
4095 }
4096 
4097 #undef __FUNCT__
4098 #define __FUNCT__ "MatNorm"
4099 /*@
4100    MatNorm - Calculates various norms of a matrix.
4101 
4102    Collective on Mat
4103 
4104    Input Parameters:
4105 +  mat - the matrix
4106 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
4107 
4108    Output Parameters:
4109 .  nrm - the resulting norm
4110 
4111    Level: intermediate
4112 
4113    Concepts: matrices^norm
4114    Concepts: norm^of matrix
4115 @*/
4116 PetscErrorCode PETSCMAT_DLLEXPORT MatNorm(Mat mat,NormType type,PetscReal *nrm)
4117 {
4118   PetscErrorCode ierr;
4119 
4120   PetscFunctionBegin;
4121   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4122   PetscValidType(mat,1);
4123   PetscValidScalarPointer(nrm,3);
4124 
4125   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4126   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4127   if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4128   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4129 
4130   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
4131   PetscFunctionReturn(0);
4132 }
4133 
4134 /*
4135      This variable is used to prevent counting of MatAssemblyBegin() that
4136    are called from within a MatAssemblyEnd().
4137 */
4138 static PetscInt MatAssemblyEnd_InUse = 0;
4139 #undef __FUNCT__
4140 #define __FUNCT__ "MatAssemblyBegin"
4141 /*@
4142    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4143    be called after completing all calls to MatSetValues().
4144 
4145    Collective on Mat
4146 
4147    Input Parameters:
4148 +  mat - the matrix
4149 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4150 
4151    Notes:
4152    MatSetValues() generally caches the values.  The matrix is ready to
4153    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4154    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4155    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4156    using the matrix.
4157 
4158    Level: beginner
4159 
4160    Concepts: matrices^assembling
4161 
4162 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4163 @*/
4164 PetscErrorCode PETSCMAT_DLLEXPORT MatAssemblyBegin(Mat mat,MatAssemblyType type)
4165 {
4166   PetscErrorCode ierr;
4167 
4168   PetscFunctionBegin;
4169   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4170   PetscValidType(mat,1);
4171   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4172   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4173   if (mat->assembled) {
4174     mat->was_assembled = PETSC_TRUE;
4175     mat->assembled     = PETSC_FALSE;
4176   }
4177   if (!MatAssemblyEnd_InUse) {
4178     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
4179     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
4180     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
4181   } else {
4182     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
4183   }
4184   PetscFunctionReturn(0);
4185 }
4186 
4187 #undef __FUNCT__
4188 #define __FUNCT__ "MatAssembed"
4189 /*@
4190    MatAssembled - Indicates if a matrix has been assembled and is ready for
4191      use; for example, in matrix-vector product.
4192 
4193    Collective on Mat
4194 
4195    Input Parameter:
4196 .  mat - the matrix
4197 
4198    Output Parameter:
4199 .  assembled - PETSC_TRUE or PETSC_FALSE
4200 
4201    Level: advanced
4202 
4203    Concepts: matrices^assembled?
4204 
4205 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4206 @*/
4207 PetscErrorCode PETSCMAT_DLLEXPORT MatAssembled(Mat mat,PetscTruth *assembled)
4208 {
4209   PetscFunctionBegin;
4210   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4211   PetscValidType(mat,1);
4212   PetscValidPointer(assembled,2);
4213   *assembled = mat->assembled;
4214   PetscFunctionReturn(0);
4215 }
4216 
4217 #undef __FUNCT__
4218 #define __FUNCT__ "MatView_Private"
4219 /*
4220     Processes command line options to determine if/how a matrix
4221   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4222 */
4223 PetscErrorCode MatView_Private(Mat mat)
4224 {
4225   PetscErrorCode    ierr;
4226   PetscTruth        flg1,flg2,flg3,flg4,flg6,flg7,flg8;
4227   static PetscTruth incall = PETSC_FALSE;
4228 #if defined(PETSC_USE_SOCKET_VIEWER)
4229   PetscTruth        flg5;
4230 #endif
4231 
4232   PetscFunctionBegin;
4233   if (incall) PetscFunctionReturn(0);
4234   incall = PETSC_TRUE;
4235   ierr = PetscOptionsBegin(((PetscObject)mat)->comm,((PetscObject)mat)->prefix,"Matrix Options","Mat");CHKERRQ(ierr);
4236     ierr = PetscOptionsName("-mat_view_info","Information on matrix size","MatView",&flg1);CHKERRQ(ierr);
4237     ierr = PetscOptionsName("-mat_view_info_detailed","Nonzeros in the matrix","MatView",&flg2);CHKERRQ(ierr);
4238     ierr = PetscOptionsName("-mat_view","Print matrix to stdout","MatView",&flg3);CHKERRQ(ierr);
4239     ierr = PetscOptionsName("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",&flg4);CHKERRQ(ierr);
4240 #if defined(PETSC_USE_SOCKET_VIEWER)
4241     ierr = PetscOptionsName("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",&flg5);CHKERRQ(ierr);
4242 #endif
4243     ierr = PetscOptionsName("-mat_view_binary","Save matrix to file in binary format","MatView",&flg6);CHKERRQ(ierr);
4244     ierr = PetscOptionsName("-mat_view_draw","Draw the matrix nonzero structure","MatView",&flg7);CHKERRQ(ierr);
4245   ierr = PetscOptionsEnd();CHKERRQ(ierr);
4246 
4247   if (flg1) {
4248     PetscViewer viewer;
4249 
4250     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4251     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
4252     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4253     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4254   }
4255   if (flg2) {
4256     PetscViewer viewer;
4257 
4258     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4259     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
4260     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4261     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4262   }
4263   if (flg3) {
4264     PetscViewer viewer;
4265 
4266     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4267     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4268   }
4269   if (flg4) {
4270     PetscViewer viewer;
4271 
4272     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4273     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr);
4274     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4275     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4276   }
4277 #if defined(PETSC_USE_SOCKET_VIEWER)
4278   if (flg5) {
4279     ierr = MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4280     ierr = PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4281   }
4282 #endif
4283   if (flg6) {
4284     ierr = MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4285     ierr = PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4286   }
4287   if (flg7) {
4288     ierr = PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8);CHKERRQ(ierr);
4289     if (flg8) {
4290       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
4291     }
4292     ierr = MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4293     ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4294     if (flg8) {
4295       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4296     }
4297   }
4298   incall = PETSC_FALSE;
4299   PetscFunctionReturn(0);
4300 }
4301 
4302 #undef __FUNCT__
4303 #define __FUNCT__ "MatAssemblyEnd"
4304 /*@
4305    MatAssemblyEnd - Completes assembling the matrix.  This routine should
4306    be called after MatAssemblyBegin().
4307 
4308    Collective on Mat
4309 
4310    Input Parameters:
4311 +  mat - the matrix
4312 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4313 
4314    Options Database Keys:
4315 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4316 .  -mat_view_info_detailed - Prints more detailed info
4317 .  -mat_view - Prints matrix in ASCII format
4318 .  -mat_view_matlab - Prints matrix in Matlab format
4319 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4320 .  -display <name> - Sets display name (default is host)
4321 .  -draw_pause <sec> - Sets number of seconds to pause after display
4322 .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
4323 .  -viewer_socket_machine <machine>
4324 .  -viewer_socket_port <port>
4325 .  -mat_view_binary - save matrix to file in binary format
4326 -  -viewer_binary_filename <name>
4327 
4328    Notes:
4329    MatSetValues() generally caches the values.  The matrix is ready to
4330    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4331    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4332    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4333    using the matrix.
4334 
4335    Level: beginner
4336 
4337 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4338 @*/
4339 PetscErrorCode PETSCMAT_DLLEXPORT MatAssemblyEnd(Mat mat,MatAssemblyType type)
4340 {
4341   PetscErrorCode  ierr;
4342   static PetscInt inassm = 0;
4343   PetscTruth      flg;
4344 
4345   PetscFunctionBegin;
4346   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4347   PetscValidType(mat,1);
4348 
4349   inassm++;
4350   MatAssemblyEnd_InUse++;
4351   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4352     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
4353     if (mat->ops->assemblyend) {
4354       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
4355     }
4356     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
4357   } else {
4358     if (mat->ops->assemblyend) {
4359       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
4360     }
4361   }
4362 
4363   /* Flush assembly is not a true assembly */
4364   if (type != MAT_FLUSH_ASSEMBLY) {
4365     mat->assembled  = PETSC_TRUE; mat->num_ass++;
4366   }
4367   mat->insertmode = NOT_SET_VALUES;
4368   MatAssemblyEnd_InUse--;
4369   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4370   if (!mat->symmetric_eternal) {
4371     mat->symmetric_set              = PETSC_FALSE;
4372     mat->hermitian_set              = PETSC_FALSE;
4373     mat->structurally_symmetric_set = PETSC_FALSE;
4374   }
4375   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4376     ierr = MatView_Private(mat);CHKERRQ(ierr);
4377     ierr = PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg);CHKERRQ(ierr);
4378     if (flg) {
4379       PetscReal tol = 0.0;
4380       ierr = PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);CHKERRQ(ierr);
4381       ierr = MatIsSymmetric(mat,tol,&flg);CHKERRQ(ierr);
4382       if (flg) {
4383         ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
4384       } else {
4385         ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
4386       }
4387     }
4388   }
4389   inassm--;
4390   PetscFunctionReturn(0);
4391 }
4392 
4393 
4394 #undef __FUNCT__
4395 #define __FUNCT__ "MatCompress"
4396 /*@
4397    MatCompress - Tries to store the matrix in as little space as
4398    possible.  May fail if memory is already fully used, since it
4399    tries to allocate new space.
4400 
4401    Collective on Mat
4402 
4403    Input Parameters:
4404 .  mat - the matrix
4405 
4406    Level: advanced
4407 
4408 @*/
4409 PetscErrorCode PETSCMAT_DLLEXPORT MatCompress(Mat mat)
4410 {
4411   PetscErrorCode ierr;
4412 
4413   PetscFunctionBegin;
4414   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4415   PetscValidType(mat,1);
4416   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4417   if (mat->ops->compress) {ierr = (*mat->ops->compress)(mat);CHKERRQ(ierr);}
4418   PetscFunctionReturn(0);
4419 }
4420 
4421 #undef __FUNCT__
4422 #define __FUNCT__ "MatSetOption"
4423 /*@
4424    MatSetOption - Sets a parameter option for a matrix. Some options
4425    may be specific to certain storage formats.  Some options
4426    determine how values will be inserted (or added). Sorted,
4427    row-oriented input will generally assemble the fastest. The default
4428    is row-oriented, nonsorted input.
4429 
4430    Collective on Mat
4431 
4432    Input Parameters:
4433 +  mat - the matrix
4434 .  option - the option, one of those listed below (and possibly others),
4435 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
4436 
4437   Options Describing Matrix Structure:
4438 +    MAT_SYMMETRIC - symmetric in terms of both structure and value
4439 .    MAT_HERMITIAN - transpose is the complex conjugation
4440 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
4441 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
4442                             you set to be kept with all future use of the matrix
4443                             including after MatAssemblyBegin/End() which could
4444                             potentially change the symmetry structure, i.e. you
4445                             KNOW the matrix will ALWAYS have the property you set.
4446 
4447 
4448    Options For Use with MatSetValues():
4449    Insert a logically dense subblock, which can be
4450 .    MAT_ROW_ORIENTED - row-oriented (default)
4451 
4452    Note these options reflect the data you pass in with MatSetValues(); it has
4453    nothing to do with how the data is stored internally in the matrix
4454    data structure.
4455 
4456    When (re)assembling a matrix, we can restrict the input for
4457    efficiency/debugging purposes.  These options include
4458 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
4459         allowed if they generate a new nonzero
4460 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
4461 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
4462 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
4463 -    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
4464 
4465    Notes:
4466    Some options are relevant only for particular matrix types and
4467    are thus ignored by others.  Other options are not supported by
4468    certain matrix types and will generate an error message if set.
4469 
4470    If using a Fortran 77 module to compute a matrix, one may need to
4471    use the column-oriented option (or convert to the row-oriented
4472    format).
4473 
4474    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
4475    that would generate a new entry in the nonzero structure is instead
4476    ignored.  Thus, if memory has not alredy been allocated for this particular
4477    data, then the insertion is ignored. For dense matrices, in which
4478    the entire array is allocated, no entries are ever ignored.
4479    Set after the first MatAssemblyEnd()
4480 
4481    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
4482    that would generate a new entry in the nonzero structure instead produces
4483    an error. (Currently supported for AIJ and BAIJ formats only.)
4484    This is a useful flag when using SAME_NONZERO_PATTERN in calling
4485    KSPSetOperators() to ensure that the nonzero pattern truely does
4486    remain unchanged. Set after the first MatAssemblyEnd()
4487 
4488    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
4489    that would generate a new entry that has not been preallocated will
4490    instead produce an error. (Currently supported for AIJ and BAIJ formats
4491    only.) This is a useful flag when debugging matrix memory preallocation.
4492 
4493    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
4494    other processors should be dropped, rather than stashed.
4495    This is useful if you know that the "owning" processor is also
4496    always generating the correct matrix entries, so that PETSc need
4497    not transfer duplicate entries generated on another processor.
4498 
4499    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
4500    searches during matrix assembly. When this flag is set, the hash table
4501    is created during the first Matrix Assembly. This hash table is
4502    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
4503    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
4504    should be used with MAT_USE_HASH_TABLE flag. This option is currently
4505    supported by MATMPIBAIJ format only.
4506 
4507    MAT_KEEP_ZEROED_ROWS indicates when MatZeroRows() is called the zeroed entries
4508    are kept in the nonzero structure
4509 
4510    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
4511    a zero location in the matrix
4512 
4513    MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
4514    ROWBS matrix types
4515 
4516    Level: intermediate
4517 
4518    Concepts: matrices^setting options
4519 
4520 @*/
4521 PetscErrorCode PETSCMAT_DLLEXPORT MatSetOption(Mat mat,MatOption op,PetscTruth flg)
4522 {
4523   PetscErrorCode ierr;
4524 
4525   PetscFunctionBegin;
4526   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4527   PetscValidType(mat,1);
4528   if (((int) op) < 0 || ((int) op) > 16) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
4529   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4530   switch (op) {
4531   case MAT_SYMMETRIC:
4532     mat->symmetric                  = flg;
4533     if (flg) mat->structurally_symmetric     = PETSC_TRUE;
4534     mat->symmetric_set              = PETSC_TRUE;
4535     mat->structurally_symmetric_set = flg;
4536     break;
4537   case MAT_HERMITIAN:
4538     mat->hermitian                  = flg;
4539     if (flg) mat->structurally_symmetric     = PETSC_TRUE;
4540     mat->hermitian_set              = PETSC_TRUE;
4541     mat->structurally_symmetric_set = flg;
4542     break;
4543   case MAT_STRUCTURALLY_SYMMETRIC:
4544     mat->structurally_symmetric     = flg;
4545     mat->structurally_symmetric_set = PETSC_TRUE;
4546     break;
4547   case MAT_SYMMETRY_ETERNAL:
4548     mat->symmetric_eternal          = flg;
4549     break;
4550   default:
4551     break;
4552   }
4553   if (mat->ops->setoption) {
4554     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
4555   }
4556   PetscFunctionReturn(0);
4557 }
4558 
4559 #undef __FUNCT__
4560 #define __FUNCT__ "MatZeroEntries"
4561 /*@
4562    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
4563    this routine retains the old nonzero structure.
4564 
4565    Collective on Mat
4566 
4567    Input Parameters:
4568 .  mat - the matrix
4569 
4570    Level: intermediate
4571 
4572    Concepts: matrices^zeroing
4573 
4574 .seealso: MatZeroRows()
4575 @*/
4576 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroEntries(Mat mat)
4577 {
4578   PetscErrorCode ierr;
4579 
4580   PetscFunctionBegin;
4581   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4582   PetscValidType(mat,1);
4583   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4584   if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
4585   if (!mat->ops->zeroentries) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4586   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4587 
4588   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
4589   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
4590   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
4591   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4592   PetscFunctionReturn(0);
4593 }
4594 
4595 #undef __FUNCT__
4596 #define __FUNCT__ "MatZeroRows"
4597 /*@C
4598    MatZeroRows - Zeros all entries (except possibly the main diagonal)
4599    of a set of rows of a matrix.
4600 
4601    Collective on Mat
4602 
4603    Input Parameters:
4604 +  mat - the matrix
4605 .  numRows - the number of rows to remove
4606 .  rows - the global row indices
4607 -  diag - value put in all diagonals of eliminated rows
4608 
4609    Notes:
4610    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4611    but does not release memory.  For the dense and block diagonal
4612    formats this does not alter the nonzero structure.
4613 
4614    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4615    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4616    merely zeroed.
4617 
4618    The user can set a value in the diagonal entry (or for the AIJ and
4619    row formats can optionally remove the main diagonal entry from the
4620    nonzero structure as well, by passing 0.0 as the final argument).
4621 
4622    For the parallel case, all processes that share the matrix (i.e.,
4623    those in the communicator used for matrix creation) MUST call this
4624    routine, regardless of whether any rows being zeroed are owned by
4625    them.
4626 
4627    Each processor should list the rows that IT wants zeroed
4628 
4629    Level: intermediate
4630 
4631    Concepts: matrices^zeroing rows
4632 
4633 .seealso: MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4634 @*/
4635 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4636 {
4637   PetscErrorCode ierr;
4638 
4639   PetscFunctionBegin;
4640   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4641   PetscValidType(mat,1);
4642   if (numRows) PetscValidIntPointer(rows,3);
4643   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4644   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4645   if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4646   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4647 
4648   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag);CHKERRQ(ierr);
4649   ierr = MatView_Private(mat);CHKERRQ(ierr);
4650   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4651   PetscFunctionReturn(0);
4652 }
4653 
4654 #undef __FUNCT__
4655 #define __FUNCT__ "MatZeroRowsIS"
4656 /*@C
4657    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
4658    of a set of rows of a matrix.
4659 
4660    Collective on Mat
4661 
4662    Input Parameters:
4663 +  mat - the matrix
4664 .  is - index set of rows to remove
4665 -  diag - value put in all diagonals of eliminated rows
4666 
4667    Notes:
4668    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4669    but does not release memory.  For the dense and block diagonal
4670    formats this does not alter the nonzero structure.
4671 
4672    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4673    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4674    merely zeroed.
4675 
4676    The user can set a value in the diagonal entry (or for the AIJ and
4677    row formats can optionally remove the main diagonal entry from the
4678    nonzero structure as well, by passing 0.0 as the final argument).
4679 
4680    For the parallel case, all processes that share the matrix (i.e.,
4681    those in the communicator used for matrix creation) MUST call this
4682    routine, regardless of whether any rows being zeroed are owned by
4683    them.
4684 
4685    Each processor should list the rows that IT wants zeroed
4686 
4687    Level: intermediate
4688 
4689    Concepts: matrices^zeroing rows
4690 
4691 .seealso: MatZeroRows(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4692 @*/
4693 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsIS(Mat mat,IS is,PetscScalar diag)
4694 {
4695   PetscInt       numRows;
4696   PetscInt       *rows;
4697   PetscErrorCode ierr;
4698 
4699   PetscFunctionBegin;
4700   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4701   PetscValidType(mat,1);
4702   PetscValidHeaderSpecific(is,IS_COOKIE,2);
4703   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
4704   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
4705   ierr = MatZeroRows(mat,numRows,rows,diag);CHKERRQ(ierr);
4706   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
4707   PetscFunctionReturn(0);
4708 }
4709 
4710 #undef __FUNCT__
4711 #define __FUNCT__ "MatZeroRowsLocal"
4712 /*@C
4713    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
4714    of a set of rows of a matrix; using local numbering of rows.
4715 
4716    Collective on Mat
4717 
4718    Input Parameters:
4719 +  mat - the matrix
4720 .  numRows - the number of rows to remove
4721 .  rows - the global row indices
4722 -  diag - value put in all diagonals of eliminated rows
4723 
4724    Notes:
4725    Before calling MatZeroRowsLocal(), the user must first set the
4726    local-to-global mapping by calling MatSetLocalToGlobalMapping().
4727 
4728    For the AIJ matrix formats this removes the old nonzero structure,
4729    but does not release memory.  For the dense and block diagonal
4730    formats this does not alter the nonzero structure.
4731 
4732    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4733    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4734    merely zeroed.
4735 
4736    The user can set a value in the diagonal entry (or for the AIJ and
4737    row formats can optionally remove the main diagonal entry from the
4738    nonzero structure as well, by passing 0.0 as the final argument).
4739 
4740    Level: intermediate
4741 
4742    Concepts: matrices^zeroing
4743 
4744 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
4745 @*/
4746 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4747 {
4748   PetscErrorCode ierr;
4749 
4750   PetscFunctionBegin;
4751   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4752   PetscValidType(mat,1);
4753   if (numRows) PetscValidIntPointer(rows,3);
4754   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4755   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4756   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4757 
4758   if (mat->ops->zerorowslocal) {
4759     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag);CHKERRQ(ierr);
4760   } else {
4761     IS is, newis;
4762     PetscInt *newRows;
4763 
4764     if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
4765     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,&is);CHKERRQ(ierr);
4766     ierr = ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);CHKERRQ(ierr);
4767     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
4768     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag);CHKERRQ(ierr);
4769     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
4770     ierr = ISDestroy(newis);CHKERRQ(ierr);
4771     ierr = ISDestroy(is);CHKERRQ(ierr);
4772   }
4773   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4774   PetscFunctionReturn(0);
4775 }
4776 
4777 #undef __FUNCT__
4778 #define __FUNCT__ "MatZeroRowsLocalIS"
4779 /*@C
4780    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
4781    of a set of rows of a matrix; using local numbering of rows.
4782 
4783    Collective on Mat
4784 
4785    Input Parameters:
4786 +  mat - the matrix
4787 .  is - index set of rows to remove
4788 -  diag - value put in all diagonals of eliminated rows
4789 
4790    Notes:
4791    Before calling MatZeroRowsLocalIS(), the user must first set the
4792    local-to-global mapping by calling MatSetLocalToGlobalMapping().
4793 
4794    For the AIJ matrix formats this removes the old nonzero structure,
4795    but does not release memory.  For the dense and block diagonal
4796    formats this does not alter the nonzero structure.
4797 
4798    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4799    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4800    merely zeroed.
4801 
4802    The user can set a value in the diagonal entry (or for the AIJ and
4803    row formats can optionally remove the main diagonal entry from the
4804    nonzero structure as well, by passing 0.0 as the final argument).
4805 
4806    Level: intermediate
4807 
4808    Concepts: matrices^zeroing
4809 
4810 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
4811 @*/
4812 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag)
4813 {
4814   PetscErrorCode ierr;
4815   PetscInt       numRows;
4816   PetscInt       *rows;
4817 
4818   PetscFunctionBegin;
4819   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4820   PetscValidType(mat,1);
4821   PetscValidHeaderSpecific(is,IS_COOKIE,2);
4822   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4823   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4824   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4825 
4826   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
4827   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
4828   ierr = MatZeroRowsLocal(mat,numRows,rows,diag);CHKERRQ(ierr);
4829   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
4830   PetscFunctionReturn(0);
4831 }
4832 
4833 #undef __FUNCT__
4834 #define __FUNCT__ "MatGetSize"
4835 /*@
4836    MatGetSize - Returns the numbers of rows and columns in a matrix.
4837 
4838    Not Collective
4839 
4840    Input Parameter:
4841 .  mat - the matrix
4842 
4843    Output Parameters:
4844 +  m - the number of global rows
4845 -  n - the number of global columns
4846 
4847    Note: both output parameters can be PETSC_NULL on input.
4848 
4849    Level: beginner
4850 
4851    Concepts: matrices^size
4852 
4853 .seealso: MatGetLocalSize()
4854 @*/
4855 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
4856 {
4857   PetscFunctionBegin;
4858   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4859   if (m) *m = mat->rmap.N;
4860   if (n) *n = mat->cmap.N;
4861   PetscFunctionReturn(0);
4862 }
4863 
4864 #undef __FUNCT__
4865 #define __FUNCT__ "MatGetLocalSize"
4866 /*@
4867    MatGetLocalSize - Returns the number of rows and columns in a matrix
4868    stored locally.  This information may be implementation dependent, so
4869    use with care.
4870 
4871    Not Collective
4872 
4873    Input Parameters:
4874 .  mat - the matrix
4875 
4876    Output Parameters:
4877 +  m - the number of local rows
4878 -  n - the number of local columns
4879 
4880    Note: both output parameters can be PETSC_NULL on input.
4881 
4882    Level: beginner
4883 
4884    Concepts: matrices^local size
4885 
4886 .seealso: MatGetSize()
4887 @*/
4888 PetscErrorCode PETSCMAT_DLLEXPORT MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
4889 {
4890   PetscFunctionBegin;
4891   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4892   if (m) PetscValidIntPointer(m,2);
4893   if (n) PetscValidIntPointer(n,3);
4894   if (m) *m = mat->rmap.n;
4895   if (n) *n = mat->cmap.n;
4896   PetscFunctionReturn(0);
4897 }
4898 
4899 #undef __FUNCT__
4900 #define __FUNCT__ "MatGetOwnershipRangeColumn"
4901 /*@
4902    MatGetOwnershipRangeColumn - Returns the range of matrix columns owned by
4903    this processor.
4904 
4905    Not Collective
4906 
4907    Input Parameters:
4908 .  mat - the matrix
4909 
4910    Output Parameters:
4911 +  m - the global index of the first local column
4912 -  n - one more than the global index of the last local column
4913 
4914    Notes: both output parameters can be PETSC_NULL on input.
4915 
4916    Level: developer
4917 
4918    Concepts: matrices^column ownership
4919 @*/
4920 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
4921 {
4922   PetscErrorCode ierr;
4923 
4924   PetscFunctionBegin;
4925   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4926   PetscValidType(mat,1);
4927   if (m) PetscValidIntPointer(m,2);
4928   if (n) PetscValidIntPointer(n,3);
4929   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4930   if (m) *m = mat->cmap.rstart;
4931   if (n) *n = mat->cmap.rend;
4932   PetscFunctionReturn(0);
4933 }
4934 
4935 #undef __FUNCT__
4936 #define __FUNCT__ "MatGetOwnershipRange"
4937 /*@
4938    MatGetOwnershipRange - Returns the range of matrix rows owned by
4939    this processor, assuming that the matrix is laid out with the first
4940    n1 rows on the first processor, the next n2 rows on the second, etc.
4941    For certain parallel layouts this range may not be well defined.
4942 
4943    Not Collective
4944 
4945    Input Parameters:
4946 .  mat - the matrix
4947 
4948    Output Parameters:
4949 +  m - the global index of the first local row
4950 -  n - one more than the global index of the last local row
4951 
4952    Note: both output parameters can be PETSC_NULL on input.
4953 
4954    Level: beginner
4955 
4956    Concepts: matrices^row ownership
4957 
4958 .seealso:   MatGetOwnershipRanges()
4959 
4960 @*/
4961 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
4962 {
4963   PetscErrorCode ierr;
4964 
4965   PetscFunctionBegin;
4966   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4967   PetscValidType(mat,1);
4968   if (m) PetscValidIntPointer(m,2);
4969   if (n) PetscValidIntPointer(n,3);
4970   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4971   if (m) *m = mat->rmap.rstart;
4972   if (n) *n = mat->rmap.rend;
4973   PetscFunctionReturn(0);
4974 }
4975 
4976 #undef __FUNCT__
4977 #define __FUNCT__ "MatGetOwnershipRanges"
4978 /*@C
4979    MatGetOwnershipRanges - Returns the range of matrix rows owned by
4980    each process
4981 
4982    Not Collective
4983 
4984    Input Parameters:
4985 .  mat - the matrix
4986 
4987    Output Parameters:
4988 .  ranges - start of each processors portion plus one more then the total length at the end
4989 
4990    Level: beginner
4991 
4992    Concepts: matrices^row ownership
4993 
4994 .seealso:   MatGetOwnershipRange()
4995 
4996 @*/
4997 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
4998 {
4999   PetscErrorCode ierr;
5000 
5001   PetscFunctionBegin;
5002   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5003   PetscValidType(mat,1);
5004   ierr = PetscMapGetGlobalRange(&mat->rmap,ranges);CHKERRQ(ierr);
5005   PetscFunctionReturn(0);
5006 }
5007 
5008 #undef __FUNCT__
5009 #define __FUNCT__ "MatILUFactorSymbolic"
5010 /*@
5011    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
5012    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
5013    to complete the factorization.
5014 
5015    Collective on Mat
5016 
5017    Input Parameters:
5018 +  mat - the matrix
5019 .  row - row permutation
5020 .  column - column permutation
5021 -  info - structure containing
5022 $      levels - number of levels of fill.
5023 $      expected fill - as ratio of original fill.
5024 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
5025                 missing diagonal entries)
5026 
5027    Output Parameters:
5028 .  fact - new matrix that has been symbolically factored
5029 
5030    Notes:
5031    See the users manual for additional information about
5032    choosing the fill factor for better efficiency.
5033 
5034    Most users should employ the simplified KSP interface for linear solvers
5035    instead of working directly with matrix algebra routines such as this.
5036    See, e.g., KSPCreate().
5037 
5038    Level: developer
5039 
5040   Concepts: matrices^symbolic LU factorization
5041   Concepts: matrices^factorization
5042   Concepts: LU^symbolic factorization
5043 
5044 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5045           MatGetOrdering(), MatFactorInfo
5046 
5047 @*/
5048 PetscErrorCode PETSCMAT_DLLEXPORT MatILUFactorSymbolic(Mat mat,IS row,IS col,MatFactorInfo *info,Mat *fact)
5049 {
5050   PetscErrorCode ierr;
5051 
5052   PetscFunctionBegin;
5053   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5054   PetscValidType(mat,1);
5055   PetscValidHeaderSpecific(row,IS_COOKIE,2);
5056   PetscValidHeaderSpecific(col,IS_COOKIE,3);
5057   PetscValidPointer(info,4);
5058   PetscValidPointer(fact,5);
5059   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
5060   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5061   if (!mat->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",((PetscObject)mat)->type_name);
5062   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5063   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5064   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5065 
5066   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
5067   ierr = (*mat->ops->ilufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
5068   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
5069   PetscFunctionReturn(0);
5070 }
5071 
5072 #undef __FUNCT__
5073 #define __FUNCT__ "MatICCFactorSymbolic"
5074 /*@
5075    MatICCFactorSymbolic - Performs symbolic incomplete
5076    Cholesky factorization for a symmetric matrix.  Use
5077    MatCholeskyFactorNumeric() to complete the factorization.
5078 
5079    Collective on Mat
5080 
5081    Input Parameters:
5082 +  mat - the matrix
5083 .  perm - row and column permutation
5084 -  info - structure containing
5085 $      levels - number of levels of fill.
5086 $      expected fill - as ratio of original fill.
5087 
5088    Output Parameter:
5089 .  fact - the factored matrix
5090 
5091    Notes:
5092    Most users should employ the KSP interface for linear solvers
5093    instead of working directly with matrix algebra routines such as this.
5094    See, e.g., KSPCreate().
5095 
5096    Level: developer
5097 
5098   Concepts: matrices^symbolic incomplete Cholesky factorization
5099   Concepts: matrices^factorization
5100   Concepts: Cholsky^symbolic factorization
5101 
5102 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
5103 @*/
5104 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactorSymbolic(Mat mat,IS perm,MatFactorInfo *info,Mat *fact)
5105 {
5106   PetscErrorCode ierr;
5107 
5108   PetscFunctionBegin;
5109   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5110   PetscValidType(mat,1);
5111   PetscValidHeaderSpecific(perm,IS_COOKIE,2);
5112   PetscValidPointer(info,3);
5113   PetscValidPointer(fact,4);
5114   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5115   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
5116   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5117   if (!mat->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",((PetscObject)mat)->type_name);
5118   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5119   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5120 
5121   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
5122   ierr = (*mat->ops->iccfactorsymbolic)(mat,perm,info,fact);CHKERRQ(ierr);
5123   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
5124   PetscFunctionReturn(0);
5125 }
5126 
5127 #undef __FUNCT__
5128 #define __FUNCT__ "MatGetArray"
5129 /*@C
5130    MatGetArray - Returns a pointer to the element values in the matrix.
5131    The result of this routine is dependent on the underlying matrix data
5132    structure, and may not even work for certain matrix types.  You MUST
5133    call MatRestoreArray() when you no longer need to access the array.
5134 
5135    Not Collective
5136 
5137    Input Parameter:
5138 .  mat - the matrix
5139 
5140    Output Parameter:
5141 .  v - the location of the values
5142 
5143 
5144    Fortran Note:
5145    This routine is used differently from Fortran, e.g.,
5146 .vb
5147         Mat         mat
5148         PetscScalar mat_array(1)
5149         PetscOffset i_mat
5150         PetscErrorCode ierr
5151         call MatGetArray(mat,mat_array,i_mat,ierr)
5152 
5153   C  Access first local entry in matrix; note that array is
5154   C  treated as one dimensional
5155         value = mat_array(i_mat + 1)
5156 
5157         [... other code ...]
5158         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5159 .ve
5160 
5161    See the Fortran chapter of the users manual and
5162    petsc/src/mat/examples/tests for details.
5163 
5164    Level: advanced
5165 
5166    Concepts: matrices^access array
5167 
5168 .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
5169 @*/
5170 PetscErrorCode PETSCMAT_DLLEXPORT MatGetArray(Mat mat,PetscScalar *v[])
5171 {
5172   PetscErrorCode ierr;
5173 
5174   PetscFunctionBegin;
5175   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5176   PetscValidType(mat,1);
5177   PetscValidPointer(v,2);
5178   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5179   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5180   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
5181   CHKMEMQ;
5182   PetscFunctionReturn(0);
5183 }
5184 
5185 #undef __FUNCT__
5186 #define __FUNCT__ "MatRestoreArray"
5187 /*@C
5188    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
5189 
5190    Not Collective
5191 
5192    Input Parameter:
5193 +  mat - the matrix
5194 -  v - the location of the values
5195 
5196    Fortran Note:
5197    This routine is used differently from Fortran, e.g.,
5198 .vb
5199         Mat         mat
5200         PetscScalar mat_array(1)
5201         PetscOffset i_mat
5202         PetscErrorCode ierr
5203         call MatGetArray(mat,mat_array,i_mat,ierr)
5204 
5205   C  Access first local entry in matrix; note that array is
5206   C  treated as one dimensional
5207         value = mat_array(i_mat + 1)
5208 
5209         [... other code ...]
5210         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5211 .ve
5212 
5213    See the Fortran chapter of the users manual and
5214    petsc/src/mat/examples/tests for details
5215 
5216    Level: advanced
5217 
5218 .seealso: MatGetArray(), MatRestoreArrayF90()
5219 @*/
5220 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreArray(Mat mat,PetscScalar *v[])
5221 {
5222   PetscErrorCode ierr;
5223 
5224   PetscFunctionBegin;
5225   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5226   PetscValidType(mat,1);
5227   PetscValidPointer(v,2);
5228 #if defined(PETSC_USE_DEBUG)
5229   CHKMEMQ;
5230 #endif
5231   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5232   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
5233   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5234   PetscFunctionReturn(0);
5235 }
5236 
5237 #undef __FUNCT__
5238 #define __FUNCT__ "MatGetSubMatrices"
5239 /*@C
5240    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
5241    points to an array of valid matrices, they may be reused to store the new
5242    submatrices.
5243 
5244    Collective on Mat
5245 
5246    Input Parameters:
5247 +  mat - the matrix
5248 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
5249 .  irow, icol - index sets of rows and columns to extract
5250 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
5251 
5252    Output Parameter:
5253 .  submat - the array of submatrices
5254 
5255    Notes:
5256    MatGetSubMatrices() can extract ONLY sequential submatrices
5257    (from both sequential and parallel matrices). Use MatGetSubMatrix()
5258    to extract a parallel submatrix.
5259 
5260    When extracting submatrices from a parallel matrix, each processor can
5261    form a different submatrix by setting the rows and columns of its
5262    individual index sets according to the local submatrix desired.
5263 
5264    When finished using the submatrices, the user should destroy
5265    them with MatDestroyMatrices().
5266 
5267    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
5268    original matrix has not changed from that last call to MatGetSubMatrices().
5269 
5270    This routine creates the matrices in submat; you should NOT create them before
5271    calling it. It also allocates the array of matrix pointers submat.
5272 
5273    For BAIJ matrices the index sets must respect the block structure, that is if they
5274    request one row/column in a block, they must request all rows/columns that are in
5275    that block. For example, if the block size is 2 you cannot request just row 0 and
5276    column 0.
5277 
5278    Fortran Note:
5279    The Fortran interface is slightly different from that given below; it
5280    requires one to pass in  as submat a Mat (integer) array of size at least m.
5281 
5282    Level: advanced
5283 
5284    Concepts: matrices^accessing submatrices
5285    Concepts: submatrices
5286 
5287 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal()
5288 @*/
5289 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
5290 {
5291   PetscErrorCode ierr;
5292   PetscInt        i;
5293   PetscTruth      eq;
5294 
5295   PetscFunctionBegin;
5296   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5297   PetscValidType(mat,1);
5298   if (n) {
5299     PetscValidPointer(irow,3);
5300     PetscValidHeaderSpecific(*irow,IS_COOKIE,3);
5301     PetscValidPointer(icol,4);
5302     PetscValidHeaderSpecific(*icol,IS_COOKIE,4);
5303   }
5304   PetscValidPointer(submat,6);
5305   if (n && scall == MAT_REUSE_MATRIX) {
5306     PetscValidPointer(*submat,6);
5307     PetscValidHeaderSpecific(**submat,MAT_COOKIE,6);
5308   }
5309   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5310   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5311   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5312   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5313 
5314   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
5315   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
5316   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
5317   for (i=0; i<n; i++) {
5318     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
5319       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
5320       if (eq) {
5321 	if (mat->symmetric){
5322 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
5323 	} else if (mat->hermitian) {
5324 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
5325 	} else if (mat->structurally_symmetric) {
5326 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
5327 	}
5328       }
5329     }
5330   }
5331   PetscFunctionReturn(0);
5332 }
5333 
5334 #undef __FUNCT__
5335 #define __FUNCT__ "MatDestroyMatrices"
5336 /*@C
5337    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
5338 
5339    Collective on Mat
5340 
5341    Input Parameters:
5342 +  n - the number of local matrices
5343 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
5344                        sequence of MatGetSubMatrices())
5345 
5346    Level: advanced
5347 
5348     Notes: Frees not only the matrices, but also the array that contains the matrices
5349 
5350 .seealso: MatGetSubMatrices()
5351 @*/
5352 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroyMatrices(PetscInt n,Mat *mat[])
5353 {
5354   PetscErrorCode ierr;
5355   PetscInt       i;
5356 
5357   PetscFunctionBegin;
5358   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
5359   PetscValidPointer(mat,2);
5360   for (i=0; i<n; i++) {
5361     ierr = MatDestroy((*mat)[i]);CHKERRQ(ierr);
5362   }
5363   /* memory is allocated even if n = 0 */
5364   ierr = PetscFree(*mat);CHKERRQ(ierr);
5365   PetscFunctionReturn(0);
5366 }
5367 
5368 #undef __FUNCT__
5369 #define __FUNCT__ "MatGetSeqNonzeroStructure"
5370 /*@C
5371    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
5372 
5373    Collective on Mat
5374 
5375    Input Parameters:
5376 .  mat - the matrix
5377 
5378    Output Parameter:
5379 .  matstruct - the sequential matrix with the nonzero structure of mat
5380 
5381   Level: intermediate
5382 
5383 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
5384 @*/
5385 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct[])
5386 {
5387   PetscErrorCode ierr;
5388 
5389   PetscFunctionBegin;
5390   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5391   PetscValidPointer(matstruct,2);
5392 
5393   PetscValidType(mat,1);
5394   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5395   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5396 
5397   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
5398   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
5399   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
5400   PetscFunctionReturn(0);
5401 }
5402 
5403 #undef __FUNCT__
5404 #define __FUNCT__ "MatDestroySeqNonzeroStructure"
5405 /*@C
5406    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
5407 
5408    Collective on Mat
5409 
5410    Input Parameters:
5411 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
5412                        sequence of MatGetSequentialNonzeroStructure())
5413 
5414    Level: advanced
5415 
5416     Notes: Frees not only the matrices, but also the array that contains the matrices
5417 
5418 .seealso: MatGetSeqNonzeroStructure()
5419 @*/
5420 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroySeqNonzeroStructure(Mat *mat[])
5421 {
5422   PetscErrorCode ierr;
5423 
5424   PetscFunctionBegin;
5425   PetscValidPointer(mat,1);
5426   ierr = MatDestroyMatrices(1,mat);CHKERRQ(ierr);
5427   PetscFunctionReturn(0);
5428 }
5429 
5430 #undef __FUNCT__
5431 #define __FUNCT__ "MatIncreaseOverlap"
5432 /*@
5433    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
5434    replaces the index sets by larger ones that represent submatrices with
5435    additional overlap.
5436 
5437    Collective on Mat
5438 
5439    Input Parameters:
5440 +  mat - the matrix
5441 .  n   - the number of index sets
5442 .  is  - the array of index sets (these index sets will changed during the call)
5443 -  ov  - the additional overlap requested
5444 
5445    Level: developer
5446 
5447    Concepts: overlap
5448    Concepts: ASM^computing overlap
5449 
5450 .seealso: MatGetSubMatrices()
5451 @*/
5452 PetscErrorCode PETSCMAT_DLLEXPORT MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
5453 {
5454   PetscErrorCode ierr;
5455 
5456   PetscFunctionBegin;
5457   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5458   PetscValidType(mat,1);
5459   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
5460   if (n) {
5461     PetscValidPointer(is,3);
5462     PetscValidHeaderSpecific(*is,IS_COOKIE,3);
5463   }
5464   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5465   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5466   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5467 
5468   if (!ov) PetscFunctionReturn(0);
5469   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5470   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
5471   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
5472   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
5473   PetscFunctionReturn(0);
5474 }
5475 
5476 #undef __FUNCT__
5477 #define __FUNCT__ "MatGetBlockSize"
5478 /*@
5479    MatGetBlockSize - Returns the matrix block size; useful especially for the
5480    block row and block diagonal formats.
5481 
5482    Not Collective
5483 
5484    Input Parameter:
5485 .  mat - the matrix
5486 
5487    Output Parameter:
5488 .  bs - block size
5489 
5490    Notes:
5491    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
5492 
5493    Level: intermediate
5494 
5495    Concepts: matrices^block size
5496 
5497 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
5498 @*/
5499 PetscErrorCode PETSCMAT_DLLEXPORT MatGetBlockSize(Mat mat,PetscInt *bs)
5500 {
5501   PetscErrorCode ierr;
5502 
5503   PetscFunctionBegin;
5504   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5505   PetscValidType(mat,1);
5506   PetscValidIntPointer(bs,2);
5507   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5508   *bs = mat->rmap.bs;
5509   PetscFunctionReturn(0);
5510 }
5511 
5512 #undef __FUNCT__
5513 #define __FUNCT__ "MatSetBlockSize"
5514 /*@
5515    MatSetBlockSize - Sets the matrix block size; for many matrix types you
5516      cannot use this and MUST set the blocksize when you preallocate the matrix
5517 
5518    Collective on Mat
5519 
5520    Input Parameters:
5521 +  mat - the matrix
5522 -  bs - block size
5523 
5524    Notes:
5525      Only works for shell and AIJ matrices
5526 
5527    Level: intermediate
5528 
5529    Concepts: matrices^block size
5530 
5531 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
5532 @*/
5533 PetscErrorCode PETSCMAT_DLLEXPORT MatSetBlockSize(Mat mat,PetscInt bs)
5534 {
5535   PetscErrorCode ierr;
5536 
5537   PetscFunctionBegin;
5538   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5539   PetscValidType(mat,1);
5540   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5541   if (mat->ops->setblocksize) {
5542     mat->rmap.bs = bs;
5543     ierr = (*mat->ops->setblocksize)(mat,bs);CHKERRQ(ierr);
5544   } else {
5545     SETERRQ1(PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
5546   }
5547   PetscFunctionReturn(0);
5548 }
5549 
5550 #undef __FUNCT__
5551 #define __FUNCT__ "MatGetRowIJ"
5552 /*@C
5553     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
5554 
5555    Collective on Mat
5556 
5557     Input Parameters:
5558 +   mat - the matrix
5559 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
5560 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5561                 symmetrized
5562 -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5563                  blockcompressed matrix is desired or not [inode, baij have blockcompressed
5564                  nonzero structure which is different than the full nonzero structure]
5565 
5566     Output Parameters:
5567 +   n - number of rows in the (possibly compressed) matrix
5568 .   ia - the row pointers [of length n+1]
5569 .   ja - the column indices
5570 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
5571            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
5572 
5573     Level: developer
5574 
5575     Notes: You CANNOT change any of the ia[] or ja[] values.
5576 
5577            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
5578 
5579     Fortran Node
5580 
5581            In Fortran use
5582 $           PetscInt ia(1), ja(1)
5583 $           PetscOffset iia, jja
5584 $      call MatGetRowIJ(mat,shift,symmetric,blockcompressed,n,ia,iia,ja,jja,done,ierr)
5585 
5586        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
5587 
5588 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
5589 @*/
5590 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5591 {
5592   PetscErrorCode ierr;
5593 
5594   PetscFunctionBegin;
5595   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5596   PetscValidType(mat,1);
5597   PetscValidIntPointer(n,4);
5598   if (ia) PetscValidIntPointer(ia,5);
5599   if (ja) PetscValidIntPointer(ja,6);
5600   PetscValidIntPointer(done,7);
5601   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5602   if (!mat->ops->getrowij) *done = PETSC_FALSE;
5603   else {
5604     *done = PETSC_TRUE;
5605     ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
5606     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);CHKERRQ(ierr);
5607     ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
5608   }
5609   PetscFunctionReturn(0);
5610 }
5611 
5612 #undef __FUNCT__
5613 #define __FUNCT__ "MatGetColumnIJ"
5614 /*@C
5615     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
5616 
5617     Collective on Mat
5618 
5619     Input Parameters:
5620 +   mat - the matrix
5621 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5622 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5623                 symmetrized
5624 -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5625                  blockcompressed matrix is desired or not [inode, baij have blockcompressed
5626                  nonzero structure which is different than the full nonzero structure]
5627 
5628     Output Parameters:
5629 +   n - number of columns in the (possibly compressed) matrix
5630 .   ia - the column pointers
5631 .   ja - the row indices
5632 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
5633 
5634     Level: developer
5635 
5636 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5637 @*/
5638 PetscErrorCode PETSCMAT_DLLEXPORT MatGetColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5639 {
5640   PetscErrorCode ierr;
5641 
5642   PetscFunctionBegin;
5643   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5644   PetscValidType(mat,1);
5645   PetscValidIntPointer(n,4);
5646   if (ia) PetscValidIntPointer(ia,5);
5647   if (ja) PetscValidIntPointer(ja,6);
5648   PetscValidIntPointer(done,7);
5649   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5650   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
5651   else {
5652     *done = PETSC_TRUE;
5653     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);CHKERRQ(ierr);
5654   }
5655   PetscFunctionReturn(0);
5656 }
5657 
5658 #undef __FUNCT__
5659 #define __FUNCT__ "MatRestoreRowIJ"
5660 /*@C
5661     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
5662     MatGetRowIJ().
5663 
5664     Collective on Mat
5665 
5666     Input Parameters:
5667 +   mat - the matrix
5668 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5669 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5670                 symmetrized
5671 -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5672                  blockcompressed matrix is desired or not [inode, baij have blockcompressed
5673                  nonzero structure which is different than the full nonzero structure]
5674 
5675     Output Parameters:
5676 +   n - size of (possibly compressed) matrix
5677 .   ia - the row pointers
5678 .   ja - the column indices
5679 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5680 
5681     Level: developer
5682 
5683 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5684 @*/
5685 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5686 {
5687   PetscErrorCode ierr;
5688 
5689   PetscFunctionBegin;
5690   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5691   PetscValidType(mat,1);
5692   if (ia) PetscValidIntPointer(ia,5);
5693   if (ja) PetscValidIntPointer(ja,6);
5694   PetscValidIntPointer(done,7);
5695   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5696 
5697   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
5698   else {
5699     *done = PETSC_TRUE;
5700     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);CHKERRQ(ierr);
5701   }
5702   PetscFunctionReturn(0);
5703 }
5704 
5705 #undef __FUNCT__
5706 #define __FUNCT__ "MatRestoreColumnIJ"
5707 /*@C
5708     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
5709     MatGetColumnIJ().
5710 
5711     Collective on Mat
5712 
5713     Input Parameters:
5714 +   mat - the matrix
5715 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5716 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5717                 symmetrized
5718 -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5719                  blockcompressed matrix is desired or not [inode, baij have blockcompressed
5720                  nonzero structure which is different than the full nonzero structure]
5721 
5722     Output Parameters:
5723 +   n - size of (possibly compressed) matrix
5724 .   ia - the column pointers
5725 .   ja - the row indices
5726 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5727 
5728     Level: developer
5729 
5730 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
5731 @*/
5732 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5733 {
5734   PetscErrorCode ierr;
5735 
5736   PetscFunctionBegin;
5737   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5738   PetscValidType(mat,1);
5739   if (ia) PetscValidIntPointer(ia,5);
5740   if (ja) PetscValidIntPointer(ja,6);
5741   PetscValidIntPointer(done,7);
5742   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5743 
5744   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
5745   else {
5746     *done = PETSC_TRUE;
5747     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);CHKERRQ(ierr);
5748   }
5749   PetscFunctionReturn(0);
5750 }
5751 
5752 #undef __FUNCT__
5753 #define __FUNCT__ "MatColoringPatch"
5754 /*@C
5755     MatColoringPatch -Used inside matrix coloring routines that
5756     use MatGetRowIJ() and/or MatGetColumnIJ().
5757 
5758     Collective on Mat
5759 
5760     Input Parameters:
5761 +   mat - the matrix
5762 .   ncolors - max color value
5763 .   n   - number of entries in colorarray
5764 -   colorarray - array indicating color for each column
5765 
5766     Output Parameters:
5767 .   iscoloring - coloring generated using colorarray information
5768 
5769     Level: developer
5770 
5771 .seealso: MatGetRowIJ(), MatGetColumnIJ()
5772 
5773 @*/
5774 PetscErrorCode PETSCMAT_DLLEXPORT MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
5775 {
5776   PetscErrorCode ierr;
5777 
5778   PetscFunctionBegin;
5779   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5780   PetscValidType(mat,1);
5781   PetscValidIntPointer(colorarray,4);
5782   PetscValidPointer(iscoloring,5);
5783   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5784 
5785   if (!mat->ops->coloringpatch){
5786     ierr = ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
5787   } else {
5788     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
5789   }
5790   PetscFunctionReturn(0);
5791 }
5792 
5793 
5794 #undef __FUNCT__
5795 #define __FUNCT__ "MatSetUnfactored"
5796 /*@
5797    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
5798 
5799    Collective on Mat
5800 
5801    Input Parameter:
5802 .  mat - the factored matrix to be reset
5803 
5804    Notes:
5805    This routine should be used only with factored matrices formed by in-place
5806    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
5807    format).  This option can save memory, for example, when solving nonlinear
5808    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
5809    ILU(0) preconditioner.
5810 
5811    Note that one can specify in-place ILU(0) factorization by calling
5812 .vb
5813      PCType(pc,PCILU);
5814      PCFactorSeUseInPlace(pc);
5815 .ve
5816    or by using the options -pc_type ilu -pc_factor_in_place
5817 
5818    In-place factorization ILU(0) can also be used as a local
5819    solver for the blocks within the block Jacobi or additive Schwarz
5820    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
5821    of these preconditioners in the users manual for details on setting
5822    local solver options.
5823 
5824    Most users should employ the simplified KSP interface for linear solvers
5825    instead of working directly with matrix algebra routines such as this.
5826    See, e.g., KSPCreate().
5827 
5828    Level: developer
5829 
5830 .seealso: PCFactorSetUseInPlace()
5831 
5832    Concepts: matrices^unfactored
5833 
5834 @*/
5835 PetscErrorCode PETSCMAT_DLLEXPORT MatSetUnfactored(Mat mat)
5836 {
5837   PetscErrorCode ierr;
5838 
5839   PetscFunctionBegin;
5840   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5841   PetscValidType(mat,1);
5842   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5843   mat->factor = 0;
5844   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
5845   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
5846   PetscFunctionReturn(0);
5847 }
5848 
5849 /*MC
5850     MatGetArrayF90 - Accesses a matrix array from Fortran90.
5851 
5852     Synopsis:
5853     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
5854 
5855     Not collective
5856 
5857     Input Parameter:
5858 .   x - matrix
5859 
5860     Output Parameters:
5861 +   xx_v - the Fortran90 pointer to the array
5862 -   ierr - error code
5863 
5864     Example of Usage:
5865 .vb
5866       PetscScalar, pointer xx_v(:)
5867       ....
5868       call MatGetArrayF90(x,xx_v,ierr)
5869       a = xx_v(3)
5870       call MatRestoreArrayF90(x,xx_v,ierr)
5871 .ve
5872 
5873     Notes:
5874     Not yet supported for all F90 compilers
5875 
5876     Level: advanced
5877 
5878 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
5879 
5880     Concepts: matrices^accessing array
5881 
5882 M*/
5883 
5884 /*MC
5885     MatRestoreArrayF90 - Restores a matrix array that has been
5886     accessed with MatGetArrayF90().
5887 
5888     Synopsis:
5889     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
5890 
5891     Not collective
5892 
5893     Input Parameters:
5894 +   x - matrix
5895 -   xx_v - the Fortran90 pointer to the array
5896 
5897     Output Parameter:
5898 .   ierr - error code
5899 
5900     Example of Usage:
5901 .vb
5902        PetscScalar, pointer xx_v(:)
5903        ....
5904        call MatGetArrayF90(x,xx_v,ierr)
5905        a = xx_v(3)
5906        call MatRestoreArrayF90(x,xx_v,ierr)
5907 .ve
5908 
5909     Notes:
5910     Not yet supported for all F90 compilers
5911 
5912     Level: advanced
5913 
5914 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
5915 
5916 M*/
5917 
5918 
5919 #undef __FUNCT__
5920 #define __FUNCT__ "MatGetSubMatrix"
5921 /*@
5922     MatGetSubMatrix - Gets a single submatrix on the same number of processors
5923                       as the original matrix.
5924 
5925     Collective on Mat
5926 
5927     Input Parameters:
5928 +   mat - the original matrix
5929 .   isrow - rows this processor should obtain
5930 .   iscol - columns for all processors you wish to keep
5931 .   csize - number of columns "local" to this processor (does nothing for sequential
5932             matrices). This should match the result from VecGetLocalSize(x,...) if you
5933             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
5934 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
5935 
5936     Output Parameter:
5937 .   newmat - the new submatrix, of the same type as the old
5938 
5939     Level: advanced
5940 
5941     Notes: the iscol argument MUST be the same on each processor. You might be
5942     able to create the iscol argument with ISAllGather(). The rows is isrow will be
5943     sorted into the same order as the original matrix.
5944 
5945       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
5946    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
5947    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
5948    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
5949    you are finished using it.
5950 
5951     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
5952     the input matrix.
5953 
5954     Concepts: matrices^submatrices
5955 
5956 .seealso: MatGetSubMatrices(), ISAllGather()
5957 @*/
5958 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrix(Mat mat,IS isrow,IS iscol,PetscInt csize,MatReuse cll,Mat *newmat)
5959 {
5960   PetscErrorCode ierr;
5961   PetscMPIInt    size;
5962   Mat            *local;
5963 
5964   PetscFunctionBegin;
5965   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5966   PetscValidHeaderSpecific(isrow,IS_COOKIE,2);
5967   PetscValidHeaderSpecific(iscol,IS_COOKIE,3);
5968   PetscValidPointer(newmat,6);
5969   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_COOKIE,6);
5970   PetscValidType(mat,1);
5971   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5972   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5973   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5974 
5975   /* if original matrix is on just one processor then use submatrix generated */
5976   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
5977     ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
5978     PetscFunctionReturn(0);
5979   } else if (!mat->ops->getsubmatrix && size == 1) {
5980     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
5981     *newmat = *local;
5982     ierr    = PetscFree(local);CHKERRQ(ierr);
5983     PetscFunctionReturn(0);
5984   }
5985 
5986   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5987   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscol,csize,cll,newmat);CHKERRQ(ierr);
5988   ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);
5989   PetscFunctionReturn(0);
5990 }
5991 
5992 #undef __FUNCT__
5993 #define __FUNCT__ "MatGetSubMatrixRaw"
5994 /*@
5995     MatGetSubMatrixRaw - Gets a single submatrix on the same number of processors
5996                          as the original matrix.
5997 
5998     Collective on Mat
5999 
6000     Input Parameters:
6001 +   mat - the original matrix
6002 .   nrows - the number of rows this processor should obtain
6003 .   rows - rows this processor should obtain
6004 .   ncols - the number of columns for all processors you wish to keep
6005 .   cols - columns for all processors you wish to keep
6006 .   csize - number of columns "local" to this processor (does nothing for sequential
6007             matrices). This should match the result from VecGetLocalSize(x,...) if you
6008             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
6009 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6010 
6011     Output Parameter:
6012 .   newmat - the new submatrix, of the same type as the old
6013 
6014     Level: advanced
6015 
6016     Notes: the iscol argument MUST be the same on each processor. You might be
6017     able to create the iscol argument with ISAllGather().
6018 
6019       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
6020    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
6021    to this routine with a mat of the same nonzero structure and with a cll of MAT_REUSE_MATRIX
6022    will reuse the matrix generated the first time.
6023 
6024     Concepts: matrices^submatrices
6025 
6026 .seealso: MatGetSubMatrices(), ISAllGather()
6027 @*/
6028 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrixRaw(Mat mat,PetscInt nrows,const PetscInt rows[],PetscInt ncols,const PetscInt cols[],PetscInt csize,MatReuse cll,Mat *newmat)
6029 {
6030   IS             isrow, iscol;
6031   PetscErrorCode ierr;
6032 
6033   PetscFunctionBegin;
6034   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6035   PetscValidIntPointer(rows,2);
6036   PetscValidIntPointer(cols,3);
6037   PetscValidPointer(newmat,6);
6038   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_COOKIE,6);
6039   PetscValidType(mat,1);
6040   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6041   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6042   ierr = ISCreateGeneralWithArray(PETSC_COMM_SELF, nrows, (PetscInt *) rows, &isrow);CHKERRQ(ierr);
6043   ierr = ISCreateGeneralWithArray(PETSC_COMM_SELF, ncols, (PetscInt *) cols, &iscol);CHKERRQ(ierr);
6044   ierr = MatGetSubMatrix(mat, isrow, iscol, csize, cll, newmat);CHKERRQ(ierr);
6045   ierr = ISDestroy(isrow);CHKERRQ(ierr);
6046   ierr = ISDestroy(iscol);CHKERRQ(ierr);
6047   PetscFunctionReturn(0);
6048 }
6049 
6050 #undef __FUNCT__
6051 #define __FUNCT__ "MatStashSetInitialSize"
6052 /*@
6053    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
6054    used during the assembly process to store values that belong to
6055    other processors.
6056 
6057    Not Collective
6058 
6059    Input Parameters:
6060 +  mat   - the matrix
6061 .  size  - the initial size of the stash.
6062 -  bsize - the initial size of the block-stash(if used).
6063 
6064    Options Database Keys:
6065 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
6066 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
6067 
6068    Level: intermediate
6069 
6070    Notes:
6071      The block-stash is used for values set with MatSetValuesBlocked() while
6072      the stash is used for values set with MatSetValues()
6073 
6074      Run with the option -info and look for output of the form
6075      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
6076      to determine the appropriate value, MM, to use for size and
6077      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
6078      to determine the value, BMM to use for bsize
6079 
6080    Concepts: stash^setting matrix size
6081    Concepts: matrices^stash
6082 
6083 @*/
6084 PetscErrorCode PETSCMAT_DLLEXPORT MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
6085 {
6086   PetscErrorCode ierr;
6087 
6088   PetscFunctionBegin;
6089   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6090   PetscValidType(mat,1);
6091   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
6092   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
6093   PetscFunctionReturn(0);
6094 }
6095 
6096 #undef __FUNCT__
6097 #define __FUNCT__ "MatInterpolateAdd"
6098 /*@
6099    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
6100      the matrix
6101 
6102    Collective on Mat
6103 
6104    Input Parameters:
6105 +  mat   - the matrix
6106 .  x,y - the vectors
6107 -  w - where the result is stored
6108 
6109    Level: intermediate
6110 
6111    Notes:
6112     w may be the same vector as y.
6113 
6114     This allows one to use either the restriction or interpolation (its transpose)
6115     matrix to do the interpolation
6116 
6117     Concepts: interpolation
6118 
6119 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6120 
6121 @*/
6122 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
6123 {
6124   PetscErrorCode ierr;
6125   PetscInt       M,N;
6126 
6127   PetscFunctionBegin;
6128   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6129   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
6130   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
6131   PetscValidHeaderSpecific(w,VEC_COOKIE,4);
6132   PetscValidType(A,1);
6133   ierr = MatPreallocated(A);CHKERRQ(ierr);
6134   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6135   if (N > M) {
6136     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
6137   } else {
6138     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
6139   }
6140   PetscFunctionReturn(0);
6141 }
6142 
6143 #undef __FUNCT__
6144 #define __FUNCT__ "MatInterpolate"
6145 /*@
6146    MatInterpolate - y = A*x or A'*x depending on the shape of
6147      the matrix
6148 
6149    Collective on Mat
6150 
6151    Input Parameters:
6152 +  mat   - the matrix
6153 -  x,y - the vectors
6154 
6155    Level: intermediate
6156 
6157    Notes:
6158     This allows one to use either the restriction or interpolation (its transpose)
6159     matrix to do the interpolation
6160 
6161    Concepts: matrices^interpolation
6162 
6163 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6164 
6165 @*/
6166 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolate(Mat A,Vec x,Vec y)
6167 {
6168   PetscErrorCode ierr;
6169   PetscInt       M,N;
6170 
6171   PetscFunctionBegin;
6172   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6173   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
6174   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
6175   PetscValidType(A,1);
6176   ierr = MatPreallocated(A);CHKERRQ(ierr);
6177   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6178   if (N > M) {
6179     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
6180   } else {
6181     ierr = MatMult(A,x,y);CHKERRQ(ierr);
6182   }
6183   PetscFunctionReturn(0);
6184 }
6185 
6186 #undef __FUNCT__
6187 #define __FUNCT__ "MatRestrict"
6188 /*@
6189    MatRestrict - y = A*x or A'*x
6190 
6191    Collective on Mat
6192 
6193    Input Parameters:
6194 +  mat   - the matrix
6195 -  x,y - the vectors
6196 
6197    Level: intermediate
6198 
6199    Notes:
6200     This allows one to use either the restriction or interpolation (its transpose)
6201     matrix to do the restriction
6202 
6203    Concepts: matrices^restriction
6204 
6205 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
6206 
6207 @*/
6208 PetscErrorCode PETSCMAT_DLLEXPORT MatRestrict(Mat A,Vec x,Vec y)
6209 {
6210   PetscErrorCode ierr;
6211   PetscInt       M,N;
6212 
6213   PetscFunctionBegin;
6214   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6215   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
6216   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
6217   PetscValidType(A,1);
6218   ierr = MatPreallocated(A);CHKERRQ(ierr);
6219 
6220   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6221   if (N > M) {
6222     ierr = MatMult(A,x,y);CHKERRQ(ierr);
6223   } else {
6224     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
6225   }
6226   PetscFunctionReturn(0);
6227 }
6228 
6229 #undef __FUNCT__
6230 #define __FUNCT__ "MatNullSpaceAttach"
6231 /*@
6232    MatNullSpaceAttach - attaches a null space to a matrix.
6233         This null space will be removed from the resulting vector whenever
6234         MatMult() is called
6235 
6236    Collective on Mat
6237 
6238    Input Parameters:
6239 +  mat - the matrix
6240 -  nullsp - the null space object
6241 
6242    Level: developer
6243 
6244    Notes:
6245       Overwrites any previous null space that may have been attached
6246 
6247    Concepts: null space^attaching to matrix
6248 
6249 .seealso: MatCreate(), MatNullSpaceCreate()
6250 @*/
6251 PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
6252 {
6253   PetscErrorCode ierr;
6254 
6255   PetscFunctionBegin;
6256   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6257   PetscValidType(mat,1);
6258   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_COOKIE,2);
6259   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6260   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
6261   if (mat->nullsp) { ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr); }
6262   mat->nullsp = nullsp;
6263   PetscFunctionReturn(0);
6264 }
6265 
6266 #undef __FUNCT__
6267 #define __FUNCT__ "MatICCFactor"
6268 /*@
6269    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
6270 
6271    Collective on Mat
6272 
6273    Input Parameters:
6274 +  mat - the matrix
6275 .  row - row/column permutation
6276 .  fill - expected fill factor >= 1.0
6277 -  level - level of fill, for ICC(k)
6278 
6279    Notes:
6280    Probably really in-place only when level of fill is zero, otherwise allocates
6281    new space to store factored matrix and deletes previous memory.
6282 
6283    Most users should employ the simplified KSP interface for linear solvers
6284    instead of working directly with matrix algebra routines such as this.
6285    See, e.g., KSPCreate().
6286 
6287    Level: developer
6288 
6289    Concepts: matrices^incomplete Cholesky factorization
6290    Concepts: Cholesky factorization
6291 
6292 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6293 @*/
6294 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactor(Mat mat,IS row,MatFactorInfo* info)
6295 {
6296   PetscErrorCode ierr;
6297 
6298   PetscFunctionBegin;
6299   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6300   PetscValidType(mat,1);
6301   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
6302   PetscValidPointer(info,3);
6303   if (mat->rmap.N != mat->cmap.N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
6304   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6305   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6306   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6307   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6308   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
6309   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6310   PetscFunctionReturn(0);
6311 }
6312 
6313 #undef __FUNCT__
6314 #define __FUNCT__ "MatSetValuesAdic"
6315 /*@
6316    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
6317 
6318    Not Collective
6319 
6320    Input Parameters:
6321 +  mat - the matrix
6322 -  v - the values compute with ADIC
6323 
6324    Level: developer
6325 
6326    Notes:
6327      Must call MatSetColoring() before using this routine. Also this matrix must already
6328      have its nonzero pattern determined.
6329 
6330 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6331           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
6332 @*/
6333 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdic(Mat mat,void *v)
6334 {
6335   PetscErrorCode ierr;
6336 
6337   PetscFunctionBegin;
6338   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6339   PetscValidType(mat,1);
6340   PetscValidPointer(mat,2);
6341 
6342   if (!mat->assembled) {
6343     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6344   }
6345   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6346   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6347   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
6348   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6349   ierr = MatView_Private(mat);CHKERRQ(ierr);
6350   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6351   PetscFunctionReturn(0);
6352 }
6353 
6354 
6355 #undef __FUNCT__
6356 #define __FUNCT__ "MatSetColoring"
6357 /*@
6358    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
6359 
6360    Not Collective
6361 
6362    Input Parameters:
6363 +  mat - the matrix
6364 -  coloring - the coloring
6365 
6366    Level: developer
6367 
6368 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6369           MatSetValues(), MatSetValuesAdic()
6370 @*/
6371 PetscErrorCode PETSCMAT_DLLEXPORT MatSetColoring(Mat mat,ISColoring coloring)
6372 {
6373   PetscErrorCode ierr;
6374 
6375   PetscFunctionBegin;
6376   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6377   PetscValidType(mat,1);
6378   PetscValidPointer(coloring,2);
6379 
6380   if (!mat->assembled) {
6381     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6382   }
6383   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6384   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
6385   PetscFunctionReturn(0);
6386 }
6387 
6388 #undef __FUNCT__
6389 #define __FUNCT__ "MatSetValuesAdifor"
6390 /*@
6391    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
6392 
6393    Not Collective
6394 
6395    Input Parameters:
6396 +  mat - the matrix
6397 .  nl - leading dimension of v
6398 -  v - the values compute with ADIFOR
6399 
6400    Level: developer
6401 
6402    Notes:
6403      Must call MatSetColoring() before using this routine. Also this matrix must already
6404      have its nonzero pattern determined.
6405 
6406 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6407           MatSetValues(), MatSetColoring()
6408 @*/
6409 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
6410 {
6411   PetscErrorCode ierr;
6412 
6413   PetscFunctionBegin;
6414   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6415   PetscValidType(mat,1);
6416   PetscValidPointer(v,3);
6417 
6418   if (!mat->assembled) {
6419     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6420   }
6421   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6422   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6423   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
6424   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6425   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6426   PetscFunctionReturn(0);
6427 }
6428 
6429 #undef __FUNCT__
6430 #define __FUNCT__ "MatDiagonalScaleLocal"
6431 /*@
6432    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
6433          ghosted ones.
6434 
6435    Not Collective
6436 
6437    Input Parameters:
6438 +  mat - the matrix
6439 -  diag = the diagonal values, including ghost ones
6440 
6441    Level: developer
6442 
6443    Notes: Works only for MPIAIJ and MPIBAIJ matrices
6444 
6445 .seealso: MatDiagonalScale()
6446 @*/
6447 PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalScaleLocal(Mat mat,Vec diag)
6448 {
6449   PetscErrorCode ierr;
6450   PetscMPIInt    size;
6451 
6452   PetscFunctionBegin;
6453   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6454   PetscValidHeaderSpecific(diag,VEC_COOKIE,2);
6455   PetscValidType(mat,1);
6456 
6457   if (!mat->assembled) {
6458     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6459   }
6460   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
6461   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
6462   if (size == 1) {
6463     PetscInt n,m;
6464     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
6465     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
6466     if (m == n) {
6467       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
6468     } else {
6469       SETERRQ(PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
6470     }
6471   } else {
6472     PetscErrorCode (*f)(Mat,Vec);
6473     ierr = PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);CHKERRQ(ierr);
6474     if (f) {
6475       ierr = (*f)(mat,diag);CHKERRQ(ierr);
6476     } else {
6477       SETERRQ(PETSC_ERR_SUP,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
6478     }
6479   }
6480   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
6481   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6482   PetscFunctionReturn(0);
6483 }
6484 
6485 #undef __FUNCT__
6486 #define __FUNCT__ "MatGetInertia"
6487 /*@
6488    MatGetInertia - Gets the inertia from a factored matrix
6489 
6490    Collective on Mat
6491 
6492    Input Parameter:
6493 .  mat - the matrix
6494 
6495    Output Parameters:
6496 +   nneg - number of negative eigenvalues
6497 .   nzero - number of zero eigenvalues
6498 -   npos - number of positive eigenvalues
6499 
6500    Level: advanced
6501 
6502    Notes: Matrix must have been factored by MatCholeskyFactor()
6503 
6504 
6505 @*/
6506 PetscErrorCode PETSCMAT_DLLEXPORT MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
6507 {
6508   PetscErrorCode ierr;
6509 
6510   PetscFunctionBegin;
6511   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6512   PetscValidType(mat,1);
6513   if (!mat->factor)    SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6514   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
6515   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6516   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
6517   PetscFunctionReturn(0);
6518 }
6519 
6520 /* ----------------------------------------------------------------*/
6521 #undef __FUNCT__
6522 #define __FUNCT__ "MatSolves"
6523 /*@
6524    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
6525 
6526    Collective on Mat and Vecs
6527 
6528    Input Parameters:
6529 +  mat - the factored matrix
6530 -  b - the right-hand-side vectors
6531 
6532    Output Parameter:
6533 .  x - the result vectors
6534 
6535    Notes:
6536    The vectors b and x cannot be the same.  I.e., one cannot
6537    call MatSolves(A,x,x).
6538 
6539    Notes:
6540    Most users should employ the simplified KSP interface for linear solvers
6541    instead of working directly with matrix algebra routines such as this.
6542    See, e.g., KSPCreate().
6543 
6544    Level: developer
6545 
6546    Concepts: matrices^triangular solves
6547 
6548 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
6549 @*/
6550 PetscErrorCode PETSCMAT_DLLEXPORT MatSolves(Mat mat,Vecs b,Vecs x)
6551 {
6552   PetscErrorCode ierr;
6553 
6554   PetscFunctionBegin;
6555   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6556   PetscValidType(mat,1);
6557   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
6558   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6559   if (!mat->rmap.N && !mat->cmap.N) PetscFunctionReturn(0);
6560 
6561   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6562   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6563   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
6564   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
6565   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
6566   PetscFunctionReturn(0);
6567 }
6568 
6569 #undef __FUNCT__
6570 #define __FUNCT__ "MatIsSymmetric"
6571 /*@
6572    MatIsSymmetric - Test whether a matrix is symmetric
6573 
6574    Collective on Mat
6575 
6576    Input Parameter:
6577 +  A - the matrix to test
6578 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
6579 
6580    Output Parameters:
6581 .  flg - the result
6582 
6583    Level: intermediate
6584 
6585    Concepts: matrix^symmetry
6586 
6587 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6588 @*/
6589 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetric(Mat A,PetscReal tol,PetscTruth *flg)
6590 {
6591   PetscErrorCode ierr;
6592 
6593   PetscFunctionBegin;
6594   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6595   PetscValidPointer(flg,2);
6596   if (!A->symmetric_set) {
6597     if (!A->ops->issymmetric) {
6598       MatType mattype;
6599       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
6600       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
6601     }
6602     ierr = (*A->ops->issymmetric)(A,tol,&A->symmetric);CHKERRQ(ierr);
6603     A->symmetric_set = PETSC_TRUE;
6604     if (A->symmetric) {
6605       A->structurally_symmetric_set = PETSC_TRUE;
6606       A->structurally_symmetric     = PETSC_TRUE;
6607     }
6608   }
6609   *flg = A->symmetric;
6610   PetscFunctionReturn(0);
6611 }
6612 
6613 #undef __FUNCT__
6614 #define __FUNCT__ "MatIsHermitian"
6615 /*@
6616    MatIsHermitian - Test whether a matrix is Hermitian
6617 
6618    Collective on Mat
6619 
6620    Input Parameter:
6621 +  A - the matrix to test
6622 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
6623 
6624    Output Parameters:
6625 .  flg - the result
6626 
6627    Level: intermediate
6628 
6629    Concepts: matrix^symmetry
6630 
6631 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6632 @*/
6633 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitian(Mat A,PetscReal tol,PetscTruth *flg)
6634 {
6635   PetscErrorCode ierr;
6636 
6637   PetscFunctionBegin;
6638   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6639   PetscValidPointer(flg,2);
6640   if (!A->hermitian_set) {
6641     if (!A->ops->ishermitian) {
6642       MatType mattype;
6643       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
6644       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for Hermitian",mattype);
6645     }
6646     ierr = (*A->ops->ishermitian)(A,tol,&A->hermitian);CHKERRQ(ierr);
6647     A->hermitian_set = PETSC_TRUE;
6648     if (A->hermitian) {
6649       A->structurally_symmetric_set = PETSC_TRUE;
6650       A->structurally_symmetric     = PETSC_TRUE;
6651     }
6652   }
6653   *flg = A->hermitian;
6654   PetscFunctionReturn(0);
6655 }
6656 
6657 #undef __FUNCT__
6658 #define __FUNCT__ "MatIsSymmetricKnown"
6659 /*@
6660    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
6661 
6662    Collective on Mat
6663 
6664    Input Parameter:
6665 .  A - the matrix to check
6666 
6667    Output Parameters:
6668 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
6669 -  flg - the result
6670 
6671    Level: advanced
6672 
6673    Concepts: matrix^symmetry
6674 
6675    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
6676          if you want it explicitly checked
6677 
6678 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6679 @*/
6680 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetricKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6681 {
6682   PetscFunctionBegin;
6683   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6684   PetscValidPointer(set,2);
6685   PetscValidPointer(flg,3);
6686   if (A->symmetric_set) {
6687     *set = PETSC_TRUE;
6688     *flg = A->symmetric;
6689   } else {
6690     *set = PETSC_FALSE;
6691   }
6692   PetscFunctionReturn(0);
6693 }
6694 
6695 #undef __FUNCT__
6696 #define __FUNCT__ "MatIsHermitianKnown"
6697 /*@
6698    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
6699 
6700    Collective on Mat
6701 
6702    Input Parameter:
6703 .  A - the matrix to check
6704 
6705    Output Parameters:
6706 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
6707 -  flg - the result
6708 
6709    Level: advanced
6710 
6711    Concepts: matrix^symmetry
6712 
6713    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
6714          if you want it explicitly checked
6715 
6716 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6717 @*/
6718 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitianKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6719 {
6720   PetscFunctionBegin;
6721   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6722   PetscValidPointer(set,2);
6723   PetscValidPointer(flg,3);
6724   if (A->hermitian_set) {
6725     *set = PETSC_TRUE;
6726     *flg = A->hermitian;
6727   } else {
6728     *set = PETSC_FALSE;
6729   }
6730   PetscFunctionReturn(0);
6731 }
6732 
6733 #undef __FUNCT__
6734 #define __FUNCT__ "MatIsStructurallySymmetric"
6735 /*@
6736    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
6737 
6738    Collective on Mat
6739 
6740    Input Parameter:
6741 .  A - the matrix to test
6742 
6743    Output Parameters:
6744 .  flg - the result
6745 
6746    Level: intermediate
6747 
6748    Concepts: matrix^symmetry
6749 
6750 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
6751 @*/
6752 PetscErrorCode PETSCMAT_DLLEXPORT MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
6753 {
6754   PetscErrorCode ierr;
6755 
6756   PetscFunctionBegin;
6757   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6758   PetscValidPointer(flg,2);
6759   if (!A->structurally_symmetric_set) {
6760     if (!A->ops->isstructurallysymmetric) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
6761     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
6762     A->structurally_symmetric_set = PETSC_TRUE;
6763   }
6764   *flg = A->structurally_symmetric;
6765   PetscFunctionReturn(0);
6766 }
6767 
6768 #undef __FUNCT__
6769 #define __FUNCT__ "MatStashGetInfo"
6770 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
6771 /*@
6772    MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
6773        to be communicated to other processors during the MatAssemblyBegin/End() process
6774 
6775     Not collective
6776 
6777    Input Parameter:
6778 .   vec - the vector
6779 
6780    Output Parameters:
6781 +   nstash   - the size of the stash
6782 .   reallocs - the number of additional mallocs incurred.
6783 .   bnstash   - the size of the block stash
6784 -   breallocs - the number of additional mallocs incurred.in the block stash
6785 
6786    Level: advanced
6787 
6788 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
6789 
6790 @*/
6791 PetscErrorCode PETSCMAT_DLLEXPORT MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
6792 {
6793   PetscErrorCode ierr;
6794   PetscFunctionBegin;
6795   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
6796   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
6797   PetscFunctionReturn(0);
6798 }
6799 
6800 #undef __FUNCT__
6801 #define __FUNCT__ "MatGetVecs"
6802 /*@C
6803    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
6804      parallel layout
6805 
6806    Collective on Mat
6807 
6808    Input Parameter:
6809 .  mat - the matrix
6810 
6811    Output Parameter:
6812 +   right - (optional) vector that the matrix can be multiplied against
6813 -   left - (optional) vector that the matrix vector product can be stored in
6814 
6815   Level: advanced
6816 
6817 .seealso: MatCreate()
6818 @*/
6819 PetscErrorCode PETSCMAT_DLLEXPORT MatGetVecs(Mat mat,Vec *right,Vec *left)
6820 {
6821   PetscErrorCode ierr;
6822 
6823   PetscFunctionBegin;
6824   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6825   PetscValidType(mat,1);
6826   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6827   if (mat->ops->getvecs) {
6828     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
6829   } else {
6830     PetscMPIInt size;
6831     ierr = MPI_Comm_size(((PetscObject)mat)->comm, &size);CHKERRQ(ierr);
6832     if (right) {
6833       ierr = VecCreate(((PetscObject)mat)->comm,right);CHKERRQ(ierr);
6834       ierr = VecSetSizes(*right,mat->cmap.n,PETSC_DETERMINE);CHKERRQ(ierr);
6835       if (size > 1) {ierr = VecSetType(*right,VECMPI);CHKERRQ(ierr);}
6836       else {ierr = VecSetType(*right,VECSEQ);CHKERRQ(ierr);}
6837     }
6838     if (left) {
6839       ierr = VecCreate(((PetscObject)mat)->comm,left);CHKERRQ(ierr);
6840       ierr = VecSetSizes(*left,mat->rmap.n,PETSC_DETERMINE);CHKERRQ(ierr);
6841       if (size > 1) {ierr = VecSetType(*left,VECMPI);CHKERRQ(ierr);}
6842       else {ierr = VecSetType(*left,VECSEQ);CHKERRQ(ierr);}
6843     }
6844   }
6845   if (right) {ierr = VecSetBlockSize(*right,mat->rmap.bs);CHKERRQ(ierr);}
6846   if (left) {ierr = VecSetBlockSize(*left,mat->rmap.bs);CHKERRQ(ierr);}
6847   if (mat->mapping) {
6848     if (right) {ierr = VecSetLocalToGlobalMapping(*right,mat->mapping);CHKERRQ(ierr);}
6849     if (left) {ierr = VecSetLocalToGlobalMapping(*left,mat->mapping);CHKERRQ(ierr);}
6850   }
6851   if (mat->bmapping) {
6852     if (right) {ierr = VecSetLocalToGlobalMappingBlock(*right,mat->bmapping);CHKERRQ(ierr);}
6853     if (left) {ierr = VecSetLocalToGlobalMappingBlock(*left,mat->bmapping);CHKERRQ(ierr);}
6854   }
6855   PetscFunctionReturn(0);
6856 }
6857 
6858 #undef __FUNCT__
6859 #define __FUNCT__ "MatFactorInfoInitialize"
6860 /*@
6861    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
6862      with default values.
6863 
6864    Not Collective
6865 
6866    Input Parameters:
6867 .    info - the MatFactorInfo data structure
6868 
6869 
6870    Notes: The solvers are generally used through the KSP and PC objects, for example
6871           PCLU, PCILU, PCCHOLESKY, PCICC
6872 
6873    Level: developer
6874 
6875 .seealso: MatFactorInfo
6876 @*/
6877 
6878 PetscErrorCode PETSCMAT_DLLEXPORT MatFactorInfoInitialize(MatFactorInfo *info)
6879 {
6880   PetscErrorCode ierr;
6881 
6882   PetscFunctionBegin;
6883   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
6884   PetscFunctionReturn(0);
6885 }
6886 
6887 #undef __FUNCT__
6888 #define __FUNCT__ "MatPtAP"
6889 /*@
6890    MatPtAP - Creates the matrix projection C = P^T * A * P
6891 
6892    Collective on Mat
6893 
6894    Input Parameters:
6895 +  A - the matrix
6896 .  P - the projection matrix
6897 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6898 -  fill - expected fill as ratio of nnz(C)/nnz(A)
6899 
6900    Output Parameters:
6901 .  C - the product matrix
6902 
6903    Notes:
6904    C will be created and must be destroyed by the user with MatDestroy().
6905 
6906    This routine is currently only implemented for pairs of AIJ matrices and classes
6907    which inherit from AIJ.
6908 
6909    Level: intermediate
6910 
6911 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
6912 @*/
6913 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
6914 {
6915   PetscErrorCode ierr;
6916 
6917   PetscFunctionBegin;
6918   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6919   PetscValidType(A,1);
6920   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6921   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6922   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
6923   PetscValidType(P,2);
6924   MatPreallocated(P);
6925   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6926   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6927   PetscValidPointer(C,3);
6928   if (P->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap.N,A->cmap.N);
6929   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
6930   ierr = MatPreallocated(A);CHKERRQ(ierr);
6931 
6932   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
6933   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
6934   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
6935 
6936   PetscFunctionReturn(0);
6937 }
6938 
6939 #undef __FUNCT__
6940 #define __FUNCT__ "MatPtAPNumeric"
6941 /*@
6942    MatPtAPNumeric - Computes the matrix projection C = P^T * A * P
6943 
6944    Collective on Mat
6945 
6946    Input Parameters:
6947 +  A - the matrix
6948 -  P - the projection matrix
6949 
6950    Output Parameters:
6951 .  C - the product matrix
6952 
6953    Notes:
6954    C must have been created by calling MatPtAPSymbolic and must be destroyed by
6955    the user using MatDeatroy().
6956 
6957    This routine is currently only implemented for pairs of AIJ matrices and classes
6958    which inherit from AIJ.  C will be of type MATAIJ.
6959 
6960    Level: intermediate
6961 
6962 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
6963 @*/
6964 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPNumeric(Mat A,Mat P,Mat C)
6965 {
6966   PetscErrorCode ierr;
6967 
6968   PetscFunctionBegin;
6969   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6970   PetscValidType(A,1);
6971   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6972   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6973   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
6974   PetscValidType(P,2);
6975   MatPreallocated(P);
6976   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6977   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6978   PetscValidHeaderSpecific(C,MAT_COOKIE,3);
6979   PetscValidType(C,3);
6980   MatPreallocated(C);
6981   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6982   if (P->cmap.N!=C->rmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap.N,C->rmap.N);
6983   if (P->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap.N,A->cmap.N);
6984   if (A->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap.N,A->cmap.N);
6985   if (P->cmap.N!=C->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap.N,C->cmap.N);
6986   ierr = MatPreallocated(A);CHKERRQ(ierr);
6987 
6988   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
6989   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
6990   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
6991   PetscFunctionReturn(0);
6992 }
6993 
6994 #undef __FUNCT__
6995 #define __FUNCT__ "MatPtAPSymbolic"
6996 /*@
6997    MatPtAPSymbolic - Creates the (i,j) structure of the matrix projection C = P^T * A * P
6998 
6999    Collective on Mat
7000 
7001    Input Parameters:
7002 +  A - the matrix
7003 -  P - the projection matrix
7004 
7005    Output Parameters:
7006 .  C - the (i,j) structure of the product matrix
7007 
7008    Notes:
7009    C will be created and must be destroyed by the user with MatDestroy().
7010 
7011    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
7012    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
7013    this (i,j) structure by calling MatPtAPNumeric().
7014 
7015    Level: intermediate
7016 
7017 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
7018 @*/
7019 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
7020 {
7021   PetscErrorCode ierr;
7022 
7023   PetscFunctionBegin;
7024   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7025   PetscValidType(A,1);
7026   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7027   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7028   if (fill <1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7029   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
7030   PetscValidType(P,2);
7031   MatPreallocated(P);
7032   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7033   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7034   PetscValidPointer(C,3);
7035 
7036   if (P->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap.N,A->cmap.N);
7037   if (A->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap.N,A->cmap.N);
7038   ierr = MatPreallocated(A);CHKERRQ(ierr);
7039   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
7040   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
7041   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
7042 
7043   ierr = MatSetBlockSize(*C,A->rmap.bs);CHKERRQ(ierr);
7044 
7045   PetscFunctionReturn(0);
7046 }
7047 
7048 #undef __FUNCT__
7049 #define __FUNCT__ "MatMatMult"
7050 /*@
7051    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
7052 
7053    Collective on Mat
7054 
7055    Input Parameters:
7056 +  A - the left matrix
7057 .  B - the right matrix
7058 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7059 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
7060           if the result is a dense matrix this is irrelevent
7061 
7062    Output Parameters:
7063 .  C - the product matrix
7064 
7065    Notes:
7066    Unless scall is MAT_REUSE_MATRIX C will be created.
7067 
7068    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7069 
7070    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7071    actually needed.
7072 
7073    If you have many matrices with the same non-zero structure to multiply, you
7074    should either
7075 $   1) use MAT_REUSE_MATRIX in all calls but the first or
7076 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
7077 
7078    Level: intermediate
7079 
7080 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
7081 @*/
7082 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7083 {
7084   PetscErrorCode ierr;
7085   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7086   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7087   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
7088 
7089   PetscFunctionBegin;
7090   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7091   PetscValidType(A,1);
7092   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7093   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7094   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7095   PetscValidType(B,2);
7096   MatPreallocated(B);
7097   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7098   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7099   PetscValidPointer(C,3);
7100   if (B->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->cmap.N);
7101   if (scall == MAT_REUSE_MATRIX){
7102     PetscValidPointer(*C,5);
7103     PetscValidHeaderSpecific(*C,MAT_COOKIE,5);
7104   }
7105   if (fill == PETSC_DEFAULT) fill = 2.0;
7106   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7107   ierr = MatPreallocated(A);CHKERRQ(ierr);
7108 
7109   fA = A->ops->matmult;
7110   fB = B->ops->matmult;
7111   if (fB == fA) {
7112     if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
7113     mult = fB;
7114   } else {
7115     /* dispatch based on the type of A and B */
7116     char  multname[256];
7117     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
7118     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7119     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
7120     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7121     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
7122     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
7123     if (!mult) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7124   }
7125   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
7126   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
7127   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
7128   PetscFunctionReturn(0);
7129 }
7130 
7131 #undef __FUNCT__
7132 #define __FUNCT__ "MatMatMultSymbolic"
7133 /*@
7134    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
7135    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
7136 
7137    Collective on Mat
7138 
7139    Input Parameters:
7140 +  A - the left matrix
7141 .  B - the right matrix
7142 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
7143       if C is a dense matrix this is irrelevent
7144 
7145    Output Parameters:
7146 .  C - the product matrix
7147 
7148    Notes:
7149    Unless scall is MAT_REUSE_MATRIX C will be created.
7150 
7151    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7152    actually needed.
7153 
7154    This routine is currently implemented for
7155     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
7156     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7157     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7158 
7159    Level: intermediate
7160 
7161 .seealso: MatMatMult(), MatMatMultNumeric()
7162 @*/
7163 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
7164 {
7165   PetscErrorCode ierr;
7166   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
7167   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
7168   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
7169 
7170   PetscFunctionBegin;
7171   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7172   PetscValidType(A,1);
7173   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7174   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7175 
7176   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7177   PetscValidType(B,2);
7178   MatPreallocated(B);
7179   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7180   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7181   PetscValidPointer(C,3);
7182 
7183   if (B->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->cmap.N);
7184   if (fill == PETSC_DEFAULT) fill = 2.0;
7185   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7186   ierr = MatPreallocated(A);CHKERRQ(ierr);
7187 
7188   Asymbolic = A->ops->matmultsymbolic;
7189   Bsymbolic = B->ops->matmultsymbolic;
7190   if (Asymbolic == Bsymbolic){
7191     if (!Bsymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
7192     symbolic = Bsymbolic;
7193   } else { /* dispatch based on the type of A and B */
7194     char  symbolicname[256];
7195     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
7196     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7197     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
7198     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7199     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
7200     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
7201     if (!symbolic) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7202   }
7203   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
7204   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
7205   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
7206   PetscFunctionReturn(0);
7207 }
7208 
7209 #undef __FUNCT__
7210 #define __FUNCT__ "MatMatMultNumeric"
7211 /*@
7212    MatMatMultNumeric - Performs the numeric matrix-matrix product.
7213    Call this routine after first calling MatMatMultSymbolic().
7214 
7215    Collective on Mat
7216 
7217    Input Parameters:
7218 +  A - the left matrix
7219 -  B - the right matrix
7220 
7221    Output Parameters:
7222 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
7223 
7224    Notes:
7225    C must have been created with MatMatMultSymbolic().
7226 
7227    This routine is currently implemented for
7228     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
7229     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7230     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7231 
7232    Level: intermediate
7233 
7234 .seealso: MatMatMult(), MatMatMultSymbolic()
7235 @*/
7236 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultNumeric(Mat A,Mat B,Mat C)
7237 {
7238   PetscErrorCode ierr;
7239   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
7240   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
7241   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
7242 
7243   PetscFunctionBegin;
7244   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7245   PetscValidType(A,1);
7246   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7247   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7248 
7249   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7250   PetscValidType(B,2);
7251   MatPreallocated(B);
7252   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7253   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7254 
7255   PetscValidHeaderSpecific(C,MAT_COOKIE,3);
7256   PetscValidType(C,3);
7257   MatPreallocated(C);
7258   if (!C->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7259   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7260 
7261   if (B->cmap.N!=C->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap.N,C->cmap.N);
7262   if (B->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->cmap.N);
7263   if (A->rmap.N!=C->rmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap.N,C->rmap.N);
7264   ierr = MatPreallocated(A);CHKERRQ(ierr);
7265 
7266   Anumeric = A->ops->matmultnumeric;
7267   Bnumeric = B->ops->matmultnumeric;
7268   if (Anumeric == Bnumeric){
7269     if (!Bnumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
7270     numeric = Bnumeric;
7271   } else {
7272     char  numericname[256];
7273     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
7274     ierr = PetscStrcat(numericname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7275     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
7276     ierr = PetscStrcat(numericname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7277     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
7278     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
7279     if (!numeric)
7280       SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7281   }
7282   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
7283   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
7284   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
7285   PetscFunctionReturn(0);
7286 }
7287 
7288 #undef __FUNCT__
7289 #define __FUNCT__ "MatMatMultTranspose"
7290 /*@
7291    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
7292 
7293    Collective on Mat
7294 
7295    Input Parameters:
7296 +  A - the left matrix
7297 .  B - the right matrix
7298 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7299 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
7300 
7301    Output Parameters:
7302 .  C - the product matrix
7303 
7304    Notes:
7305    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
7306 
7307    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7308 
7309   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7310    actually needed.
7311 
7312    This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
7313    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
7314 
7315    Level: intermediate
7316 
7317 .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
7318 @*/
7319 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7320 {
7321   PetscErrorCode ierr;
7322   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7323   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7324 
7325   PetscFunctionBegin;
7326   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7327   PetscValidType(A,1);
7328   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7329   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7330   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7331   PetscValidType(B,2);
7332   MatPreallocated(B);
7333   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7334   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7335   PetscValidPointer(C,3);
7336   if (B->rmap.N!=A->rmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->rmap.N);
7337   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7338   ierr = MatPreallocated(A);CHKERRQ(ierr);
7339 
7340   fA = A->ops->matmulttranspose;
7341   if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
7342   fB = B->ops->matmulttranspose;
7343   if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
7344   if (fB!=fA) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultTranspose requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7345 
7346   ierr = PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
7347   ierr = (*A->ops->matmulttranspose)(A,B,scall,fill,C);CHKERRQ(ierr);
7348   ierr = PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
7349 
7350   PetscFunctionReturn(0);
7351 }
7352 
7353 #undef __FUNCT__
7354 #define __FUNCT__ "MatGetRedundantMatrix"
7355 /*@C
7356    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
7357 
7358    Collective on Mat
7359 
7360    Input Parameters:
7361 +  mat - the matrix
7362 .  nsubcomm - the number of subcommunicators (= number of redundant pareallel or sequential matrices)
7363 .  subcomm - MPI communicator split from the communicator where mat resides in
7364 .  mlocal_red - number of local rows of the redundant matrix
7365 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7366 
7367    Output Parameter:
7368 .  matredundant - redundant matrix
7369 
7370    Notes:
7371    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
7372    original matrix has not changed from that last call to MatGetRedundantMatrix().
7373 
7374    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
7375    calling it.
7376 
7377    Only MPIAIJ matrix is supported.
7378 
7379    Level: advanced
7380 
7381    Concepts: subcommunicator
7382    Concepts: duplicate matrix
7383 
7384 .seealso: MatDestroy()
7385 @*/
7386 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
7387 {
7388   PetscErrorCode ierr;
7389 
7390   PetscFunctionBegin;
7391   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
7392   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
7393     PetscValidPointer(*matredundant,6);
7394     PetscValidHeaderSpecific(*matredundant,MAT_COOKIE,6);
7395   }
7396   if (!mat->ops->getredundantmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7397   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7398   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7399   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7400 
7401   ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
7402   ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr);
7403   ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
7404   PetscFunctionReturn(0);
7405 }
7406