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