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