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