xref: /petsc/src/mat/interface/matrix.c (revision b0c88d4da53470685f8bc73fa222c9ca9a6785ae)
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   PetscFunctionBegin;
3339   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3340   PetscValidType(mat,1);
3341   *type = mat->solvertype;
3342   PetscFunctionReturn(0);
3343 }
3344 
3345 #undef __FUNCT__
3346 #define __FUNCT__ "MatSetSolverType"
3347 /*@C
3348    MatSetSolverType - Sets the type of LU or Cholesky factorization/solver routines that are used
3349    or different type.
3350 
3351    Collective on Mat
3352 
3353    Input Parameters:
3354 +  mat - the matrix
3355 -  type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3356 
3357 
3358    Notes:
3359       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3360      such as superlu, mumps, spooles etc.
3361 
3362       PETSc must have been config/configure.py to use the external solver, using the option --download-package
3363 
3364    Level: intermediate
3365 
3366 
3367 .seealso: MatCopy(), MatDuplicate(), MatGetSolverType()
3368 @*/
3369 PetscErrorCode PETSCMAT_DLLEXPORT MatSetSolverType(Mat mat, MatSolverType type)
3370 {
3371   PetscErrorCode         ierr;
3372   char                   convname[256];
3373   PetscErrorCode         (*conv)(Mat,const char *);
3374 
3375   PetscFunctionBegin;
3376   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3377   PetscValidType(mat,1);
3378 
3379   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3380   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3381 
3382   ierr = PetscStrcpy(convname,"MatSetSolverType_");CHKERRQ(ierr);
3383   ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr);
3384   ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3385   ierr = PetscStrcat(convname,type);CHKERRQ(ierr);
3386   ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3387   ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3388   if (!conv) {
3389     PetscTruth flag;
3390     ierr = PetscStrcasecmp("petsc",type,&flag);CHKERRQ(ierr);
3391     if (flag) {
3392       SETERRQ1(PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc solver",mat->hdr.type_name);
3393     } else {
3394       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);
3395     }
3396   }
3397   if (mat->ops->destroysolver) {
3398     ierr = (*mat->ops->destroysolver)(mat);CHKERRQ(ierr);
3399   }
3400   ierr = (*conv)(mat,type);CHKERRQ(ierr);
3401   ierr = PetscStrfree(mat->solvertype);CHKERRQ(ierr);
3402   ierr = PetscStrallocpy(type,&mat->solvertype);CHKERRQ(ierr);
3403   PetscFunctionReturn(0);
3404 }
3405 
3406 
3407 #undef __FUNCT__
3408 #define __FUNCT__ "MatDuplicate"
3409 /*@
3410    MatDuplicate - Duplicates a matrix including the non-zero structure.
3411 
3412    Collective on Mat
3413 
3414    Input Parameters:
3415 +  mat - the matrix
3416 -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
3417         values as well or not
3418 
3419    Output Parameter:
3420 .  M - pointer to place new matrix
3421 
3422    Level: intermediate
3423 
3424    Concepts: matrices^duplicating
3425 
3426 .seealso: MatCopy(), MatConvert()
3427 @*/
3428 PetscErrorCode PETSCMAT_DLLEXPORT MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
3429 {
3430   PetscErrorCode ierr;
3431   Mat            B;
3432 
3433   PetscFunctionBegin;
3434   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3435   PetscValidType(mat,1);
3436   PetscValidPointer(M,3);
3437   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3438   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3439   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3440 
3441   *M  = 0;
3442   if (!mat->ops->duplicate) {
3443     SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type");
3444   }
3445   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3446   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
3447   B = *M;
3448   if (mat->mapping) {
3449     ierr = MatSetLocalToGlobalMapping(B,mat->mapping);CHKERRQ(ierr);
3450   }
3451   if (mat->bmapping) {
3452     ierr = MatSetLocalToGlobalMappingBlock(B,mat->bmapping);CHKERRQ(ierr);
3453   }
3454   ierr = PetscMapCopy(((PetscObject)mat)->comm,&mat->rmap,&B->rmap);CHKERRQ(ierr);
3455   ierr = PetscMapCopy(((PetscObject)mat)->comm,&mat->cmap,&B->cmap);CHKERRQ(ierr);
3456 
3457   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3458   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3459   PetscFunctionReturn(0);
3460 }
3461 
3462 #undef __FUNCT__
3463 #define __FUNCT__ "MatGetDiagonal"
3464 /*@
3465    MatGetDiagonal - Gets the diagonal of a matrix.
3466 
3467    Collective on Mat and Vec
3468 
3469    Input Parameters:
3470 +  mat - the matrix
3471 -  v - the vector for storing the diagonal
3472 
3473    Output Parameter:
3474 .  v - the diagonal of the matrix
3475 
3476    Notes: The result of this call are the same as if one converted the matrix to dense format
3477       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
3478 
3479    Level: intermediate
3480 
3481    Concepts: matrices^accessing diagonals
3482 
3483 .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
3484 @*/
3485 PetscErrorCode PETSCMAT_DLLEXPORT MatGetDiagonal(Mat mat,Vec v)
3486 {
3487   PetscErrorCode ierr;
3488 
3489   PetscFunctionBegin;
3490   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3491   PetscValidType(mat,1);
3492   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3493   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3494   if (!mat->ops->getdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3495   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3496 
3497   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
3498   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3499   PetscFunctionReturn(0);
3500 }
3501 
3502 #undef __FUNCT__
3503 #define __FUNCT__ "MatGetRowMin"
3504 /*@
3505    MatGetRowMin - Gets the minimum value (of the real part) of each
3506         row of the matrix
3507 
3508    Collective on Mat and Vec
3509 
3510    Input Parameters:
3511 .  mat - the matrix
3512 
3513    Output Parameter:
3514 +  v - the vector for storing the maximums
3515 -  idx - the indices of the column found for each row (optional)
3516 
3517    Level: intermediate
3518 
3519    Notes: The result of this call are the same as if one converted the matrix to dense format
3520       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
3521 
3522     This code is only implemented for a couple of matrix formats.
3523 
3524    Concepts: matrices^getting row maximums
3525 
3526 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
3527           MatGetRowMax()
3528 @*/
3529 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
3530 {
3531   PetscErrorCode ierr;
3532 
3533   PetscFunctionBegin;
3534   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3535   PetscValidType(mat,1);
3536   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3537   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3538   if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3539   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3540 
3541   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
3542   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3543   PetscFunctionReturn(0);
3544 }
3545 
3546 #undef __FUNCT__
3547 #define __FUNCT__ "MatGetRowMax"
3548 /*@
3549    MatGetRowMax - Gets the maximum value (of the real part) of each
3550         row of the matrix
3551 
3552    Collective on Mat and Vec
3553 
3554    Input Parameters:
3555 .  mat - the matrix
3556 
3557    Output Parameter:
3558 +  v - the vector for storing the maximums
3559 -  idx - the indices of the column found for each row (optional)
3560 
3561    Level: intermediate
3562 
3563    Notes: The result of this call are the same as if one converted the matrix to dense format
3564       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
3565 
3566     This code is only implemented for a couple of matrix formats.
3567 
3568    Concepts: matrices^getting row maximums
3569 
3570 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
3571 @*/
3572 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
3573 {
3574   PetscErrorCode ierr;
3575 
3576   PetscFunctionBegin;
3577   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3578   PetscValidType(mat,1);
3579   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3580   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3581   if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3582   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3583 
3584   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
3585   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3586   PetscFunctionReturn(0);
3587 }
3588 
3589 #undef __FUNCT__
3590 #define __FUNCT__ "MatGetRowMaxAbs"
3591 /*@
3592    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
3593         row of the matrix
3594 
3595    Collective on Mat and Vec
3596 
3597    Input Parameters:
3598 .  mat - the matrix
3599 
3600    Output Parameter:
3601 +  v - the vector for storing the maximums
3602 -  idx - the indices of the column found for each row (optional)
3603 
3604    Level: intermediate
3605 
3606    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
3607     row is 0 (the first column).
3608 
3609     This code is only implemented for a couple of matrix formats.
3610 
3611    Concepts: matrices^getting row maximums
3612 
3613 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3614 @*/
3615 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
3616 {
3617   PetscErrorCode ierr;
3618 
3619   PetscFunctionBegin;
3620   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3621   PetscValidType(mat,1);
3622   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3623   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3624   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3625   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3626   if (idx) {ierr = PetscMemzero(idx,mat->rmap.n*sizeof(PetscInt));CHKERRQ(ierr);}
3627 
3628   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
3629   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3630   PetscFunctionReturn(0);
3631 }
3632 
3633 #undef __FUNCT__
3634 #define __FUNCT__ "MatGetRowSum"
3635 /*@
3636    MatGetRowSum - Gets the sum of each row of the matrix
3637 
3638    Collective on Mat and Vec
3639 
3640    Input Parameters:
3641 .  mat - the matrix
3642 
3643    Output Parameter:
3644 .  v - the vector for storing the maximums
3645 
3646    Level: intermediate
3647 
3648    Notes: This code is slow since it is not currently specialized for different formats
3649 
3650    Concepts: matrices^getting row sums
3651 
3652 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3653 @*/
3654 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowSum(Mat mat, Vec v)
3655 {
3656   PetscInt       start, end, row;
3657   PetscScalar   *array;
3658   PetscErrorCode ierr;
3659 
3660   PetscFunctionBegin;
3661   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3662   PetscValidType(mat,1);
3663   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3664   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3665   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3666   ierr = MatGetOwnershipRange(mat, &start, &end);CHKERRQ(ierr);
3667   ierr = VecGetArray(v, &array);CHKERRQ(ierr);
3668   for(row = start; row < end; ++row) {
3669     PetscInt           ncols, col;
3670     const PetscInt    *cols;
3671     const PetscScalar *vals;
3672 
3673     array[row - start] = 0.0;
3674     ierr = MatGetRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr);
3675     for(col = 0; col < ncols; col++) {
3676       array[row - start] += vals[col];
3677     }
3678     ierr = MatRestoreRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr);
3679   }
3680   ierr = VecRestoreArray(v, &array);CHKERRQ(ierr);
3681   ierr = PetscObjectStateIncrease((PetscObject) v);CHKERRQ(ierr);
3682   PetscFunctionReturn(0);
3683 }
3684 
3685 #undef __FUNCT__
3686 #define __FUNCT__ "MatTranspose"
3687 /*@
3688    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
3689 
3690    Collective on Mat
3691 
3692    Input Parameter:
3693 +  mat - the matrix to transpose
3694 -  reuse - store the transpose matrix in the provided B
3695 
3696    Output Parameters:
3697 .  B - the transpose
3698 
3699    Notes:
3700      If you  pass in &mat for B the matrix will be done in place
3701 
3702    Level: intermediate
3703 
3704    Concepts: matrices^transposing
3705 
3706 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose()
3707 @*/
3708 PetscErrorCode PETSCMAT_DLLEXPORT MatTranspose(Mat mat,MatReuse reuse,Mat *B)
3709 {
3710   PetscErrorCode ierr;
3711 
3712   PetscFunctionBegin;
3713   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3714   PetscValidType(mat,1);
3715   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3716   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3717   if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3718   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3719 
3720   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
3721   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
3722   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
3723   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
3724   PetscFunctionReturn(0);
3725 }
3726 
3727 #undef __FUNCT__
3728 #define __FUNCT__ "MatIsTranspose"
3729 /*@
3730    MatIsTranspose - Test whether a matrix is another one's transpose,
3731         or its own, in which case it tests symmetry.
3732 
3733    Collective on Mat
3734 
3735    Input Parameter:
3736 +  A - the matrix to test
3737 -  B - the matrix to test against, this can equal the first parameter
3738 
3739    Output Parameters:
3740 .  flg - the result
3741 
3742    Notes:
3743    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
3744    has a running time of the order of the number of nonzeros; the parallel
3745    test involves parallel copies of the block-offdiagonal parts of the matrix.
3746 
3747    Level: intermediate
3748 
3749    Concepts: matrices^transposing, matrix^symmetry
3750 
3751 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
3752 @*/
3753 PetscErrorCode PETSCMAT_DLLEXPORT MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
3754 {
3755   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);
3756 
3757   PetscFunctionBegin;
3758   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
3759   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
3760   PetscValidPointer(flg,3);
3761   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
3762   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
3763   if (f && g) {
3764     if (f==g) {
3765       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
3766     } else {
3767       SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
3768     }
3769   }
3770   PetscFunctionReturn(0);
3771 }
3772 
3773 #undef __FUNCT__
3774 #define __FUNCT__ "MatIsHermitianTranspose"
3775 /*@
3776    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
3777 
3778    Collective on Mat
3779 
3780    Input Parameter:
3781 +  A - the matrix to test
3782 -  B - the matrix to test against, this can equal the first parameter
3783 
3784    Output Parameters:
3785 .  flg - the result
3786 
3787    Notes:
3788    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
3789    has a running time of the order of the number of nonzeros; the parallel
3790    test involves parallel copies of the block-offdiagonal parts of the matrix.
3791 
3792    Level: intermediate
3793 
3794    Concepts: matrices^transposing, matrix^symmetry
3795 
3796 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
3797 @*/
3798 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
3799 {
3800   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);
3801 
3802   PetscFunctionBegin;
3803   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
3804   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
3805   PetscValidPointer(flg,3);
3806   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
3807   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
3808   if (f && g) {
3809     if (f==g) {
3810       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
3811     } else {
3812       SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
3813     }
3814   }
3815   PetscFunctionReturn(0);
3816 }
3817 
3818 #undef __FUNCT__
3819 #define __FUNCT__ "MatPermute"
3820 /*@
3821    MatPermute - Creates a new matrix with rows and columns permuted from the
3822    original.
3823 
3824    Collective on Mat
3825 
3826    Input Parameters:
3827 +  mat - the matrix to permute
3828 .  row - row permutation, each processor supplies only the permutation for its rows
3829 -  col - column permutation, each processor needs the entire column permutation, that is
3830          this is the same size as the total number of columns in the matrix
3831 
3832    Output Parameters:
3833 .  B - the permuted matrix
3834 
3835    Level: advanced
3836 
3837    Concepts: matrices^permuting
3838 
3839 .seealso: MatGetOrdering()
3840 @*/
3841 PetscErrorCode PETSCMAT_DLLEXPORT MatPermute(Mat mat,IS row,IS col,Mat *B)
3842 {
3843   PetscErrorCode ierr;
3844 
3845   PetscFunctionBegin;
3846   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3847   PetscValidType(mat,1);
3848   PetscValidHeaderSpecific(row,IS_COOKIE,2);
3849   PetscValidHeaderSpecific(col,IS_COOKIE,3);
3850   PetscValidPointer(B,4);
3851   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3852   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3853   if (!mat->ops->permute) SETERRQ1(PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
3854   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3855 
3856   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
3857   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
3858   PetscFunctionReturn(0);
3859 }
3860 
3861 #undef __FUNCT__
3862 #define __FUNCT__ "MatPermuteSparsify"
3863 /*@
3864   MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the
3865   original and sparsified to the prescribed tolerance.
3866 
3867   Collective on Mat
3868 
3869   Input Parameters:
3870 + A    - The matrix to permute
3871 . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
3872 . frac - The half-bandwidth as a fraction of the total size, or 0.0
3873 . tol  - The drop tolerance
3874 . rowp - The row permutation
3875 - colp - The column permutation
3876 
3877   Output Parameter:
3878 . B    - The permuted, sparsified matrix
3879 
3880   Level: advanced
3881 
3882   Note:
3883   The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
3884   restrict the half-bandwidth of the resulting matrix to 5% of the
3885   total matrix size.
3886 
3887 .keywords: matrix, permute, sparsify
3888 
3889 .seealso: MatGetOrdering(), MatPermute()
3890 @*/
3891 PetscErrorCode PETSCMAT_DLLEXPORT MatPermuteSparsify(Mat A, PetscInt band, PetscReal frac, PetscReal tol, IS rowp, IS colp, Mat *B)
3892 {
3893   IS                irowp, icolp;
3894   PetscInt          *rows, *cols;
3895   PetscInt          M, N, locRowStart, locRowEnd;
3896   PetscInt          nz, newNz;
3897   const PetscInt    *cwork;
3898   PetscInt          *cnew;
3899   const PetscScalar *vwork;
3900   PetscScalar       *vnew;
3901   PetscInt          bw, issize;
3902   PetscInt          row, locRow, newRow, col, newCol;
3903   PetscErrorCode    ierr;
3904 
3905   PetscFunctionBegin;
3906   PetscValidHeaderSpecific(A,    MAT_COOKIE,1);
3907   PetscValidHeaderSpecific(rowp, IS_COOKIE,5);
3908   PetscValidHeaderSpecific(colp, IS_COOKIE,6);
3909   PetscValidPointer(B,7);
3910   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
3911   if (A->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
3912   if (!A->ops->permutesparsify) {
3913     ierr = MatGetSize(A, &M, &N);CHKERRQ(ierr);
3914     ierr = MatGetOwnershipRange(A, &locRowStart, &locRowEnd);CHKERRQ(ierr);
3915     ierr = ISGetSize(rowp, &issize);CHKERRQ(ierr);
3916     if (issize != M) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for row permutation, should be %D", issize, M);
3917     ierr = ISGetSize(colp, &issize);CHKERRQ(ierr);
3918     if (issize != N) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for column permutation, should be %D", issize, N);
3919     ierr = ISInvertPermutation(rowp, 0, &irowp);CHKERRQ(ierr);
3920     ierr = ISGetIndices(irowp, &rows);CHKERRQ(ierr);
3921     ierr = ISInvertPermutation(colp, 0, &icolp);CHKERRQ(ierr);
3922     ierr = ISGetIndices(icolp, &cols);CHKERRQ(ierr);
3923     ierr = PetscMalloc(N * sizeof(PetscInt),         &cnew);CHKERRQ(ierr);
3924     ierr = PetscMalloc(N * sizeof(PetscScalar), &vnew);CHKERRQ(ierr);
3925 
3926     /* Setup bandwidth to include */
3927     if (band == PETSC_DECIDE) {
3928       if (frac <= 0.0)
3929         bw = (PetscInt) (M * 0.05);
3930       else
3931         bw = (PetscInt) (M * frac);
3932     } else {
3933       if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
3934       bw = band;
3935     }
3936 
3937     /* Put values into new matrix */
3938     ierr = MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B);CHKERRQ(ierr);
3939     for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) {
3940       ierr = MatGetRow(A, row, &nz, &cwork, &vwork);CHKERRQ(ierr);
3941       newRow   = rows[locRow]+locRowStart;
3942       for(col = 0, newNz = 0; col < nz; col++) {
3943         newCol = cols[cwork[col]];
3944         if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (PetscAbsScalar(vwork[col]) >= tol)) {
3945           cnew[newNz] = newCol;
3946           vnew[newNz] = vwork[col];
3947           newNz++;
3948         }
3949       }
3950       ierr = MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES);CHKERRQ(ierr);
3951       ierr = MatRestoreRow(A, row, &nz, &cwork, &vwork);CHKERRQ(ierr);
3952     }
3953     ierr = PetscFree(cnew);CHKERRQ(ierr);
3954     ierr = PetscFree(vnew);CHKERRQ(ierr);
3955     ierr = MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3956     ierr = MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3957     ierr = ISRestoreIndices(irowp, &rows);CHKERRQ(ierr);
3958     ierr = ISRestoreIndices(icolp, &cols);CHKERRQ(ierr);
3959     ierr = ISDestroy(irowp);CHKERRQ(ierr);
3960     ierr = ISDestroy(icolp);CHKERRQ(ierr);
3961   } else {
3962     ierr = (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B);CHKERRQ(ierr);
3963   }
3964   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
3965   PetscFunctionReturn(0);
3966 }
3967 
3968 #undef __FUNCT__
3969 #define __FUNCT__ "MatEqual"
3970 /*@
3971    MatEqual - Compares two matrices.
3972 
3973    Collective on Mat
3974 
3975    Input Parameters:
3976 +  A - the first matrix
3977 -  B - the second matrix
3978 
3979    Output Parameter:
3980 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
3981 
3982    Level: intermediate
3983 
3984    Concepts: matrices^equality between
3985 @*/
3986 PetscErrorCode PETSCMAT_DLLEXPORT MatEqual(Mat A,Mat B,PetscTruth *flg)
3987 {
3988   PetscErrorCode ierr;
3989 
3990   PetscFunctionBegin;
3991   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
3992   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
3993   PetscValidType(A,1);
3994   PetscValidType(B,2);
3995   MatPreallocated(B);
3996   PetscValidIntPointer(flg,3);
3997   PetscCheckSameComm(A,1,B,2);
3998   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3999   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4000   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);
4001   if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4002   if (!B->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4003   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);
4004   ierr = MatPreallocated(A);CHKERRQ(ierr);
4005 
4006   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
4007   PetscFunctionReturn(0);
4008 }
4009 
4010 #undef __FUNCT__
4011 #define __FUNCT__ "MatDiagonalScale"
4012 /*@
4013    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4014    matrices that are stored as vectors.  Either of the two scaling
4015    matrices can be PETSC_NULL.
4016 
4017    Collective on Mat
4018 
4019    Input Parameters:
4020 +  mat - the matrix to be scaled
4021 .  l - the left scaling vector (or PETSC_NULL)
4022 -  r - the right scaling vector (or PETSC_NULL)
4023 
4024    Notes:
4025    MatDiagonalScale() computes A = LAR, where
4026    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4027 
4028    Level: intermediate
4029 
4030    Concepts: matrices^diagonal scaling
4031    Concepts: diagonal scaling of matrices
4032 
4033 .seealso: MatScale()
4034 @*/
4035 PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalScale(Mat mat,Vec l,Vec r)
4036 {
4037   PetscErrorCode ierr;
4038 
4039   PetscFunctionBegin;
4040   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4041   PetscValidType(mat,1);
4042   if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4043   if (l) {PetscValidHeaderSpecific(l,VEC_COOKIE,2);PetscCheckSameComm(mat,1,l,2);}
4044   if (r) {PetscValidHeaderSpecific(r,VEC_COOKIE,3);PetscCheckSameComm(mat,1,r,3);}
4045   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4046   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4047   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4048 
4049   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4050   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
4051   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4052   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4053   PetscFunctionReturn(0);
4054 }
4055 
4056 #undef __FUNCT__
4057 #define __FUNCT__ "MatScale"
4058 /*@
4059     MatScale - Scales all elements of a matrix by a given number.
4060 
4061     Collective on Mat
4062 
4063     Input Parameters:
4064 +   mat - the matrix to be scaled
4065 -   a  - the scaling value
4066 
4067     Output Parameter:
4068 .   mat - the scaled matrix
4069 
4070     Level: intermediate
4071 
4072     Concepts: matrices^scaling all entries
4073 
4074 .seealso: MatDiagonalScale()
4075 @*/
4076 PetscErrorCode PETSCMAT_DLLEXPORT MatScale(Mat mat,PetscScalar a)
4077 {
4078   PetscErrorCode ierr;
4079 
4080   PetscFunctionBegin;
4081   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4082   PetscValidType(mat,1);
4083   if (!mat->ops->scale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4084   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4085   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4086   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4087 
4088   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4089   ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
4090   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4091   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4092   PetscFunctionReturn(0);
4093 }
4094 
4095 #undef __FUNCT__
4096 #define __FUNCT__ "MatNorm"
4097 /*@
4098    MatNorm - Calculates various norms of a matrix.
4099 
4100    Collective on Mat
4101 
4102    Input Parameters:
4103 +  mat - the matrix
4104 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
4105 
4106    Output Parameters:
4107 .  nrm - the resulting norm
4108 
4109    Level: intermediate
4110 
4111    Concepts: matrices^norm
4112    Concepts: norm^of matrix
4113 @*/
4114 PetscErrorCode PETSCMAT_DLLEXPORT MatNorm(Mat mat,NormType type,PetscReal *nrm)
4115 {
4116   PetscErrorCode ierr;
4117 
4118   PetscFunctionBegin;
4119   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4120   PetscValidType(mat,1);
4121   PetscValidScalarPointer(nrm,3);
4122 
4123   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4124   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4125   if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4126   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4127 
4128   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
4129   PetscFunctionReturn(0);
4130 }
4131 
4132 /*
4133      This variable is used to prevent counting of MatAssemblyBegin() that
4134    are called from within a MatAssemblyEnd().
4135 */
4136 static PetscInt MatAssemblyEnd_InUse = 0;
4137 #undef __FUNCT__
4138 #define __FUNCT__ "MatAssemblyBegin"
4139 /*@
4140    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4141    be called after completing all calls to MatSetValues().
4142 
4143    Collective on Mat
4144 
4145    Input Parameters:
4146 +  mat - the matrix
4147 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4148 
4149    Notes:
4150    MatSetValues() generally caches the values.  The matrix is ready to
4151    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4152    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4153    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4154    using the matrix.
4155 
4156    Level: beginner
4157 
4158    Concepts: matrices^assembling
4159 
4160 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4161 @*/
4162 PetscErrorCode PETSCMAT_DLLEXPORT MatAssemblyBegin(Mat mat,MatAssemblyType type)
4163 {
4164   PetscErrorCode ierr;
4165 
4166   PetscFunctionBegin;
4167   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4168   PetscValidType(mat,1);
4169   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4170   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4171   if (mat->assembled) {
4172     mat->was_assembled = PETSC_TRUE;
4173     mat->assembled     = PETSC_FALSE;
4174   }
4175   if (!MatAssemblyEnd_InUse) {
4176     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
4177     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
4178     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
4179   } else {
4180     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
4181   }
4182   PetscFunctionReturn(0);
4183 }
4184 
4185 #undef __FUNCT__
4186 #define __FUNCT__ "MatAssembed"
4187 /*@
4188    MatAssembled - Indicates if a matrix has been assembled and is ready for
4189      use; for example, in matrix-vector product.
4190 
4191    Collective on Mat
4192 
4193    Input Parameter:
4194 .  mat - the matrix
4195 
4196    Output Parameter:
4197 .  assembled - PETSC_TRUE or PETSC_FALSE
4198 
4199    Level: advanced
4200 
4201    Concepts: matrices^assembled?
4202 
4203 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4204 @*/
4205 PetscErrorCode PETSCMAT_DLLEXPORT MatAssembled(Mat mat,PetscTruth *assembled)
4206 {
4207   PetscFunctionBegin;
4208   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4209   PetscValidType(mat,1);
4210   PetscValidPointer(assembled,2);
4211   *assembled = mat->assembled;
4212   PetscFunctionReturn(0);
4213 }
4214 
4215 #undef __FUNCT__
4216 #define __FUNCT__ "MatView_Private"
4217 /*
4218     Processes command line options to determine if/how a matrix
4219   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4220 */
4221 PetscErrorCode MatView_Private(Mat mat)
4222 {
4223   PetscErrorCode    ierr;
4224   PetscTruth        flg1,flg2,flg3,flg4,flg6,flg7,flg8;
4225   static PetscTruth incall = PETSC_FALSE;
4226 #if defined(PETSC_USE_SOCKET_VIEWER)
4227   PetscTruth        flg5;
4228 #endif
4229 
4230   PetscFunctionBegin;
4231   if (incall) PetscFunctionReturn(0);
4232   incall = PETSC_TRUE;
4233   ierr = PetscOptionsBegin(((PetscObject)mat)->comm,((PetscObject)mat)->prefix,"Matrix Options","Mat");CHKERRQ(ierr);
4234     ierr = PetscOptionsName("-mat_view_info","Information on matrix size","MatView",&flg1);CHKERRQ(ierr);
4235     ierr = PetscOptionsName("-mat_view_info_detailed","Nonzeros in the matrix","MatView",&flg2);CHKERRQ(ierr);
4236     ierr = PetscOptionsName("-mat_view","Print matrix to stdout","MatView",&flg3);CHKERRQ(ierr);
4237     ierr = PetscOptionsName("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",&flg4);CHKERRQ(ierr);
4238 #if defined(PETSC_USE_SOCKET_VIEWER)
4239     ierr = PetscOptionsName("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",&flg5);CHKERRQ(ierr);
4240 #endif
4241     ierr = PetscOptionsName("-mat_view_binary","Save matrix to file in binary format","MatView",&flg6);CHKERRQ(ierr);
4242     ierr = PetscOptionsName("-mat_view_draw","Draw the matrix nonzero structure","MatView",&flg7);CHKERRQ(ierr);
4243   ierr = PetscOptionsEnd();CHKERRQ(ierr);
4244 
4245   if (flg1) {
4246     PetscViewer viewer;
4247 
4248     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4249     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
4250     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4251     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4252   }
4253   if (flg2) {
4254     PetscViewer viewer;
4255 
4256     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4257     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
4258     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4259     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4260   }
4261   if (flg3) {
4262     PetscViewer viewer;
4263 
4264     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4265     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4266   }
4267   if (flg4) {
4268     PetscViewer viewer;
4269 
4270     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4271     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr);
4272     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4273     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4274   }
4275 #if defined(PETSC_USE_SOCKET_VIEWER)
4276   if (flg5) {
4277     ierr = MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4278     ierr = PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4279   }
4280 #endif
4281   if (flg6) {
4282     ierr = MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4283     ierr = PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4284   }
4285   if (flg7) {
4286     ierr = PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8);CHKERRQ(ierr);
4287     if (flg8) {
4288       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
4289     }
4290     ierr = MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4291     ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4292     if (flg8) {
4293       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4294     }
4295   }
4296   incall = PETSC_FALSE;
4297   PetscFunctionReturn(0);
4298 }
4299 
4300 #undef __FUNCT__
4301 #define __FUNCT__ "MatAssemblyEnd"
4302 /*@
4303    MatAssemblyEnd - Completes assembling the matrix.  This routine should
4304    be called after MatAssemblyBegin().
4305 
4306    Collective on Mat
4307 
4308    Input Parameters:
4309 +  mat - the matrix
4310 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4311 
4312    Options Database Keys:
4313 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4314 .  -mat_view_info_detailed - Prints more detailed info
4315 .  -mat_view - Prints matrix in ASCII format
4316 .  -mat_view_matlab - Prints matrix in Matlab format
4317 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4318 .  -display <name> - Sets display name (default is host)
4319 .  -draw_pause <sec> - Sets number of seconds to pause after display
4320 .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
4321 .  -viewer_socket_machine <machine>
4322 .  -viewer_socket_port <port>
4323 .  -mat_view_binary - save matrix to file in binary format
4324 -  -viewer_binary_filename <name>
4325 
4326    Notes:
4327    MatSetValues() generally caches the values.  The matrix is ready to
4328    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4329    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4330    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4331    using the matrix.
4332 
4333    Level: beginner
4334 
4335 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4336 @*/
4337 PetscErrorCode PETSCMAT_DLLEXPORT MatAssemblyEnd(Mat mat,MatAssemblyType type)
4338 {
4339   PetscErrorCode  ierr;
4340   static PetscInt inassm = 0;
4341   PetscTruth      flg;
4342 
4343   PetscFunctionBegin;
4344   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4345   PetscValidType(mat,1);
4346 
4347   inassm++;
4348   MatAssemblyEnd_InUse++;
4349   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4350     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
4351     if (mat->ops->assemblyend) {
4352       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
4353     }
4354     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
4355   } else {
4356     if (mat->ops->assemblyend) {
4357       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
4358     }
4359   }
4360 
4361   /* Flush assembly is not a true assembly */
4362   if (type != MAT_FLUSH_ASSEMBLY) {
4363     mat->assembled  = PETSC_TRUE; mat->num_ass++;
4364   }
4365   mat->insertmode = NOT_SET_VALUES;
4366   MatAssemblyEnd_InUse--;
4367   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4368   if (!mat->symmetric_eternal) {
4369     mat->symmetric_set              = PETSC_FALSE;
4370     mat->hermitian_set              = PETSC_FALSE;
4371     mat->structurally_symmetric_set = PETSC_FALSE;
4372   }
4373   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4374     ierr = MatView_Private(mat);CHKERRQ(ierr);
4375     ierr = PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg);CHKERRQ(ierr);
4376     if (flg) {
4377       PetscReal tol = 0.0;
4378       ierr = PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);CHKERRQ(ierr);
4379       ierr = MatIsSymmetric(mat,tol,&flg);CHKERRQ(ierr);
4380       if (flg) {
4381         ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
4382       } else {
4383         ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
4384       }
4385     }
4386   }
4387   inassm--;
4388   PetscFunctionReturn(0);
4389 }
4390 
4391 
4392 #undef __FUNCT__
4393 #define __FUNCT__ "MatCompress"
4394 /*@
4395    MatCompress - Tries to store the matrix in as little space as
4396    possible.  May fail if memory is already fully used, since it
4397    tries to allocate new space.
4398 
4399    Collective on Mat
4400 
4401    Input Parameters:
4402 .  mat - the matrix
4403 
4404    Level: advanced
4405 
4406 @*/
4407 PetscErrorCode PETSCMAT_DLLEXPORT MatCompress(Mat mat)
4408 {
4409   PetscErrorCode ierr;
4410 
4411   PetscFunctionBegin;
4412   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4413   PetscValidType(mat,1);
4414   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4415   if (mat->ops->compress) {ierr = (*mat->ops->compress)(mat);CHKERRQ(ierr);}
4416   PetscFunctionReturn(0);
4417 }
4418 
4419 #undef __FUNCT__
4420 #define __FUNCT__ "MatSetOption"
4421 /*@
4422    MatSetOption - Sets a parameter option for a matrix. Some options
4423    may be specific to certain storage formats.  Some options
4424    determine how values will be inserted (or added). Sorted,
4425    row-oriented input will generally assemble the fastest. The default
4426    is row-oriented, nonsorted input.
4427 
4428    Collective on Mat
4429 
4430    Input Parameters:
4431 +  mat - the matrix
4432 .  option - the option, one of those listed below (and possibly others),
4433 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
4434 
4435   Options Describing Matrix Structure:
4436 +    MAT_SYMMETRIC - symmetric in terms of both structure and value
4437 .    MAT_HERMITIAN - transpose is the complex conjugation
4438 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
4439 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
4440                             you set to be kept with all future use of the matrix
4441                             including after MatAssemblyBegin/End() which could
4442                             potentially change the symmetry structure, i.e. you
4443                             KNOW the matrix will ALWAYS have the property you set.
4444 
4445 
4446    Options For Use with MatSetValues():
4447    Insert a logically dense subblock, which can be
4448 .    MAT_ROW_ORIENTED - row-oriented (default)
4449 
4450    Note these options reflect the data you pass in with MatSetValues(); it has
4451    nothing to do with how the data is stored internally in the matrix
4452    data structure.
4453 
4454    When (re)assembling a matrix, we can restrict the input for
4455    efficiency/debugging purposes.  These options include
4456 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
4457         allowed if they generate a new nonzero
4458 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
4459 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
4460 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
4461 -    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
4462 
4463    Notes:
4464    Some options are relevant only for particular matrix types and
4465    are thus ignored by others.  Other options are not supported by
4466    certain matrix types and will generate an error message if set.
4467 
4468    If using a Fortran 77 module to compute a matrix, one may need to
4469    use the column-oriented option (or convert to the row-oriented
4470    format).
4471 
4472    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
4473    that would generate a new entry in the nonzero structure is instead
4474    ignored.  Thus, if memory has not alredy been allocated for this particular
4475    data, then the insertion is ignored. For dense matrices, in which
4476    the entire array is allocated, no entries are ever ignored.
4477    Set after the first MatAssemblyEnd()
4478 
4479    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
4480    that would generate a new entry in the nonzero structure instead produces
4481    an error. (Currently supported for AIJ and BAIJ formats only.)
4482    This is a useful flag when using SAME_NONZERO_PATTERN in calling
4483    KSPSetOperators() to ensure that the nonzero pattern truely does
4484    remain unchanged. Set after the first MatAssemblyEnd()
4485 
4486    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
4487    that would generate a new entry that has not been preallocated will
4488    instead produce an error. (Currently supported for AIJ and BAIJ formats
4489    only.) This is a useful flag when debugging matrix memory preallocation.
4490 
4491    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
4492    other processors should be dropped, rather than stashed.
4493    This is useful if you know that the "owning" processor is also
4494    always generating the correct matrix entries, so that PETSc need
4495    not transfer duplicate entries generated on another processor.
4496 
4497    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
4498    searches during matrix assembly. When this flag is set, the hash table
4499    is created during the first Matrix Assembly. This hash table is
4500    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
4501    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
4502    should be used with MAT_USE_HASH_TABLE flag. This option is currently
4503    supported by MATMPIBAIJ format only.
4504 
4505    MAT_KEEP_ZEROED_ROWS indicates when MatZeroRows() is called the zeroed entries
4506    are kept in the nonzero structure
4507 
4508    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
4509    a zero location in the matrix
4510 
4511    MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
4512    ROWBS matrix types
4513 
4514    Level: intermediate
4515 
4516    Concepts: matrices^setting options
4517 
4518 @*/
4519 PetscErrorCode PETSCMAT_DLLEXPORT MatSetOption(Mat mat,MatOption op,PetscTruth flg)
4520 {
4521   PetscErrorCode ierr;
4522 
4523   PetscFunctionBegin;
4524   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4525   PetscValidType(mat,1);
4526   if (((int) op) < 0 || ((int) op) > 16) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
4527   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4528   switch (op) {
4529   case MAT_SYMMETRIC:
4530     mat->symmetric                  = flg;
4531     if (flg) mat->structurally_symmetric     = PETSC_TRUE;
4532     mat->symmetric_set              = PETSC_TRUE;
4533     mat->structurally_symmetric_set = flg;
4534     break;
4535   case MAT_HERMITIAN:
4536     mat->hermitian                  = flg;
4537     if (flg) mat->structurally_symmetric     = PETSC_TRUE;
4538     mat->hermitian_set              = PETSC_TRUE;
4539     mat->structurally_symmetric_set = flg;
4540     break;
4541   case MAT_STRUCTURALLY_SYMMETRIC:
4542     mat->structurally_symmetric     = flg;
4543     mat->structurally_symmetric_set = PETSC_TRUE;
4544     break;
4545   case MAT_SYMMETRY_ETERNAL:
4546     mat->symmetric_eternal          = flg;
4547     break;
4548   default:
4549     break;
4550   }
4551   if (mat->ops->setoption) {
4552     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
4553   }
4554   PetscFunctionReturn(0);
4555 }
4556 
4557 #undef __FUNCT__
4558 #define __FUNCT__ "MatZeroEntries"
4559 /*@
4560    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
4561    this routine retains the old nonzero structure.
4562 
4563    Collective on Mat
4564 
4565    Input Parameters:
4566 .  mat - the matrix
4567 
4568    Level: intermediate
4569 
4570    Concepts: matrices^zeroing
4571 
4572 .seealso: MatZeroRows()
4573 @*/
4574 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroEntries(Mat mat)
4575 {
4576   PetscErrorCode ierr;
4577 
4578   PetscFunctionBegin;
4579   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4580   PetscValidType(mat,1);
4581   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4582   if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
4583   if (!mat->ops->zeroentries) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4584   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4585 
4586   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
4587   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
4588   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
4589   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4590   PetscFunctionReturn(0);
4591 }
4592 
4593 #undef __FUNCT__
4594 #define __FUNCT__ "MatZeroRows"
4595 /*@C
4596    MatZeroRows - Zeros all entries (except possibly the main diagonal)
4597    of a set of rows of a matrix.
4598 
4599    Collective on Mat
4600 
4601    Input Parameters:
4602 +  mat - the matrix
4603 .  numRows - the number of rows to remove
4604 .  rows - the global row indices
4605 -  diag - value put in all diagonals of eliminated rows
4606 
4607    Notes:
4608    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4609    but does not release memory.  For the dense and block diagonal
4610    formats this does not alter the nonzero structure.
4611 
4612    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4613    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4614    merely zeroed.
4615 
4616    The user can set a value in the diagonal entry (or for the AIJ and
4617    row formats can optionally remove the main diagonal entry from the
4618    nonzero structure as well, by passing 0.0 as the final argument).
4619 
4620    For the parallel case, all processes that share the matrix (i.e.,
4621    those in the communicator used for matrix creation) MUST call this
4622    routine, regardless of whether any rows being zeroed are owned by
4623    them.
4624 
4625    Each processor should list the rows that IT wants zeroed
4626 
4627    Level: intermediate
4628 
4629    Concepts: matrices^zeroing rows
4630 
4631 .seealso: MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4632 @*/
4633 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4634 {
4635   PetscErrorCode ierr;
4636 
4637   PetscFunctionBegin;
4638   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4639   PetscValidType(mat,1);
4640   if (numRows) PetscValidIntPointer(rows,3);
4641   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4642   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4643   if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4644   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4645 
4646   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag);CHKERRQ(ierr);
4647   ierr = MatView_Private(mat);CHKERRQ(ierr);
4648   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4649   PetscFunctionReturn(0);
4650 }
4651 
4652 #undef __FUNCT__
4653 #define __FUNCT__ "MatZeroRowsIS"
4654 /*@C
4655    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
4656    of a set of rows of a matrix.
4657 
4658    Collective on Mat
4659 
4660    Input Parameters:
4661 +  mat - the matrix
4662 .  is - index set of rows to remove
4663 -  diag - value put in all diagonals of eliminated rows
4664 
4665    Notes:
4666    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4667    but does not release memory.  For the dense and block diagonal
4668    formats this does not alter the nonzero structure.
4669 
4670    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4671    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4672    merely zeroed.
4673 
4674    The user can set a value in the diagonal entry (or for the AIJ and
4675    row formats can optionally remove the main diagonal entry from the
4676    nonzero structure as well, by passing 0.0 as the final argument).
4677 
4678    For the parallel case, all processes that share the matrix (i.e.,
4679    those in the communicator used for matrix creation) MUST call this
4680    routine, regardless of whether any rows being zeroed are owned by
4681    them.
4682 
4683    Each processor should list the rows that IT wants zeroed
4684 
4685    Level: intermediate
4686 
4687    Concepts: matrices^zeroing rows
4688 
4689 .seealso: MatZeroRows(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4690 @*/
4691 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsIS(Mat mat,IS is,PetscScalar diag)
4692 {
4693   PetscInt       numRows;
4694   PetscInt       *rows;
4695   PetscErrorCode ierr;
4696 
4697   PetscFunctionBegin;
4698   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4699   PetscValidType(mat,1);
4700   PetscValidHeaderSpecific(is,IS_COOKIE,2);
4701   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
4702   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
4703   ierr = MatZeroRows(mat,numRows,rows,diag);CHKERRQ(ierr);
4704   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
4705   PetscFunctionReturn(0);
4706 }
4707 
4708 #undef __FUNCT__
4709 #define __FUNCT__ "MatZeroRowsLocal"
4710 /*@C
4711    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
4712    of a set of rows of a matrix; using local numbering of rows.
4713 
4714    Collective on Mat
4715 
4716    Input Parameters:
4717 +  mat - the matrix
4718 .  numRows - the number of rows to remove
4719 .  rows - the global row indices
4720 -  diag - value put in all diagonals of eliminated rows
4721 
4722    Notes:
4723    Before calling MatZeroRowsLocal(), the user must first set the
4724    local-to-global mapping by calling MatSetLocalToGlobalMapping().
4725 
4726    For the AIJ matrix formats this removes the old nonzero structure,
4727    but does not release memory.  For the dense and block diagonal
4728    formats this does not alter the nonzero structure.
4729 
4730    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4731    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4732    merely zeroed.
4733 
4734    The user can set a value in the diagonal entry (or for the AIJ and
4735    row formats can optionally remove the main diagonal entry from the
4736    nonzero structure as well, by passing 0.0 as the final argument).
4737 
4738    Level: intermediate
4739 
4740    Concepts: matrices^zeroing
4741 
4742 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
4743 @*/
4744 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4745 {
4746   PetscErrorCode ierr;
4747 
4748   PetscFunctionBegin;
4749   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4750   PetscValidType(mat,1);
4751   if (numRows) PetscValidIntPointer(rows,3);
4752   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4753   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4754   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4755 
4756   if (mat->ops->zerorowslocal) {
4757     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag);CHKERRQ(ierr);
4758   } else {
4759     IS is, newis;
4760     PetscInt *newRows;
4761 
4762     if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
4763     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,&is);CHKERRQ(ierr);
4764     ierr = ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);CHKERRQ(ierr);
4765     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
4766     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag);CHKERRQ(ierr);
4767     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
4768     ierr = ISDestroy(newis);CHKERRQ(ierr);
4769     ierr = ISDestroy(is);CHKERRQ(ierr);
4770   }
4771   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4772   PetscFunctionReturn(0);
4773 }
4774 
4775 #undef __FUNCT__
4776 #define __FUNCT__ "MatZeroRowsLocalIS"
4777 /*@C
4778    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
4779    of a set of rows of a matrix; using local numbering of rows.
4780 
4781    Collective on Mat
4782 
4783    Input Parameters:
4784 +  mat - the matrix
4785 .  is - index set of rows to remove
4786 -  diag - value put in all diagonals of eliminated rows
4787 
4788    Notes:
4789    Before calling MatZeroRowsLocalIS(), the user must first set the
4790    local-to-global mapping by calling MatSetLocalToGlobalMapping().
4791 
4792    For the AIJ matrix formats this removes the old nonzero structure,
4793    but does not release memory.  For the dense and block diagonal
4794    formats this does not alter the nonzero structure.
4795 
4796    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4797    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4798    merely zeroed.
4799 
4800    The user can set a value in the diagonal entry (or for the AIJ and
4801    row formats can optionally remove the main diagonal entry from the
4802    nonzero structure as well, by passing 0.0 as the final argument).
4803 
4804    Level: intermediate
4805 
4806    Concepts: matrices^zeroing
4807 
4808 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
4809 @*/
4810 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag)
4811 {
4812   PetscErrorCode ierr;
4813   PetscInt       numRows;
4814   PetscInt       *rows;
4815 
4816   PetscFunctionBegin;
4817   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4818   PetscValidType(mat,1);
4819   PetscValidHeaderSpecific(is,IS_COOKIE,2);
4820   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4821   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4822   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4823 
4824   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
4825   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
4826   ierr = MatZeroRowsLocal(mat,numRows,rows,diag);CHKERRQ(ierr);
4827   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
4828   PetscFunctionReturn(0);
4829 }
4830 
4831 #undef __FUNCT__
4832 #define __FUNCT__ "MatGetSize"
4833 /*@
4834    MatGetSize - Returns the numbers of rows and columns in a matrix.
4835 
4836    Not Collective
4837 
4838    Input Parameter:
4839 .  mat - the matrix
4840 
4841    Output Parameters:
4842 +  m - the number of global rows
4843 -  n - the number of global columns
4844 
4845    Note: both output parameters can be PETSC_NULL on input.
4846 
4847    Level: beginner
4848 
4849    Concepts: matrices^size
4850 
4851 .seealso: MatGetLocalSize()
4852 @*/
4853 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
4854 {
4855   PetscFunctionBegin;
4856   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4857   if (m) *m = mat->rmap.N;
4858   if (n) *n = mat->cmap.N;
4859   PetscFunctionReturn(0);
4860 }
4861 
4862 #undef __FUNCT__
4863 #define __FUNCT__ "MatGetLocalSize"
4864 /*@
4865    MatGetLocalSize - Returns the number of rows and columns in a matrix
4866    stored locally.  This information may be implementation dependent, so
4867    use with care.
4868 
4869    Not Collective
4870 
4871    Input Parameters:
4872 .  mat - the matrix
4873 
4874    Output Parameters:
4875 +  m - the number of local rows
4876 -  n - the number of local columns
4877 
4878    Note: both output parameters can be PETSC_NULL on input.
4879 
4880    Level: beginner
4881 
4882    Concepts: matrices^local size
4883 
4884 .seealso: MatGetSize()
4885 @*/
4886 PetscErrorCode PETSCMAT_DLLEXPORT MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
4887 {
4888   PetscFunctionBegin;
4889   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4890   if (m) PetscValidIntPointer(m,2);
4891   if (n) PetscValidIntPointer(n,3);
4892   if (m) *m = mat->rmap.n;
4893   if (n) *n = mat->cmap.n;
4894   PetscFunctionReturn(0);
4895 }
4896 
4897 #undef __FUNCT__
4898 #define __FUNCT__ "MatGetOwnershipRangeColumn"
4899 /*@
4900    MatGetOwnershipRangeColumn - Returns the range of matrix columns owned by
4901    this processor.
4902 
4903    Not Collective
4904 
4905    Input Parameters:
4906 .  mat - the matrix
4907 
4908    Output Parameters:
4909 +  m - the global index of the first local column
4910 -  n - one more than the global index of the last local column
4911 
4912    Notes: both output parameters can be PETSC_NULL on input.
4913 
4914    Level: developer
4915 
4916    Concepts: matrices^column ownership
4917 @*/
4918 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
4919 {
4920   PetscErrorCode ierr;
4921 
4922   PetscFunctionBegin;
4923   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4924   PetscValidType(mat,1);
4925   if (m) PetscValidIntPointer(m,2);
4926   if (n) PetscValidIntPointer(n,3);
4927   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4928   if (m) *m = mat->cmap.rstart;
4929   if (n) *n = mat->cmap.rend;
4930   PetscFunctionReturn(0);
4931 }
4932 
4933 #undef __FUNCT__
4934 #define __FUNCT__ "MatGetOwnershipRange"
4935 /*@
4936    MatGetOwnershipRange - Returns the range of matrix rows owned by
4937    this processor, assuming that the matrix is laid out with the first
4938    n1 rows on the first processor, the next n2 rows on the second, etc.
4939    For certain parallel layouts this range may not be well defined.
4940 
4941    Not Collective
4942 
4943    Input Parameters:
4944 .  mat - the matrix
4945 
4946    Output Parameters:
4947 +  m - the global index of the first local row
4948 -  n - one more than the global index of the last local row
4949 
4950    Note: both output parameters can be PETSC_NULL on input.
4951 
4952    Level: beginner
4953 
4954    Concepts: matrices^row ownership
4955 
4956 .seealso:   MatGetOwnershipRanges()
4957 
4958 @*/
4959 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
4960 {
4961   PetscErrorCode ierr;
4962 
4963   PetscFunctionBegin;
4964   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4965   PetscValidType(mat,1);
4966   if (m) PetscValidIntPointer(m,2);
4967   if (n) PetscValidIntPointer(n,3);
4968   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4969   if (m) *m = mat->rmap.rstart;
4970   if (n) *n = mat->rmap.rend;
4971   PetscFunctionReturn(0);
4972 }
4973 
4974 #undef __FUNCT__
4975 #define __FUNCT__ "MatGetOwnershipRanges"
4976 /*@C
4977    MatGetOwnershipRanges - Returns the range of matrix rows owned by
4978    each process
4979 
4980    Not Collective
4981 
4982    Input Parameters:
4983 .  mat - the matrix
4984 
4985    Output Parameters:
4986 .  ranges - start of each processors portion plus one more then the total length at the end
4987 
4988    Level: beginner
4989 
4990    Concepts: matrices^row ownership
4991 
4992 .seealso:   MatGetOwnershipRange()
4993 
4994 @*/
4995 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
4996 {
4997   PetscErrorCode ierr;
4998 
4999   PetscFunctionBegin;
5000   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5001   PetscValidType(mat,1);
5002   ierr = PetscMapGetGlobalRange(&mat->rmap,ranges);CHKERRQ(ierr);
5003   PetscFunctionReturn(0);
5004 }
5005 
5006 #undef __FUNCT__
5007 #define __FUNCT__ "MatILUFactorSymbolic"
5008 /*@
5009    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
5010    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
5011    to complete the factorization.
5012 
5013    Collective on Mat
5014 
5015    Input Parameters:
5016 +  mat - the matrix
5017 .  row - row permutation
5018 .  column - column permutation
5019 -  info - structure containing
5020 $      levels - number of levels of fill.
5021 $      expected fill - as ratio of original fill.
5022 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
5023                 missing diagonal entries)
5024 
5025    Output Parameters:
5026 .  fact - new matrix that has been symbolically factored
5027 
5028    Notes:
5029    See the users manual for additional information about
5030    choosing the fill factor for better efficiency.
5031 
5032    Most users should employ the simplified KSP interface for linear solvers
5033    instead of working directly with matrix algebra routines such as this.
5034    See, e.g., KSPCreate().
5035 
5036    Level: developer
5037 
5038   Concepts: matrices^symbolic LU factorization
5039   Concepts: matrices^factorization
5040   Concepts: LU^symbolic factorization
5041 
5042 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5043           MatGetOrdering(), MatFactorInfo
5044 
5045 @*/
5046 PetscErrorCode PETSCMAT_DLLEXPORT MatILUFactorSymbolic(Mat mat,IS row,IS col,MatFactorInfo *info,Mat *fact)
5047 {
5048   PetscErrorCode ierr;
5049 
5050   PetscFunctionBegin;
5051   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5052   PetscValidType(mat,1);
5053   PetscValidHeaderSpecific(row,IS_COOKIE,2);
5054   PetscValidHeaderSpecific(col,IS_COOKIE,3);
5055   PetscValidPointer(info,4);
5056   PetscValidPointer(fact,5);
5057   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
5058   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5059   if (!mat->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",((PetscObject)mat)->type_name);
5060   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5061   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5062   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5063 
5064   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
5065   ierr = (*mat->ops->ilufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
5066   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
5067   PetscFunctionReturn(0);
5068 }
5069 
5070 #undef __FUNCT__
5071 #define __FUNCT__ "MatICCFactorSymbolic"
5072 /*@
5073    MatICCFactorSymbolic - Performs symbolic incomplete
5074    Cholesky factorization for a symmetric matrix.  Use
5075    MatCholeskyFactorNumeric() to complete the factorization.
5076 
5077    Collective on Mat
5078 
5079    Input Parameters:
5080 +  mat - the matrix
5081 .  perm - row and column permutation
5082 -  info - structure containing
5083 $      levels - number of levels of fill.
5084 $      expected fill - as ratio of original fill.
5085 
5086    Output Parameter:
5087 .  fact - the factored matrix
5088 
5089    Notes:
5090    Most users should employ the KSP interface for linear solvers
5091    instead of working directly with matrix algebra routines such as this.
5092    See, e.g., KSPCreate().
5093 
5094    Level: developer
5095 
5096   Concepts: matrices^symbolic incomplete Cholesky factorization
5097   Concepts: matrices^factorization
5098   Concepts: Cholsky^symbolic factorization
5099 
5100 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
5101 @*/
5102 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactorSymbolic(Mat mat,IS perm,MatFactorInfo *info,Mat *fact)
5103 {
5104   PetscErrorCode ierr;
5105 
5106   PetscFunctionBegin;
5107   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5108   PetscValidType(mat,1);
5109   PetscValidHeaderSpecific(perm,IS_COOKIE,2);
5110   PetscValidPointer(info,3);
5111   PetscValidPointer(fact,4);
5112   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5113   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
5114   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5115   if (!mat->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",((PetscObject)mat)->type_name);
5116   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5117   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5118 
5119   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
5120   ierr = (*mat->ops->iccfactorsymbolic)(mat,perm,info,fact);CHKERRQ(ierr);
5121   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
5122   PetscFunctionReturn(0);
5123 }
5124 
5125 #undef __FUNCT__
5126 #define __FUNCT__ "MatGetArray"
5127 /*@C
5128    MatGetArray - Returns a pointer to the element values in the matrix.
5129    The result of this routine is dependent on the underlying matrix data
5130    structure, and may not even work for certain matrix types.  You MUST
5131    call MatRestoreArray() when you no longer need to access the array.
5132 
5133    Not Collective
5134 
5135    Input Parameter:
5136 .  mat - the matrix
5137 
5138    Output Parameter:
5139 .  v - the location of the values
5140 
5141 
5142    Fortran Note:
5143    This routine is used differently from Fortran, e.g.,
5144 .vb
5145         Mat         mat
5146         PetscScalar mat_array(1)
5147         PetscOffset i_mat
5148         PetscErrorCode ierr
5149         call MatGetArray(mat,mat_array,i_mat,ierr)
5150 
5151   C  Access first local entry in matrix; note that array is
5152   C  treated as one dimensional
5153         value = mat_array(i_mat + 1)
5154 
5155         [... other code ...]
5156         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5157 .ve
5158 
5159    See the Fortran chapter of the users manual and
5160    petsc/src/mat/examples/tests for details.
5161 
5162    Level: advanced
5163 
5164    Concepts: matrices^access array
5165 
5166 .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
5167 @*/
5168 PetscErrorCode PETSCMAT_DLLEXPORT MatGetArray(Mat mat,PetscScalar *v[])
5169 {
5170   PetscErrorCode ierr;
5171 
5172   PetscFunctionBegin;
5173   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5174   PetscValidType(mat,1);
5175   PetscValidPointer(v,2);
5176   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5177   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5178   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
5179   CHKMEMQ;
5180   PetscFunctionReturn(0);
5181 }
5182 
5183 #undef __FUNCT__
5184 #define __FUNCT__ "MatRestoreArray"
5185 /*@C
5186    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
5187 
5188    Not Collective
5189 
5190    Input Parameter:
5191 +  mat - the matrix
5192 -  v - the location of the values
5193 
5194    Fortran Note:
5195    This routine is used differently from Fortran, e.g.,
5196 .vb
5197         Mat         mat
5198         PetscScalar mat_array(1)
5199         PetscOffset i_mat
5200         PetscErrorCode ierr
5201         call MatGetArray(mat,mat_array,i_mat,ierr)
5202 
5203   C  Access first local entry in matrix; note that array is
5204   C  treated as one dimensional
5205         value = mat_array(i_mat + 1)
5206 
5207         [... other code ...]
5208         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5209 .ve
5210 
5211    See the Fortran chapter of the users manual and
5212    petsc/src/mat/examples/tests for details
5213 
5214    Level: advanced
5215 
5216 .seealso: MatGetArray(), MatRestoreArrayF90()
5217 @*/
5218 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreArray(Mat mat,PetscScalar *v[])
5219 {
5220   PetscErrorCode ierr;
5221 
5222   PetscFunctionBegin;
5223   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5224   PetscValidType(mat,1);
5225   PetscValidPointer(v,2);
5226 #if defined(PETSC_USE_DEBUG)
5227   CHKMEMQ;
5228 #endif
5229   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5230   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
5231   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5232   PetscFunctionReturn(0);
5233 }
5234 
5235 #undef __FUNCT__
5236 #define __FUNCT__ "MatGetSubMatrices"
5237 /*@C
5238    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
5239    points to an array of valid matrices, they may be reused to store the new
5240    submatrices.
5241 
5242    Collective on Mat
5243 
5244    Input Parameters:
5245 +  mat - the matrix
5246 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
5247 .  irow, icol - index sets of rows and columns to extract
5248 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
5249 
5250    Output Parameter:
5251 .  submat - the array of submatrices
5252 
5253    Notes:
5254    MatGetSubMatrices() can extract ONLY sequential submatrices
5255    (from both sequential and parallel matrices). Use MatGetSubMatrix()
5256    to extract a parallel submatrix.
5257 
5258    When extracting submatrices from a parallel matrix, each processor can
5259    form a different submatrix by setting the rows and columns of its
5260    individual index sets according to the local submatrix desired.
5261 
5262    When finished using the submatrices, the user should destroy
5263    them with MatDestroyMatrices().
5264 
5265    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
5266    original matrix has not changed from that last call to MatGetSubMatrices().
5267 
5268    This routine creates the matrices in submat; you should NOT create them before
5269    calling it. It also allocates the array of matrix pointers submat.
5270 
5271    For BAIJ matrices the index sets must respect the block structure, that is if they
5272    request one row/column in a block, they must request all rows/columns that are in
5273    that block. For example, if the block size is 2 you cannot request just row 0 and
5274    column 0.
5275 
5276    Fortran Note:
5277    The Fortran interface is slightly different from that given below; it
5278    requires one to pass in  as submat a Mat (integer) array of size at least m.
5279 
5280    Level: advanced
5281 
5282    Concepts: matrices^accessing submatrices
5283    Concepts: submatrices
5284 
5285 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal()
5286 @*/
5287 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
5288 {
5289   PetscErrorCode ierr;
5290   PetscInt        i;
5291   PetscTruth      eq;
5292 
5293   PetscFunctionBegin;
5294   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5295   PetscValidType(mat,1);
5296   if (n) {
5297     PetscValidPointer(irow,3);
5298     PetscValidHeaderSpecific(*irow,IS_COOKIE,3);
5299     PetscValidPointer(icol,4);
5300     PetscValidHeaderSpecific(*icol,IS_COOKIE,4);
5301   }
5302   PetscValidPointer(submat,6);
5303   if (n && scall == MAT_REUSE_MATRIX) {
5304     PetscValidPointer(*submat,6);
5305     PetscValidHeaderSpecific(**submat,MAT_COOKIE,6);
5306   }
5307   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5308   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5309   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5310   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5311 
5312   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
5313   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
5314   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
5315   for (i=0; i<n; i++) {
5316     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
5317       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
5318       if (eq) {
5319 	if (mat->symmetric){
5320 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
5321 	} else if (mat->hermitian) {
5322 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
5323 	} else if (mat->structurally_symmetric) {
5324 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
5325 	}
5326       }
5327     }
5328   }
5329   PetscFunctionReturn(0);
5330 }
5331 
5332 #undef __FUNCT__
5333 #define __FUNCT__ "MatDestroyMatrices"
5334 /*@C
5335    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
5336 
5337    Collective on Mat
5338 
5339    Input Parameters:
5340 +  n - the number of local matrices
5341 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
5342                        sequence of MatGetSubMatrices())
5343 
5344    Level: advanced
5345 
5346     Notes: Frees not only the matrices, but also the array that contains the matrices
5347 
5348 .seealso: MatGetSubMatrices()
5349 @*/
5350 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroyMatrices(PetscInt n,Mat *mat[])
5351 {
5352   PetscErrorCode ierr;
5353   PetscInt       i;
5354 
5355   PetscFunctionBegin;
5356   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
5357   PetscValidPointer(mat,2);
5358   for (i=0; i<n; i++) {
5359     ierr = MatDestroy((*mat)[i]);CHKERRQ(ierr);
5360   }
5361   /* memory is allocated even if n = 0 */
5362   ierr = PetscFree(*mat);CHKERRQ(ierr);
5363   PetscFunctionReturn(0);
5364 }
5365 
5366 #undef __FUNCT__
5367 #define __FUNCT__ "MatGetSeqNonzeroStructure"
5368 /*@C
5369    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
5370 
5371    Collective on Mat
5372 
5373    Input Parameters:
5374 .  mat - the matrix
5375 
5376    Output Parameter:
5377 .  matstruct - the sequential matrix with the nonzero structure of mat
5378 
5379   Level: intermediate
5380 
5381 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
5382 @*/
5383 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct[])
5384 {
5385   PetscErrorCode ierr;
5386 
5387   PetscFunctionBegin;
5388   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5389   PetscValidPointer(matstruct,2);
5390 
5391   PetscValidType(mat,1);
5392   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5393   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5394 
5395   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
5396   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
5397   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
5398   PetscFunctionReturn(0);
5399 }
5400 
5401 #undef __FUNCT__
5402 #define __FUNCT__ "MatDestroySeqNonzeroStructure"
5403 /*@C
5404    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
5405 
5406    Collective on Mat
5407 
5408    Input Parameters:
5409 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
5410                        sequence of MatGetSequentialNonzeroStructure())
5411 
5412    Level: advanced
5413 
5414     Notes: Frees not only the matrices, but also the array that contains the matrices
5415 
5416 .seealso: MatGetSeqNonzeroStructure()
5417 @*/
5418 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroySeqNonzeroStructure(Mat *mat[])
5419 {
5420   PetscErrorCode ierr;
5421 
5422   PetscFunctionBegin;
5423   PetscValidPointer(mat,1);
5424   ierr = MatDestroyMatrices(1,mat);CHKERRQ(ierr);
5425   PetscFunctionReturn(0);
5426 }
5427 
5428 #undef __FUNCT__
5429 #define __FUNCT__ "MatIncreaseOverlap"
5430 /*@
5431    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
5432    replaces the index sets by larger ones that represent submatrices with
5433    additional overlap.
5434 
5435    Collective on Mat
5436 
5437    Input Parameters:
5438 +  mat - the matrix
5439 .  n   - the number of index sets
5440 .  is  - the array of index sets (these index sets will changed during the call)
5441 -  ov  - the additional overlap requested
5442 
5443    Level: developer
5444 
5445    Concepts: overlap
5446    Concepts: ASM^computing overlap
5447 
5448 .seealso: MatGetSubMatrices()
5449 @*/
5450 PetscErrorCode PETSCMAT_DLLEXPORT MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
5451 {
5452   PetscErrorCode ierr;
5453 
5454   PetscFunctionBegin;
5455   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5456   PetscValidType(mat,1);
5457   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
5458   if (n) {
5459     PetscValidPointer(is,3);
5460     PetscValidHeaderSpecific(*is,IS_COOKIE,3);
5461   }
5462   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5463   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5464   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5465 
5466   if (!ov) PetscFunctionReturn(0);
5467   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5468   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
5469   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
5470   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
5471   PetscFunctionReturn(0);
5472 }
5473 
5474 #undef __FUNCT__
5475 #define __FUNCT__ "MatGetBlockSize"
5476 /*@
5477    MatGetBlockSize - Returns the matrix block size; useful especially for the
5478    block row and block diagonal formats.
5479 
5480    Not Collective
5481 
5482    Input Parameter:
5483 .  mat - the matrix
5484 
5485    Output Parameter:
5486 .  bs - block size
5487 
5488    Notes:
5489    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
5490 
5491    Level: intermediate
5492 
5493    Concepts: matrices^block size
5494 
5495 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
5496 @*/
5497 PetscErrorCode PETSCMAT_DLLEXPORT MatGetBlockSize(Mat mat,PetscInt *bs)
5498 {
5499   PetscErrorCode ierr;
5500 
5501   PetscFunctionBegin;
5502   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5503   PetscValidType(mat,1);
5504   PetscValidIntPointer(bs,2);
5505   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5506   *bs = mat->rmap.bs;
5507   PetscFunctionReturn(0);
5508 }
5509 
5510 #undef __FUNCT__
5511 #define __FUNCT__ "MatSetBlockSize"
5512 /*@
5513    MatSetBlockSize - Sets the matrix block size; for many matrix types you
5514      cannot use this and MUST set the blocksize when you preallocate the matrix
5515 
5516    Collective on Mat
5517 
5518    Input Parameters:
5519 +  mat - the matrix
5520 -  bs - block size
5521 
5522    Notes:
5523      Only works for shell and AIJ matrices
5524 
5525    Level: intermediate
5526 
5527    Concepts: matrices^block size
5528 
5529 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
5530 @*/
5531 PetscErrorCode PETSCMAT_DLLEXPORT MatSetBlockSize(Mat mat,PetscInt bs)
5532 {
5533   PetscErrorCode ierr;
5534 
5535   PetscFunctionBegin;
5536   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5537   PetscValidType(mat,1);
5538   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5539   if (mat->ops->setblocksize) {
5540     mat->rmap.bs = bs;
5541     ierr = (*mat->ops->setblocksize)(mat,bs);CHKERRQ(ierr);
5542   } else {
5543     SETERRQ1(PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
5544   }
5545   PetscFunctionReturn(0);
5546 }
5547 
5548 #undef __FUNCT__
5549 #define __FUNCT__ "MatGetRowIJ"
5550 /*@C
5551     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
5552 
5553    Collective on Mat
5554 
5555     Input Parameters:
5556 +   mat - the matrix
5557 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
5558 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5559                 symmetrized
5560 -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5561                  blockcompressed matrix is desired or not [inode, baij have blockcompressed
5562                  nonzero structure which is different than the full nonzero structure]
5563 
5564     Output Parameters:
5565 +   n - number of rows in the (possibly compressed) matrix
5566 .   ia - the row pointers [of length n+1]
5567 .   ja - the column indices
5568 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
5569            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
5570 
5571     Level: developer
5572 
5573     Notes: You CANNOT change any of the ia[] or ja[] values.
5574 
5575            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
5576 
5577     Fortran Node
5578 
5579            In Fortran use
5580 $           PetscInt ia(1), ja(1)
5581 $           PetscOffset iia, jja
5582 $      call MatGetRowIJ(mat,shift,symmetric,blockcompressed,n,ia,iia,ja,jja,done,ierr)
5583 
5584        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
5585 
5586 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
5587 @*/
5588 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5589 {
5590   PetscErrorCode ierr;
5591 
5592   PetscFunctionBegin;
5593   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5594   PetscValidType(mat,1);
5595   PetscValidIntPointer(n,4);
5596   if (ia) PetscValidIntPointer(ia,5);
5597   if (ja) PetscValidIntPointer(ja,6);
5598   PetscValidIntPointer(done,7);
5599   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5600   if (!mat->ops->getrowij) *done = PETSC_FALSE;
5601   else {
5602     *done = PETSC_TRUE;
5603     ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
5604     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);CHKERRQ(ierr);
5605     ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
5606   }
5607   PetscFunctionReturn(0);
5608 }
5609 
5610 #undef __FUNCT__
5611 #define __FUNCT__ "MatGetColumnIJ"
5612 /*@C
5613     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
5614 
5615     Collective on Mat
5616 
5617     Input Parameters:
5618 +   mat - the matrix
5619 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5620 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5621                 symmetrized
5622 -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5623                  blockcompressed matrix is desired or not [inode, baij have blockcompressed
5624                  nonzero structure which is different than the full nonzero structure]
5625 
5626     Output Parameters:
5627 +   n - number of columns in the (possibly compressed) matrix
5628 .   ia - the column pointers
5629 .   ja - the row indices
5630 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
5631 
5632     Level: developer
5633 
5634 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5635 @*/
5636 PetscErrorCode PETSCMAT_DLLEXPORT MatGetColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5637 {
5638   PetscErrorCode ierr;
5639 
5640   PetscFunctionBegin;
5641   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5642   PetscValidType(mat,1);
5643   PetscValidIntPointer(n,4);
5644   if (ia) PetscValidIntPointer(ia,5);
5645   if (ja) PetscValidIntPointer(ja,6);
5646   PetscValidIntPointer(done,7);
5647   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5648   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
5649   else {
5650     *done = PETSC_TRUE;
5651     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);CHKERRQ(ierr);
5652   }
5653   PetscFunctionReturn(0);
5654 }
5655 
5656 #undef __FUNCT__
5657 #define __FUNCT__ "MatRestoreRowIJ"
5658 /*@C
5659     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
5660     MatGetRowIJ().
5661 
5662     Collective on Mat
5663 
5664     Input Parameters:
5665 +   mat - the matrix
5666 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5667 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5668                 symmetrized
5669 -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5670                  blockcompressed matrix is desired or not [inode, baij have blockcompressed
5671                  nonzero structure which is different than the full nonzero structure]
5672 
5673     Output Parameters:
5674 +   n - size of (possibly compressed) matrix
5675 .   ia - the row pointers
5676 .   ja - the column indices
5677 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5678 
5679     Level: developer
5680 
5681 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5682 @*/
5683 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5684 {
5685   PetscErrorCode ierr;
5686 
5687   PetscFunctionBegin;
5688   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5689   PetscValidType(mat,1);
5690   if (ia) PetscValidIntPointer(ia,5);
5691   if (ja) PetscValidIntPointer(ja,6);
5692   PetscValidIntPointer(done,7);
5693   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5694 
5695   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
5696   else {
5697     *done = PETSC_TRUE;
5698     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);CHKERRQ(ierr);
5699   }
5700   PetscFunctionReturn(0);
5701 }
5702 
5703 #undef __FUNCT__
5704 #define __FUNCT__ "MatRestoreColumnIJ"
5705 /*@C
5706     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
5707     MatGetColumnIJ().
5708 
5709     Collective on Mat
5710 
5711     Input Parameters:
5712 +   mat - the matrix
5713 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5714 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5715                 symmetrized
5716 -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5717                  blockcompressed matrix is desired or not [inode, baij have blockcompressed
5718                  nonzero structure which is different than the full nonzero structure]
5719 
5720     Output Parameters:
5721 +   n - size of (possibly compressed) matrix
5722 .   ia - the column pointers
5723 .   ja - the row indices
5724 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5725 
5726     Level: developer
5727 
5728 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
5729 @*/
5730 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5731 {
5732   PetscErrorCode ierr;
5733 
5734   PetscFunctionBegin;
5735   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5736   PetscValidType(mat,1);
5737   if (ia) PetscValidIntPointer(ia,5);
5738   if (ja) PetscValidIntPointer(ja,6);
5739   PetscValidIntPointer(done,7);
5740   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5741 
5742   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
5743   else {
5744     *done = PETSC_TRUE;
5745     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);CHKERRQ(ierr);
5746   }
5747   PetscFunctionReturn(0);
5748 }
5749 
5750 #undef __FUNCT__
5751 #define __FUNCT__ "MatColoringPatch"
5752 /*@C
5753     MatColoringPatch -Used inside matrix coloring routines that
5754     use MatGetRowIJ() and/or MatGetColumnIJ().
5755 
5756     Collective on Mat
5757 
5758     Input Parameters:
5759 +   mat - the matrix
5760 .   ncolors - max color value
5761 .   n   - number of entries in colorarray
5762 -   colorarray - array indicating color for each column
5763 
5764     Output Parameters:
5765 .   iscoloring - coloring generated using colorarray information
5766 
5767     Level: developer
5768 
5769 .seealso: MatGetRowIJ(), MatGetColumnIJ()
5770 
5771 @*/
5772 PetscErrorCode PETSCMAT_DLLEXPORT MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
5773 {
5774   PetscErrorCode ierr;
5775 
5776   PetscFunctionBegin;
5777   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5778   PetscValidType(mat,1);
5779   PetscValidIntPointer(colorarray,4);
5780   PetscValidPointer(iscoloring,5);
5781   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5782 
5783   if (!mat->ops->coloringpatch){
5784     ierr = ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
5785   } else {
5786     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
5787   }
5788   PetscFunctionReturn(0);
5789 }
5790 
5791 
5792 #undef __FUNCT__
5793 #define __FUNCT__ "MatSetUnfactored"
5794 /*@
5795    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
5796 
5797    Collective on Mat
5798 
5799    Input Parameter:
5800 .  mat - the factored matrix to be reset
5801 
5802    Notes:
5803    This routine should be used only with factored matrices formed by in-place
5804    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
5805    format).  This option can save memory, for example, when solving nonlinear
5806    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
5807    ILU(0) preconditioner.
5808 
5809    Note that one can specify in-place ILU(0) factorization by calling
5810 .vb
5811      PCType(pc,PCILU);
5812      PCFactorSeUseInPlace(pc);
5813 .ve
5814    or by using the options -pc_type ilu -pc_factor_in_place
5815 
5816    In-place factorization ILU(0) can also be used as a local
5817    solver for the blocks within the block Jacobi or additive Schwarz
5818    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
5819    of these preconditioners in the users manual for details on setting
5820    local solver options.
5821 
5822    Most users should employ the simplified KSP interface for linear solvers
5823    instead of working directly with matrix algebra routines such as this.
5824    See, e.g., KSPCreate().
5825 
5826    Level: developer
5827 
5828 .seealso: PCFactorSetUseInPlace()
5829 
5830    Concepts: matrices^unfactored
5831 
5832 @*/
5833 PetscErrorCode PETSCMAT_DLLEXPORT MatSetUnfactored(Mat mat)
5834 {
5835   PetscErrorCode ierr;
5836 
5837   PetscFunctionBegin;
5838   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5839   PetscValidType(mat,1);
5840   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5841   mat->factor = 0;
5842   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
5843   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
5844   PetscFunctionReturn(0);
5845 }
5846 
5847 /*MC
5848     MatGetArrayF90 - Accesses a matrix array from Fortran90.
5849 
5850     Synopsis:
5851     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
5852 
5853     Not collective
5854 
5855     Input Parameter:
5856 .   x - matrix
5857 
5858     Output Parameters:
5859 +   xx_v - the Fortran90 pointer to the array
5860 -   ierr - error code
5861 
5862     Example of Usage:
5863 .vb
5864       PetscScalar, pointer xx_v(:)
5865       ....
5866       call MatGetArrayF90(x,xx_v,ierr)
5867       a = xx_v(3)
5868       call MatRestoreArrayF90(x,xx_v,ierr)
5869 .ve
5870 
5871     Notes:
5872     Not yet supported for all F90 compilers
5873 
5874     Level: advanced
5875 
5876 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
5877 
5878     Concepts: matrices^accessing array
5879 
5880 M*/
5881 
5882 /*MC
5883     MatRestoreArrayF90 - Restores a matrix array that has been
5884     accessed with MatGetArrayF90().
5885 
5886     Synopsis:
5887     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
5888 
5889     Not collective
5890 
5891     Input Parameters:
5892 +   x - matrix
5893 -   xx_v - the Fortran90 pointer to the array
5894 
5895     Output Parameter:
5896 .   ierr - error code
5897 
5898     Example of Usage:
5899 .vb
5900        PetscScalar, pointer xx_v(:)
5901        ....
5902        call MatGetArrayF90(x,xx_v,ierr)
5903        a = xx_v(3)
5904        call MatRestoreArrayF90(x,xx_v,ierr)
5905 .ve
5906 
5907     Notes:
5908     Not yet supported for all F90 compilers
5909 
5910     Level: advanced
5911 
5912 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
5913 
5914 M*/
5915 
5916 
5917 #undef __FUNCT__
5918 #define __FUNCT__ "MatGetSubMatrix"
5919 /*@
5920     MatGetSubMatrix - Gets a single submatrix on the same number of processors
5921                       as the original matrix.
5922 
5923     Collective on Mat
5924 
5925     Input Parameters:
5926 +   mat - the original matrix
5927 .   isrow - rows this processor should obtain
5928 .   iscol - columns for all processors you wish to keep
5929 .   csize - number of columns "local" to this processor (does nothing for sequential
5930             matrices). This should match the result from VecGetLocalSize(x,...) if you
5931             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
5932 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
5933 
5934     Output Parameter:
5935 .   newmat - the new submatrix, of the same type as the old
5936 
5937     Level: advanced
5938 
5939     Notes: the iscol argument MUST be the same on each processor. You might be
5940     able to create the iscol argument with ISAllGather(). The rows is isrow will be
5941     sorted into the same order as the original matrix.
5942 
5943       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
5944    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
5945    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
5946    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
5947    you are finished using it.
5948 
5949     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
5950     the input matrix.
5951 
5952     Concepts: matrices^submatrices
5953 
5954 .seealso: MatGetSubMatrices(), ISAllGather()
5955 @*/
5956 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrix(Mat mat,IS isrow,IS iscol,PetscInt csize,MatReuse cll,Mat *newmat)
5957 {
5958   PetscErrorCode ierr;
5959   PetscMPIInt    size;
5960   Mat            *local;
5961 
5962   PetscFunctionBegin;
5963   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5964   PetscValidHeaderSpecific(isrow,IS_COOKIE,2);
5965   PetscValidHeaderSpecific(iscol,IS_COOKIE,3);
5966   PetscValidPointer(newmat,6);
5967   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_COOKIE,6);
5968   PetscValidType(mat,1);
5969   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5970   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5971   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5972 
5973   /* if original matrix is on just one processor then use submatrix generated */
5974   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
5975     ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
5976     PetscFunctionReturn(0);
5977   } else if (!mat->ops->getsubmatrix && size == 1) {
5978     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
5979     *newmat = *local;
5980     ierr    = PetscFree(local);CHKERRQ(ierr);
5981     PetscFunctionReturn(0);
5982   }
5983 
5984   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5985   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscol,csize,cll,newmat);CHKERRQ(ierr);
5986   ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);
5987   PetscFunctionReturn(0);
5988 }
5989 
5990 #undef __FUNCT__
5991 #define __FUNCT__ "MatGetSubMatrixRaw"
5992 /*@
5993     MatGetSubMatrixRaw - Gets a single submatrix on the same number of processors
5994                          as the original matrix.
5995 
5996     Collective on Mat
5997 
5998     Input Parameters:
5999 +   mat - the original matrix
6000 .   nrows - the number of rows this processor should obtain
6001 .   rows - rows this processor should obtain
6002 .   ncols - the number of columns for all processors you wish to keep
6003 .   cols - columns for all processors you wish to keep
6004 .   csize - number of columns "local" to this processor (does nothing for sequential
6005             matrices). This should match the result from VecGetLocalSize(x,...) if you
6006             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
6007 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6008 
6009     Output Parameter:
6010 .   newmat - the new submatrix, of the same type as the old
6011 
6012     Level: advanced
6013 
6014     Notes: the iscol argument MUST be the same on each processor. You might be
6015     able to create the iscol argument with ISAllGather().
6016 
6017       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
6018    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
6019    to this routine with a mat of the same nonzero structure and with a cll of MAT_REUSE_MATRIX
6020    will reuse the matrix generated the first time.
6021 
6022     Concepts: matrices^submatrices
6023 
6024 .seealso: MatGetSubMatrices(), ISAllGather()
6025 @*/
6026 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrixRaw(Mat mat,PetscInt nrows,const PetscInt rows[],PetscInt ncols,const PetscInt cols[],PetscInt csize,MatReuse cll,Mat *newmat)
6027 {
6028   IS             isrow, iscol;
6029   PetscErrorCode ierr;
6030 
6031   PetscFunctionBegin;
6032   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6033   PetscValidIntPointer(rows,2);
6034   PetscValidIntPointer(cols,3);
6035   PetscValidPointer(newmat,6);
6036   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_COOKIE,6);
6037   PetscValidType(mat,1);
6038   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6039   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6040   ierr = ISCreateGeneralWithArray(PETSC_COMM_SELF, nrows, (PetscInt *) rows, &isrow);CHKERRQ(ierr);
6041   ierr = ISCreateGeneralWithArray(PETSC_COMM_SELF, ncols, (PetscInt *) cols, &iscol);CHKERRQ(ierr);
6042   ierr = MatGetSubMatrix(mat, isrow, iscol, csize, cll, newmat);CHKERRQ(ierr);
6043   ierr = ISDestroy(isrow);CHKERRQ(ierr);
6044   ierr = ISDestroy(iscol);CHKERRQ(ierr);
6045   PetscFunctionReturn(0);
6046 }
6047 
6048 #undef __FUNCT__
6049 #define __FUNCT__ "MatStashSetInitialSize"
6050 /*@
6051    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
6052    used during the assembly process to store values that belong to
6053    other processors.
6054 
6055    Not Collective
6056 
6057    Input Parameters:
6058 +  mat   - the matrix
6059 .  size  - the initial size of the stash.
6060 -  bsize - the initial size of the block-stash(if used).
6061 
6062    Options Database Keys:
6063 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
6064 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
6065 
6066    Level: intermediate
6067 
6068    Notes:
6069      The block-stash is used for values set with MatSetValuesBlocked() while
6070      the stash is used for values set with MatSetValues()
6071 
6072      Run with the option -info and look for output of the form
6073      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
6074      to determine the appropriate value, MM, to use for size and
6075      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
6076      to determine the value, BMM to use for bsize
6077 
6078    Concepts: stash^setting matrix size
6079    Concepts: matrices^stash
6080 
6081 @*/
6082 PetscErrorCode PETSCMAT_DLLEXPORT MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
6083 {
6084   PetscErrorCode ierr;
6085 
6086   PetscFunctionBegin;
6087   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6088   PetscValidType(mat,1);
6089   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
6090   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
6091   PetscFunctionReturn(0);
6092 }
6093 
6094 #undef __FUNCT__
6095 #define __FUNCT__ "MatInterpolateAdd"
6096 /*@
6097    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
6098      the matrix
6099 
6100    Collective on Mat
6101 
6102    Input Parameters:
6103 +  mat   - the matrix
6104 .  x,y - the vectors
6105 -  w - where the result is stored
6106 
6107    Level: intermediate
6108 
6109    Notes:
6110     w may be the same vector as y.
6111 
6112     This allows one to use either the restriction or interpolation (its transpose)
6113     matrix to do the interpolation
6114 
6115     Concepts: interpolation
6116 
6117 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6118 
6119 @*/
6120 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
6121 {
6122   PetscErrorCode ierr;
6123   PetscInt       M,N;
6124 
6125   PetscFunctionBegin;
6126   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6127   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
6128   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
6129   PetscValidHeaderSpecific(w,VEC_COOKIE,4);
6130   PetscValidType(A,1);
6131   ierr = MatPreallocated(A);CHKERRQ(ierr);
6132   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6133   if (N > M) {
6134     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
6135   } else {
6136     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
6137   }
6138   PetscFunctionReturn(0);
6139 }
6140 
6141 #undef __FUNCT__
6142 #define __FUNCT__ "MatInterpolate"
6143 /*@
6144    MatInterpolate - y = A*x or A'*x depending on the shape of
6145      the matrix
6146 
6147    Collective on Mat
6148 
6149    Input Parameters:
6150 +  mat   - the matrix
6151 -  x,y - the vectors
6152 
6153    Level: intermediate
6154 
6155    Notes:
6156     This allows one to use either the restriction or interpolation (its transpose)
6157     matrix to do the interpolation
6158 
6159    Concepts: matrices^interpolation
6160 
6161 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6162 
6163 @*/
6164 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolate(Mat A,Vec x,Vec y)
6165 {
6166   PetscErrorCode ierr;
6167   PetscInt       M,N;
6168 
6169   PetscFunctionBegin;
6170   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6171   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
6172   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
6173   PetscValidType(A,1);
6174   ierr = MatPreallocated(A);CHKERRQ(ierr);
6175   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6176   if (N > M) {
6177     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
6178   } else {
6179     ierr = MatMult(A,x,y);CHKERRQ(ierr);
6180   }
6181   PetscFunctionReturn(0);
6182 }
6183 
6184 #undef __FUNCT__
6185 #define __FUNCT__ "MatRestrict"
6186 /*@
6187    MatRestrict - y = A*x or A'*x
6188 
6189    Collective on Mat
6190 
6191    Input Parameters:
6192 +  mat   - the matrix
6193 -  x,y - the vectors
6194 
6195    Level: intermediate
6196 
6197    Notes:
6198     This allows one to use either the restriction or interpolation (its transpose)
6199     matrix to do the restriction
6200 
6201    Concepts: matrices^restriction
6202 
6203 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
6204 
6205 @*/
6206 PetscErrorCode PETSCMAT_DLLEXPORT MatRestrict(Mat A,Vec x,Vec y)
6207 {
6208   PetscErrorCode ierr;
6209   PetscInt       M,N;
6210 
6211   PetscFunctionBegin;
6212   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6213   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
6214   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
6215   PetscValidType(A,1);
6216   ierr = MatPreallocated(A);CHKERRQ(ierr);
6217 
6218   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6219   if (N > M) {
6220     ierr = MatMult(A,x,y);CHKERRQ(ierr);
6221   } else {
6222     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
6223   }
6224   PetscFunctionReturn(0);
6225 }
6226 
6227 #undef __FUNCT__
6228 #define __FUNCT__ "MatNullSpaceAttach"
6229 /*@
6230    MatNullSpaceAttach - attaches a null space to a matrix.
6231         This null space will be removed from the resulting vector whenever
6232         MatMult() is called
6233 
6234    Collective on Mat
6235 
6236    Input Parameters:
6237 +  mat - the matrix
6238 -  nullsp - the null space object
6239 
6240    Level: developer
6241 
6242    Notes:
6243       Overwrites any previous null space that may have been attached
6244 
6245    Concepts: null space^attaching to matrix
6246 
6247 .seealso: MatCreate(), MatNullSpaceCreate()
6248 @*/
6249 PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
6250 {
6251   PetscErrorCode ierr;
6252 
6253   PetscFunctionBegin;
6254   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6255   PetscValidType(mat,1);
6256   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_COOKIE,2);
6257   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6258   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
6259   if (mat->nullsp) { ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr); }
6260   mat->nullsp = nullsp;
6261   PetscFunctionReturn(0);
6262 }
6263 
6264 #undef __FUNCT__
6265 #define __FUNCT__ "MatICCFactor"
6266 /*@
6267    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
6268 
6269    Collective on Mat
6270 
6271    Input Parameters:
6272 +  mat - the matrix
6273 .  row - row/column permutation
6274 .  fill - expected fill factor >= 1.0
6275 -  level - level of fill, for ICC(k)
6276 
6277    Notes:
6278    Probably really in-place only when level of fill is zero, otherwise allocates
6279    new space to store factored matrix and deletes previous memory.
6280 
6281    Most users should employ the simplified KSP interface for linear solvers
6282    instead of working directly with matrix algebra routines such as this.
6283    See, e.g., KSPCreate().
6284 
6285    Level: developer
6286 
6287    Concepts: matrices^incomplete Cholesky factorization
6288    Concepts: Cholesky factorization
6289 
6290 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6291 @*/
6292 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactor(Mat mat,IS row,MatFactorInfo* info)
6293 {
6294   PetscErrorCode ierr;
6295 
6296   PetscFunctionBegin;
6297   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6298   PetscValidType(mat,1);
6299   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
6300   PetscValidPointer(info,3);
6301   if (mat->rmap.N != mat->cmap.N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
6302   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6303   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6304   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6305   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6306   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
6307   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6308   PetscFunctionReturn(0);
6309 }
6310 
6311 #undef __FUNCT__
6312 #define __FUNCT__ "MatSetValuesAdic"
6313 /*@
6314    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
6315 
6316    Not Collective
6317 
6318    Input Parameters:
6319 +  mat - the matrix
6320 -  v - the values compute with ADIC
6321 
6322    Level: developer
6323 
6324    Notes:
6325      Must call MatSetColoring() before using this routine. Also this matrix must already
6326      have its nonzero pattern determined.
6327 
6328 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6329           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
6330 @*/
6331 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdic(Mat mat,void *v)
6332 {
6333   PetscErrorCode ierr;
6334 
6335   PetscFunctionBegin;
6336   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6337   PetscValidType(mat,1);
6338   PetscValidPointer(mat,2);
6339 
6340   if (!mat->assembled) {
6341     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6342   }
6343   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6344   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6345   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
6346   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6347   ierr = MatView_Private(mat);CHKERRQ(ierr);
6348   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6349   PetscFunctionReturn(0);
6350 }
6351 
6352 
6353 #undef __FUNCT__
6354 #define __FUNCT__ "MatSetColoring"
6355 /*@
6356    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
6357 
6358    Not Collective
6359 
6360    Input Parameters:
6361 +  mat - the matrix
6362 -  coloring - the coloring
6363 
6364    Level: developer
6365 
6366 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6367           MatSetValues(), MatSetValuesAdic()
6368 @*/
6369 PetscErrorCode PETSCMAT_DLLEXPORT MatSetColoring(Mat mat,ISColoring coloring)
6370 {
6371   PetscErrorCode ierr;
6372 
6373   PetscFunctionBegin;
6374   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6375   PetscValidType(mat,1);
6376   PetscValidPointer(coloring,2);
6377 
6378   if (!mat->assembled) {
6379     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6380   }
6381   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6382   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
6383   PetscFunctionReturn(0);
6384 }
6385 
6386 #undef __FUNCT__
6387 #define __FUNCT__ "MatSetValuesAdifor"
6388 /*@
6389    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
6390 
6391    Not Collective
6392 
6393    Input Parameters:
6394 +  mat - the matrix
6395 .  nl - leading dimension of v
6396 -  v - the values compute with ADIFOR
6397 
6398    Level: developer
6399 
6400    Notes:
6401      Must call MatSetColoring() before using this routine. Also this matrix must already
6402      have its nonzero pattern determined.
6403 
6404 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6405           MatSetValues(), MatSetColoring()
6406 @*/
6407 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
6408 {
6409   PetscErrorCode ierr;
6410 
6411   PetscFunctionBegin;
6412   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6413   PetscValidType(mat,1);
6414   PetscValidPointer(v,3);
6415 
6416   if (!mat->assembled) {
6417     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6418   }
6419   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6420   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6421   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
6422   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6423   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6424   PetscFunctionReturn(0);
6425 }
6426 
6427 #undef __FUNCT__
6428 #define __FUNCT__ "MatDiagonalScaleLocal"
6429 /*@
6430    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
6431          ghosted ones.
6432 
6433    Not Collective
6434 
6435    Input Parameters:
6436 +  mat - the matrix
6437 -  diag = the diagonal values, including ghost ones
6438 
6439    Level: developer
6440 
6441    Notes: Works only for MPIAIJ and MPIBAIJ matrices
6442 
6443 .seealso: MatDiagonalScale()
6444 @*/
6445 PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalScaleLocal(Mat mat,Vec diag)
6446 {
6447   PetscErrorCode ierr;
6448   PetscMPIInt    size;
6449 
6450   PetscFunctionBegin;
6451   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6452   PetscValidHeaderSpecific(diag,VEC_COOKIE,2);
6453   PetscValidType(mat,1);
6454 
6455   if (!mat->assembled) {
6456     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6457   }
6458   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
6459   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
6460   if (size == 1) {
6461     PetscInt n,m;
6462     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
6463     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
6464     if (m == n) {
6465       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
6466     } else {
6467       SETERRQ(PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
6468     }
6469   } else {
6470     PetscErrorCode (*f)(Mat,Vec);
6471     ierr = PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);CHKERRQ(ierr);
6472     if (f) {
6473       ierr = (*f)(mat,diag);CHKERRQ(ierr);
6474     } else {
6475       SETERRQ(PETSC_ERR_SUP,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
6476     }
6477   }
6478   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
6479   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6480   PetscFunctionReturn(0);
6481 }
6482 
6483 #undef __FUNCT__
6484 #define __FUNCT__ "MatGetInertia"
6485 /*@
6486    MatGetInertia - Gets the inertia from a factored matrix
6487 
6488    Collective on Mat
6489 
6490    Input Parameter:
6491 .  mat - the matrix
6492 
6493    Output Parameters:
6494 +   nneg - number of negative eigenvalues
6495 .   nzero - number of zero eigenvalues
6496 -   npos - number of positive eigenvalues
6497 
6498    Level: advanced
6499 
6500    Notes: Matrix must have been factored by MatCholeskyFactor()
6501 
6502 
6503 @*/
6504 PetscErrorCode PETSCMAT_DLLEXPORT MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
6505 {
6506   PetscErrorCode ierr;
6507 
6508   PetscFunctionBegin;
6509   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6510   PetscValidType(mat,1);
6511   if (!mat->factor)    SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6512   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
6513   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6514   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
6515   PetscFunctionReturn(0);
6516 }
6517 
6518 /* ----------------------------------------------------------------*/
6519 #undef __FUNCT__
6520 #define __FUNCT__ "MatSolves"
6521 /*@
6522    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
6523 
6524    Collective on Mat and Vecs
6525 
6526    Input Parameters:
6527 +  mat - the factored matrix
6528 -  b - the right-hand-side vectors
6529 
6530    Output Parameter:
6531 .  x - the result vectors
6532 
6533    Notes:
6534    The vectors b and x cannot be the same.  I.e., one cannot
6535    call MatSolves(A,x,x).
6536 
6537    Notes:
6538    Most users should employ the simplified KSP interface for linear solvers
6539    instead of working directly with matrix algebra routines such as this.
6540    See, e.g., KSPCreate().
6541 
6542    Level: developer
6543 
6544    Concepts: matrices^triangular solves
6545 
6546 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
6547 @*/
6548 PetscErrorCode PETSCMAT_DLLEXPORT MatSolves(Mat mat,Vecs b,Vecs x)
6549 {
6550   PetscErrorCode ierr;
6551 
6552   PetscFunctionBegin;
6553   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6554   PetscValidType(mat,1);
6555   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
6556   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6557   if (!mat->rmap.N && !mat->cmap.N) PetscFunctionReturn(0);
6558 
6559   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6560   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6561   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
6562   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
6563   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
6564   PetscFunctionReturn(0);
6565 }
6566 
6567 #undef __FUNCT__
6568 #define __FUNCT__ "MatIsSymmetric"
6569 /*@
6570    MatIsSymmetric - Test whether a matrix is symmetric
6571 
6572    Collective on Mat
6573 
6574    Input Parameter:
6575 +  A - the matrix to test
6576 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
6577 
6578    Output Parameters:
6579 .  flg - the result
6580 
6581    Level: intermediate
6582 
6583    Concepts: matrix^symmetry
6584 
6585 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6586 @*/
6587 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetric(Mat A,PetscReal tol,PetscTruth *flg)
6588 {
6589   PetscErrorCode ierr;
6590 
6591   PetscFunctionBegin;
6592   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6593   PetscValidPointer(flg,2);
6594   if (!A->symmetric_set) {
6595     if (!A->ops->issymmetric) {
6596       MatType mattype;
6597       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
6598       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
6599     }
6600     ierr = (*A->ops->issymmetric)(A,tol,&A->symmetric);CHKERRQ(ierr);
6601     A->symmetric_set = PETSC_TRUE;
6602     if (A->symmetric) {
6603       A->structurally_symmetric_set = PETSC_TRUE;
6604       A->structurally_symmetric     = PETSC_TRUE;
6605     }
6606   }
6607   *flg = A->symmetric;
6608   PetscFunctionReturn(0);
6609 }
6610 
6611 #undef __FUNCT__
6612 #define __FUNCT__ "MatIsHermitian"
6613 /*@
6614    MatIsHermitian - Test whether a matrix is Hermitian
6615 
6616    Collective on Mat
6617 
6618    Input Parameter:
6619 +  A - the matrix to test
6620 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
6621 
6622    Output Parameters:
6623 .  flg - the result
6624 
6625    Level: intermediate
6626 
6627    Concepts: matrix^symmetry
6628 
6629 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6630 @*/
6631 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitian(Mat A,PetscReal tol,PetscTruth *flg)
6632 {
6633   PetscErrorCode ierr;
6634 
6635   PetscFunctionBegin;
6636   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6637   PetscValidPointer(flg,2);
6638   if (!A->hermitian_set) {
6639     if (!A->ops->ishermitian) {
6640       MatType mattype;
6641       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
6642       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for Hermitian",mattype);
6643     }
6644     ierr = (*A->ops->ishermitian)(A,tol,&A->hermitian);CHKERRQ(ierr);
6645     A->hermitian_set = PETSC_TRUE;
6646     if (A->hermitian) {
6647       A->structurally_symmetric_set = PETSC_TRUE;
6648       A->structurally_symmetric     = PETSC_TRUE;
6649     }
6650   }
6651   *flg = A->hermitian;
6652   PetscFunctionReturn(0);
6653 }
6654 
6655 #undef __FUNCT__
6656 #define __FUNCT__ "MatIsSymmetricKnown"
6657 /*@
6658    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
6659 
6660    Collective on Mat
6661 
6662    Input Parameter:
6663 .  A - the matrix to check
6664 
6665    Output Parameters:
6666 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
6667 -  flg - the result
6668 
6669    Level: advanced
6670 
6671    Concepts: matrix^symmetry
6672 
6673    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
6674          if you want it explicitly checked
6675 
6676 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6677 @*/
6678 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetricKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6679 {
6680   PetscFunctionBegin;
6681   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6682   PetscValidPointer(set,2);
6683   PetscValidPointer(flg,3);
6684   if (A->symmetric_set) {
6685     *set = PETSC_TRUE;
6686     *flg = A->symmetric;
6687   } else {
6688     *set = PETSC_FALSE;
6689   }
6690   PetscFunctionReturn(0);
6691 }
6692 
6693 #undef __FUNCT__
6694 #define __FUNCT__ "MatIsHermitianKnown"
6695 /*@
6696    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
6697 
6698    Collective on Mat
6699 
6700    Input Parameter:
6701 .  A - the matrix to check
6702 
6703    Output Parameters:
6704 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
6705 -  flg - the result
6706 
6707    Level: advanced
6708 
6709    Concepts: matrix^symmetry
6710 
6711    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
6712          if you want it explicitly checked
6713 
6714 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6715 @*/
6716 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitianKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6717 {
6718   PetscFunctionBegin;
6719   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6720   PetscValidPointer(set,2);
6721   PetscValidPointer(flg,3);
6722   if (A->hermitian_set) {
6723     *set = PETSC_TRUE;
6724     *flg = A->hermitian;
6725   } else {
6726     *set = PETSC_FALSE;
6727   }
6728   PetscFunctionReturn(0);
6729 }
6730 
6731 #undef __FUNCT__
6732 #define __FUNCT__ "MatIsStructurallySymmetric"
6733 /*@
6734    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
6735 
6736    Collective on Mat
6737 
6738    Input Parameter:
6739 .  A - the matrix to test
6740 
6741    Output Parameters:
6742 .  flg - the result
6743 
6744    Level: intermediate
6745 
6746    Concepts: matrix^symmetry
6747 
6748 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
6749 @*/
6750 PetscErrorCode PETSCMAT_DLLEXPORT MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
6751 {
6752   PetscErrorCode ierr;
6753 
6754   PetscFunctionBegin;
6755   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6756   PetscValidPointer(flg,2);
6757   if (!A->structurally_symmetric_set) {
6758     if (!A->ops->isstructurallysymmetric) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
6759     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
6760     A->structurally_symmetric_set = PETSC_TRUE;
6761   }
6762   *flg = A->structurally_symmetric;
6763   PetscFunctionReturn(0);
6764 }
6765 
6766 #undef __FUNCT__
6767 #define __FUNCT__ "MatStashGetInfo"
6768 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
6769 /*@
6770    MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
6771        to be communicated to other processors during the MatAssemblyBegin/End() process
6772 
6773     Not collective
6774 
6775    Input Parameter:
6776 .   vec - the vector
6777 
6778    Output Parameters:
6779 +   nstash   - the size of the stash
6780 .   reallocs - the number of additional mallocs incurred.
6781 .   bnstash   - the size of the block stash
6782 -   breallocs - the number of additional mallocs incurred.in the block stash
6783 
6784    Level: advanced
6785 
6786 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
6787 
6788 @*/
6789 PetscErrorCode PETSCMAT_DLLEXPORT MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
6790 {
6791   PetscErrorCode ierr;
6792   PetscFunctionBegin;
6793   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
6794   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
6795   PetscFunctionReturn(0);
6796 }
6797 
6798 #undef __FUNCT__
6799 #define __FUNCT__ "MatGetVecs"
6800 /*@C
6801    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
6802      parallel layout
6803 
6804    Collective on Mat
6805 
6806    Input Parameter:
6807 .  mat - the matrix
6808 
6809    Output Parameter:
6810 +   right - (optional) vector that the matrix can be multiplied against
6811 -   left - (optional) vector that the matrix vector product can be stored in
6812 
6813   Level: advanced
6814 
6815 .seealso: MatCreate()
6816 @*/
6817 PetscErrorCode PETSCMAT_DLLEXPORT MatGetVecs(Mat mat,Vec *right,Vec *left)
6818 {
6819   PetscErrorCode ierr;
6820 
6821   PetscFunctionBegin;
6822   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6823   PetscValidType(mat,1);
6824   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6825   if (mat->ops->getvecs) {
6826     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
6827   } else {
6828     PetscMPIInt size;
6829     ierr = MPI_Comm_size(((PetscObject)mat)->comm, &size);CHKERRQ(ierr);
6830     if (right) {
6831       ierr = VecCreate(((PetscObject)mat)->comm,right);CHKERRQ(ierr);
6832       ierr = VecSetSizes(*right,mat->cmap.n,PETSC_DETERMINE);CHKERRQ(ierr);
6833       if (size > 1) {ierr = VecSetType(*right,VECMPI);CHKERRQ(ierr);}
6834       else {ierr = VecSetType(*right,VECSEQ);CHKERRQ(ierr);}
6835     }
6836     if (left) {
6837       ierr = VecCreate(((PetscObject)mat)->comm,left);CHKERRQ(ierr);
6838       ierr = VecSetSizes(*left,mat->rmap.n,PETSC_DETERMINE);CHKERRQ(ierr);
6839       if (size > 1) {ierr = VecSetType(*left,VECMPI);CHKERRQ(ierr);}
6840       else {ierr = VecSetType(*left,VECSEQ);CHKERRQ(ierr);}
6841     }
6842   }
6843   if (right) {ierr = VecSetBlockSize(*right,mat->rmap.bs);CHKERRQ(ierr);}
6844   if (left) {ierr = VecSetBlockSize(*left,mat->rmap.bs);CHKERRQ(ierr);}
6845   if (mat->mapping) {
6846     if (right) {ierr = VecSetLocalToGlobalMapping(*right,mat->mapping);CHKERRQ(ierr);}
6847     if (left) {ierr = VecSetLocalToGlobalMapping(*left,mat->mapping);CHKERRQ(ierr);}
6848   }
6849   if (mat->bmapping) {
6850     if (right) {ierr = VecSetLocalToGlobalMappingBlock(*right,mat->bmapping);CHKERRQ(ierr);}
6851     if (left) {ierr = VecSetLocalToGlobalMappingBlock(*left,mat->bmapping);CHKERRQ(ierr);}
6852   }
6853   PetscFunctionReturn(0);
6854 }
6855 
6856 #undef __FUNCT__
6857 #define __FUNCT__ "MatFactorInfoInitialize"
6858 /*@
6859    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
6860      with default values.
6861 
6862    Not Collective
6863 
6864    Input Parameters:
6865 .    info - the MatFactorInfo data structure
6866 
6867 
6868    Notes: The solvers are generally used through the KSP and PC objects, for example
6869           PCLU, PCILU, PCCHOLESKY, PCICC
6870 
6871    Level: developer
6872 
6873 .seealso: MatFactorInfo
6874 @*/
6875 
6876 PetscErrorCode PETSCMAT_DLLEXPORT MatFactorInfoInitialize(MatFactorInfo *info)
6877 {
6878   PetscErrorCode ierr;
6879 
6880   PetscFunctionBegin;
6881   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
6882   PetscFunctionReturn(0);
6883 }
6884 
6885 #undef __FUNCT__
6886 #define __FUNCT__ "MatPtAP"
6887 /*@
6888    MatPtAP - Creates the matrix projection C = P^T * A * P
6889 
6890    Collective on Mat
6891 
6892    Input Parameters:
6893 +  A - the matrix
6894 .  P - the projection matrix
6895 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6896 -  fill - expected fill as ratio of nnz(C)/nnz(A)
6897 
6898    Output Parameters:
6899 .  C - the product matrix
6900 
6901    Notes:
6902    C will be created and must be destroyed by the user with MatDestroy().
6903 
6904    This routine is currently only implemented for pairs of AIJ matrices and classes
6905    which inherit from AIJ.
6906 
6907    Level: intermediate
6908 
6909 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
6910 @*/
6911 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
6912 {
6913   PetscErrorCode ierr;
6914 
6915   PetscFunctionBegin;
6916   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6917   PetscValidType(A,1);
6918   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6919   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6920   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
6921   PetscValidType(P,2);
6922   MatPreallocated(P);
6923   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6924   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6925   PetscValidPointer(C,3);
6926   if (P->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap.N,A->cmap.N);
6927   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
6928   ierr = MatPreallocated(A);CHKERRQ(ierr);
6929 
6930   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
6931   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
6932   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
6933 
6934   PetscFunctionReturn(0);
6935 }
6936 
6937 #undef __FUNCT__
6938 #define __FUNCT__ "MatPtAPNumeric"
6939 /*@
6940    MatPtAPNumeric - Computes the matrix projection C = P^T * A * P
6941 
6942    Collective on Mat
6943 
6944    Input Parameters:
6945 +  A - the matrix
6946 -  P - the projection matrix
6947 
6948    Output Parameters:
6949 .  C - the product matrix
6950 
6951    Notes:
6952    C must have been created by calling MatPtAPSymbolic and must be destroyed by
6953    the user using MatDeatroy().
6954 
6955    This routine is currently only implemented for pairs of AIJ matrices and classes
6956    which inherit from AIJ.  C will be of type MATAIJ.
6957 
6958    Level: intermediate
6959 
6960 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
6961 @*/
6962 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPNumeric(Mat A,Mat P,Mat C)
6963 {
6964   PetscErrorCode ierr;
6965 
6966   PetscFunctionBegin;
6967   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6968   PetscValidType(A,1);
6969   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6970   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6971   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
6972   PetscValidType(P,2);
6973   MatPreallocated(P);
6974   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6975   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6976   PetscValidHeaderSpecific(C,MAT_COOKIE,3);
6977   PetscValidType(C,3);
6978   MatPreallocated(C);
6979   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6980   if (P->cmap.N!=C->rmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap.N,C->rmap.N);
6981   if (P->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap.N,A->cmap.N);
6982   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);
6983   if (P->cmap.N!=C->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap.N,C->cmap.N);
6984   ierr = MatPreallocated(A);CHKERRQ(ierr);
6985 
6986   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
6987   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
6988   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
6989   PetscFunctionReturn(0);
6990 }
6991 
6992 #undef __FUNCT__
6993 #define __FUNCT__ "MatPtAPSymbolic"
6994 /*@
6995    MatPtAPSymbolic - Creates the (i,j) structure of the matrix projection C = P^T * A * P
6996 
6997    Collective on Mat
6998 
6999    Input Parameters:
7000 +  A - the matrix
7001 -  P - the projection matrix
7002 
7003    Output Parameters:
7004 .  C - the (i,j) structure of the product matrix
7005 
7006    Notes:
7007    C will be created and must be destroyed by the user with MatDestroy().
7008 
7009    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
7010    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
7011    this (i,j) structure by calling MatPtAPNumeric().
7012 
7013    Level: intermediate
7014 
7015 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
7016 @*/
7017 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
7018 {
7019   PetscErrorCode ierr;
7020 
7021   PetscFunctionBegin;
7022   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7023   PetscValidType(A,1);
7024   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7025   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7026   if (fill <1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7027   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
7028   PetscValidType(P,2);
7029   MatPreallocated(P);
7030   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7031   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7032   PetscValidPointer(C,3);
7033 
7034   if (P->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap.N,A->cmap.N);
7035   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);
7036   ierr = MatPreallocated(A);CHKERRQ(ierr);
7037   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
7038   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
7039   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
7040 
7041   ierr = MatSetBlockSize(*C,A->rmap.bs);CHKERRQ(ierr);
7042 
7043   PetscFunctionReturn(0);
7044 }
7045 
7046 #undef __FUNCT__
7047 #define __FUNCT__ "MatMatMult"
7048 /*@
7049    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
7050 
7051    Collective on Mat
7052 
7053    Input Parameters:
7054 +  A - the left matrix
7055 .  B - the right matrix
7056 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7057 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
7058           if the result is a dense matrix this is irrelevent
7059 
7060    Output Parameters:
7061 .  C - the product matrix
7062 
7063    Notes:
7064    Unless scall is MAT_REUSE_MATRIX C will be created.
7065 
7066    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7067 
7068    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7069    actually needed.
7070 
7071    If you have many matrices with the same non-zero structure to multiply, you
7072    should either
7073 $   1) use MAT_REUSE_MATRIX in all calls but the first or
7074 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
7075 
7076    Level: intermediate
7077 
7078 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
7079 @*/
7080 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7081 {
7082   PetscErrorCode ierr;
7083   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7084   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7085   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
7086 
7087   PetscFunctionBegin;
7088   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7089   PetscValidType(A,1);
7090   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7091   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7092   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7093   PetscValidType(B,2);
7094   MatPreallocated(B);
7095   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7096   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7097   PetscValidPointer(C,3);
7098   if (B->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->cmap.N);
7099   if (scall == MAT_REUSE_MATRIX){
7100     PetscValidPointer(*C,5);
7101     PetscValidHeaderSpecific(*C,MAT_COOKIE,5);
7102   }
7103   if (fill == PETSC_DEFAULT) fill = 2.0;
7104   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7105   ierr = MatPreallocated(A);CHKERRQ(ierr);
7106 
7107   fA = A->ops->matmult;
7108   fB = B->ops->matmult;
7109   if (fB == fA) {
7110     if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
7111     mult = fB;
7112   } else {
7113     /* dispatch based on the type of A and B */
7114     char  multname[256];
7115     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
7116     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7117     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
7118     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7119     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
7120     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
7121     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);
7122   }
7123   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
7124   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
7125   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
7126   PetscFunctionReturn(0);
7127 }
7128 
7129 #undef __FUNCT__
7130 #define __FUNCT__ "MatMatMultSymbolic"
7131 /*@
7132    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
7133    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
7134 
7135    Collective on Mat
7136 
7137    Input Parameters:
7138 +  A - the left matrix
7139 .  B - the right matrix
7140 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
7141       if C is a dense matrix this is irrelevent
7142 
7143    Output Parameters:
7144 .  C - the product matrix
7145 
7146    Notes:
7147    Unless scall is MAT_REUSE_MATRIX C will be created.
7148 
7149    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7150    actually needed.
7151 
7152    This routine is currently implemented for
7153     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
7154     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7155     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7156 
7157    Level: intermediate
7158 
7159 .seealso: MatMatMult(), MatMatMultNumeric()
7160 @*/
7161 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
7162 {
7163   PetscErrorCode ierr;
7164   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
7165   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
7166   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
7167 
7168   PetscFunctionBegin;
7169   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7170   PetscValidType(A,1);
7171   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7172   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7173 
7174   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7175   PetscValidType(B,2);
7176   MatPreallocated(B);
7177   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7178   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7179   PetscValidPointer(C,3);
7180 
7181   if (B->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->cmap.N);
7182   if (fill == PETSC_DEFAULT) fill = 2.0;
7183   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7184   ierr = MatPreallocated(A);CHKERRQ(ierr);
7185 
7186   Asymbolic = A->ops->matmultsymbolic;
7187   Bsymbolic = B->ops->matmultsymbolic;
7188   if (Asymbolic == Bsymbolic){
7189     if (!Bsymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
7190     symbolic = Bsymbolic;
7191   } else { /* dispatch based on the type of A and B */
7192     char  symbolicname[256];
7193     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
7194     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7195     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
7196     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7197     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
7198     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
7199     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);
7200   }
7201   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
7202   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
7203   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
7204   PetscFunctionReturn(0);
7205 }
7206 
7207 #undef __FUNCT__
7208 #define __FUNCT__ "MatMatMultNumeric"
7209 /*@
7210    MatMatMultNumeric - Performs the numeric matrix-matrix product.
7211    Call this routine after first calling MatMatMultSymbolic().
7212 
7213    Collective on Mat
7214 
7215    Input Parameters:
7216 +  A - the left matrix
7217 -  B - the right matrix
7218 
7219    Output Parameters:
7220 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
7221 
7222    Notes:
7223    C must have been created with MatMatMultSymbolic().
7224 
7225    This routine is currently implemented for
7226     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
7227     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7228     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7229 
7230    Level: intermediate
7231 
7232 .seealso: MatMatMult(), MatMatMultSymbolic()
7233 @*/
7234 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultNumeric(Mat A,Mat B,Mat C)
7235 {
7236   PetscErrorCode ierr;
7237   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
7238   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
7239   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
7240 
7241   PetscFunctionBegin;
7242   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7243   PetscValidType(A,1);
7244   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7245   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7246 
7247   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7248   PetscValidType(B,2);
7249   MatPreallocated(B);
7250   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7251   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7252 
7253   PetscValidHeaderSpecific(C,MAT_COOKIE,3);
7254   PetscValidType(C,3);
7255   MatPreallocated(C);
7256   if (!C->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7257   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7258 
7259   if (B->cmap.N!=C->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap.N,C->cmap.N);
7260   if (B->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->cmap.N);
7261   if (A->rmap.N!=C->rmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap.N,C->rmap.N);
7262   ierr = MatPreallocated(A);CHKERRQ(ierr);
7263 
7264   Anumeric = A->ops->matmultnumeric;
7265   Bnumeric = B->ops->matmultnumeric;
7266   if (Anumeric == Bnumeric){
7267     if (!Bnumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
7268     numeric = Bnumeric;
7269   } else {
7270     char  numericname[256];
7271     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
7272     ierr = PetscStrcat(numericname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7273     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
7274     ierr = PetscStrcat(numericname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7275     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
7276     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
7277     if (!numeric)
7278       SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7279   }
7280   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
7281   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
7282   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
7283   PetscFunctionReturn(0);
7284 }
7285 
7286 #undef __FUNCT__
7287 #define __FUNCT__ "MatMatMultTranspose"
7288 /*@
7289    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
7290 
7291    Collective on Mat
7292 
7293    Input Parameters:
7294 +  A - the left matrix
7295 .  B - the right matrix
7296 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7297 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
7298 
7299    Output Parameters:
7300 .  C - the product matrix
7301 
7302    Notes:
7303    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
7304 
7305    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7306 
7307   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7308    actually needed.
7309 
7310    This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
7311    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
7312 
7313    Level: intermediate
7314 
7315 .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
7316 @*/
7317 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7318 {
7319   PetscErrorCode ierr;
7320   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7321   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7322 
7323   PetscFunctionBegin;
7324   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7325   PetscValidType(A,1);
7326   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7327   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7328   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7329   PetscValidType(B,2);
7330   MatPreallocated(B);
7331   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7332   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7333   PetscValidPointer(C,3);
7334   if (B->rmap.N!=A->rmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->rmap.N);
7335   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7336   ierr = MatPreallocated(A);CHKERRQ(ierr);
7337 
7338   fA = A->ops->matmulttranspose;
7339   if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
7340   fB = B->ops->matmulttranspose;
7341   if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
7342   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);
7343 
7344   ierr = PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
7345   ierr = (*A->ops->matmulttranspose)(A,B,scall,fill,C);CHKERRQ(ierr);
7346   ierr = PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
7347 
7348   PetscFunctionReturn(0);
7349 }
7350 
7351 #undef __FUNCT__
7352 #define __FUNCT__ "MatGetRedundantMatrix"
7353 /*@C
7354    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
7355 
7356    Collective on Mat
7357 
7358    Input Parameters:
7359 +  mat - the matrix
7360 .  nsubcomm - the number of subcommunicators (= number of redundant pareallel or sequential matrices)
7361 .  subcomm - MPI communicator split from the communicator where mat resides in
7362 .  mlocal_red - number of local rows of the redundant matrix
7363 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7364 
7365    Output Parameter:
7366 .  matredundant - redundant matrix
7367 
7368    Notes:
7369    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
7370    original matrix has not changed from that last call to MatGetRedundantMatrix().
7371 
7372    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
7373    calling it.
7374 
7375    Only MPIAIJ matrix is supported.
7376 
7377    Level: advanced
7378 
7379    Concepts: subcommunicator
7380    Concepts: duplicate matrix
7381 
7382 .seealso: MatDestroy()
7383 @*/
7384 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
7385 {
7386   PetscErrorCode ierr;
7387 
7388   PetscFunctionBegin;
7389   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
7390   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
7391     PetscValidPointer(*matredundant,6);
7392     PetscValidHeaderSpecific(*matredundant,MAT_COOKIE,6);
7393   }
7394   if (!mat->ops->getredundantmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7395   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7396   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7397   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7398 
7399   ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
7400   ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr);
7401   ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
7402   PetscFunctionReturn(0);
7403 }
7404