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