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