xref: /petsc/src/mat/interface/matrix.c (revision 4c31538ffd239e73dd305c31381fa18130b7ff69)
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, unless matrix has not been allocated, then collective on Mat
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(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
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, unless matrix has not been allocated, then collective on Mat
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(), MatGetOwnershipRangesColumn()
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, unless matrix has not been allocated, then collective on Mat
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(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
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 = MatPreallocated(mat);CHKERRQ(ierr);
4964   ierr = PetscMapGetRanges(&mat->rmap,ranges);CHKERRQ(ierr);
4965   PetscFunctionReturn(0);
4966 }
4967 
4968 #undef __FUNCT__
4969 #define __FUNCT__ "MatGetOwnershipRangesColumn"
4970 /*@C
4971    MatGetOwnershipRangesColumn - Returns the range of local columns for each process
4972 
4973    Not Collective, unless matrix has not been allocated, then collective on Mat
4974 
4975    Input Parameters:
4976 .  mat - the matrix
4977 
4978    Output Parameters:
4979 .  ranges - start of each processors portion plus one more then the total length at the end
4980 
4981    Level: beginner
4982 
4983    Concepts: matrices^column ownership
4984 
4985 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
4986 
4987 @*/
4988 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
4989 {
4990   PetscErrorCode ierr;
4991 
4992   PetscFunctionBegin;
4993   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4994   PetscValidType(mat,1);
4995   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4996   ierr = PetscMapGetRanges(&mat->cmap,ranges);CHKERRQ(ierr);
4997   PetscFunctionReturn(0);
4998 }
4999 
5000 #undef __FUNCT__
5001 #define __FUNCT__ "MatILUFactorSymbolic"
5002 /*@
5003    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
5004    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
5005    to complete the factorization.
5006 
5007    Collective on Mat
5008 
5009    Input Parameters:
5010 +  mat - the matrix
5011 .  row - row permutation
5012 .  column - column permutation
5013 -  info - structure containing
5014 $      levels - number of levels of fill.
5015 $      expected fill - as ratio of original fill.
5016 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
5017                 missing diagonal entries)
5018 
5019    Output Parameters:
5020 .  fact - new matrix that has been symbolically factored
5021 
5022    Notes:
5023    See the users manual for additional information about
5024    choosing the fill factor for better efficiency.
5025 
5026    Most users should employ the simplified KSP interface for linear solvers
5027    instead of working directly with matrix algebra routines such as this.
5028    See, e.g., KSPCreate().
5029 
5030    Level: developer
5031 
5032   Concepts: matrices^symbolic LU factorization
5033   Concepts: matrices^factorization
5034   Concepts: LU^symbolic factorization
5035 
5036 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5037           MatGetOrdering(), MatFactorInfo
5038 
5039 @*/
5040 PetscErrorCode PETSCMAT_DLLEXPORT MatILUFactorSymbolic(Mat mat,IS row,IS col,MatFactorInfo *info,Mat *fact)
5041 {
5042   PetscErrorCode ierr;
5043 
5044   PetscFunctionBegin;
5045   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5046   PetscValidType(mat,1);
5047   PetscValidHeaderSpecific(row,IS_COOKIE,2);
5048   PetscValidHeaderSpecific(col,IS_COOKIE,3);
5049   PetscValidPointer(info,4);
5050   PetscValidPointer(fact,5);
5051   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
5052   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5053   if (!mat->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",((PetscObject)mat)->type_name);
5054   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5055   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5056   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5057 
5058   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
5059   ierr = (*(*fact)->ops->ilufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
5060   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
5061   PetscFunctionReturn(0);
5062 }
5063 
5064 #undef __FUNCT__
5065 #define __FUNCT__ "MatICCFactorSymbolic"
5066 /*@
5067    MatICCFactorSymbolic - Performs symbolic incomplete
5068    Cholesky factorization for a symmetric matrix.  Use
5069    MatCholeskyFactorNumeric() to complete the factorization.
5070 
5071    Collective on Mat
5072 
5073    Input Parameters:
5074 +  mat - the matrix
5075 .  perm - row and column permutation
5076 -  info - structure containing
5077 $      levels - number of levels of fill.
5078 $      expected fill - as ratio of original fill.
5079 
5080    Output Parameter:
5081 .  fact - the factored matrix
5082 
5083    Notes:
5084    Most users should employ the KSP interface for linear solvers
5085    instead of working directly with matrix algebra routines such as this.
5086    See, e.g., KSPCreate().
5087 
5088    Level: developer
5089 
5090   Concepts: matrices^symbolic incomplete Cholesky factorization
5091   Concepts: matrices^factorization
5092   Concepts: Cholsky^symbolic factorization
5093 
5094 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
5095 @*/
5096 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactorSymbolic(Mat mat,IS perm,MatFactorInfo *info,Mat *fact)
5097 {
5098   PetscErrorCode ierr;
5099 
5100   PetscFunctionBegin;
5101   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5102   PetscValidType(mat,1);
5103   PetscValidHeaderSpecific(perm,IS_COOKIE,2);
5104   PetscValidPointer(info,3);
5105   PetscValidPointer(fact,4);
5106   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5107   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
5108   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5109   if (!mat->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",((PetscObject)mat)->type_name);
5110   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5111   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5112 
5113   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
5114   ierr = (*(*fact)->ops->iccfactorsymbolic)(mat,perm,info,fact);CHKERRQ(ierr);
5115   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
5116   PetscFunctionReturn(0);
5117 }
5118 
5119 #undef __FUNCT__
5120 #define __FUNCT__ "MatGetArray"
5121 /*@C
5122    MatGetArray - Returns a pointer to the element values in the matrix.
5123    The result of this routine is dependent on the underlying matrix data
5124    structure, and may not even work for certain matrix types.  You MUST
5125    call MatRestoreArray() when you no longer need to access the array.
5126 
5127    Not Collective
5128 
5129    Input Parameter:
5130 .  mat - the matrix
5131 
5132    Output Parameter:
5133 .  v - the location of the values
5134 
5135 
5136    Fortran Note:
5137    This routine is used differently from Fortran, e.g.,
5138 .vb
5139         Mat         mat
5140         PetscScalar mat_array(1)
5141         PetscOffset i_mat
5142         PetscErrorCode ierr
5143         call MatGetArray(mat,mat_array,i_mat,ierr)
5144 
5145   C  Access first local entry in matrix; note that array is
5146   C  treated as one dimensional
5147         value = mat_array(i_mat + 1)
5148 
5149         [... other code ...]
5150         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5151 .ve
5152 
5153    See the Fortran chapter of the users manual and
5154    petsc/src/mat/examples/tests for details.
5155 
5156    Level: advanced
5157 
5158    Concepts: matrices^access array
5159 
5160 .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
5161 @*/
5162 PetscErrorCode PETSCMAT_DLLEXPORT MatGetArray(Mat mat,PetscScalar *v[])
5163 {
5164   PetscErrorCode ierr;
5165 
5166   PetscFunctionBegin;
5167   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5168   PetscValidType(mat,1);
5169   PetscValidPointer(v,2);
5170   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5171   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5172   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
5173   CHKMEMQ;
5174   PetscFunctionReturn(0);
5175 }
5176 
5177 #undef __FUNCT__
5178 #define __FUNCT__ "MatRestoreArray"
5179 /*@C
5180    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
5181 
5182    Not Collective
5183 
5184    Input Parameter:
5185 +  mat - the matrix
5186 -  v - the location of the values
5187 
5188    Fortran Note:
5189    This routine is used differently from Fortran, e.g.,
5190 .vb
5191         Mat         mat
5192         PetscScalar mat_array(1)
5193         PetscOffset i_mat
5194         PetscErrorCode ierr
5195         call MatGetArray(mat,mat_array,i_mat,ierr)
5196 
5197   C  Access first local entry in matrix; note that array is
5198   C  treated as one dimensional
5199         value = mat_array(i_mat + 1)
5200 
5201         [... other code ...]
5202         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5203 .ve
5204 
5205    See the Fortran chapter of the users manual and
5206    petsc/src/mat/examples/tests for details
5207 
5208    Level: advanced
5209 
5210 .seealso: MatGetArray(), MatRestoreArrayF90()
5211 @*/
5212 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreArray(Mat mat,PetscScalar *v[])
5213 {
5214   PetscErrorCode ierr;
5215 
5216   PetscFunctionBegin;
5217   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5218   PetscValidType(mat,1);
5219   PetscValidPointer(v,2);
5220 #if defined(PETSC_USE_DEBUG)
5221   CHKMEMQ;
5222 #endif
5223   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5224   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
5225   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5226   PetscFunctionReturn(0);
5227 }
5228 
5229 #undef __FUNCT__
5230 #define __FUNCT__ "MatGetSubMatrices"
5231 /*@C
5232    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
5233    points to an array of valid matrices, they may be reused to store the new
5234    submatrices.
5235 
5236    Collective on Mat
5237 
5238    Input Parameters:
5239 +  mat - the matrix
5240 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
5241 .  irow, icol - index sets of rows and columns to extract
5242 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
5243 
5244    Output Parameter:
5245 .  submat - the array of submatrices
5246 
5247    Notes:
5248    MatGetSubMatrices() can extract ONLY sequential submatrices
5249    (from both sequential and parallel matrices). Use MatGetSubMatrix()
5250    to extract a parallel submatrix.
5251 
5252    When extracting submatrices from a parallel matrix, each processor can
5253    form a different submatrix by setting the rows and columns of its
5254    individual index sets according to the local submatrix desired.
5255 
5256    When finished using the submatrices, the user should destroy
5257    them with MatDestroyMatrices().
5258 
5259    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
5260    original matrix has not changed from that last call to MatGetSubMatrices().
5261 
5262    This routine creates the matrices in submat; you should NOT create them before
5263    calling it. It also allocates the array of matrix pointers submat.
5264 
5265    For BAIJ matrices the index sets must respect the block structure, that is if they
5266    request one row/column in a block, they must request all rows/columns that are in
5267    that block. For example, if the block size is 2 you cannot request just row 0 and
5268    column 0.
5269 
5270    Fortran Note:
5271    The Fortran interface is slightly different from that given below; it
5272    requires one to pass in  as submat a Mat (integer) array of size at least m.
5273 
5274    Level: advanced
5275 
5276    Concepts: matrices^accessing submatrices
5277    Concepts: submatrices
5278 
5279 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal()
5280 @*/
5281 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
5282 {
5283   PetscErrorCode ierr;
5284   PetscInt        i;
5285   PetscTruth      eq;
5286 
5287   PetscFunctionBegin;
5288   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5289   PetscValidType(mat,1);
5290   if (n) {
5291     PetscValidPointer(irow,3);
5292     PetscValidHeaderSpecific(*irow,IS_COOKIE,3);
5293     PetscValidPointer(icol,4);
5294     PetscValidHeaderSpecific(*icol,IS_COOKIE,4);
5295   }
5296   PetscValidPointer(submat,6);
5297   if (n && scall == MAT_REUSE_MATRIX) {
5298     PetscValidPointer(*submat,6);
5299     PetscValidHeaderSpecific(**submat,MAT_COOKIE,6);
5300   }
5301   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5302   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5303   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5304   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5305 
5306   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
5307   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
5308   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
5309   for (i=0; i<n; i++) {
5310     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
5311       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
5312       if (eq) {
5313 	if (mat->symmetric){
5314 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
5315 	} else if (mat->hermitian) {
5316 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
5317 	} else if (mat->structurally_symmetric) {
5318 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
5319 	}
5320       }
5321     }
5322   }
5323   PetscFunctionReturn(0);
5324 }
5325 
5326 #undef __FUNCT__
5327 #define __FUNCT__ "MatDestroyMatrices"
5328 /*@C
5329    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
5330 
5331    Collective on Mat
5332 
5333    Input Parameters:
5334 +  n - the number of local matrices
5335 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
5336                        sequence of MatGetSubMatrices())
5337 
5338    Level: advanced
5339 
5340     Notes: Frees not only the matrices, but also the array that contains the matrices
5341 
5342 .seealso: MatGetSubMatrices()
5343 @*/
5344 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroyMatrices(PetscInt n,Mat *mat[])
5345 {
5346   PetscErrorCode ierr;
5347   PetscInt       i;
5348 
5349   PetscFunctionBegin;
5350   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
5351   PetscValidPointer(mat,2);
5352   for (i=0; i<n; i++) {
5353     ierr = MatDestroy((*mat)[i]);CHKERRQ(ierr);
5354   }
5355   /* memory is allocated even if n = 0 */
5356   ierr = PetscFree(*mat);CHKERRQ(ierr);
5357   PetscFunctionReturn(0);
5358 }
5359 
5360 #undef __FUNCT__
5361 #define __FUNCT__ "MatGetSeqNonzeroStructure"
5362 /*@C
5363    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
5364 
5365    Collective on Mat
5366 
5367    Input Parameters:
5368 .  mat - the matrix
5369 
5370    Output Parameter:
5371 .  matstruct - the sequential matrix with the nonzero structure of mat
5372 
5373   Level: intermediate
5374 
5375 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
5376 @*/
5377 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct[])
5378 {
5379   PetscErrorCode ierr;
5380 
5381   PetscFunctionBegin;
5382   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5383   PetscValidPointer(matstruct,2);
5384 
5385   PetscValidType(mat,1);
5386   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5387   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5388 
5389   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
5390   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
5391   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
5392   PetscFunctionReturn(0);
5393 }
5394 
5395 #undef __FUNCT__
5396 #define __FUNCT__ "MatDestroySeqNonzeroStructure"
5397 /*@C
5398    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
5399 
5400    Collective on Mat
5401 
5402    Input Parameters:
5403 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
5404                        sequence of MatGetSequentialNonzeroStructure())
5405 
5406    Level: advanced
5407 
5408     Notes: Frees not only the matrices, but also the array that contains the matrices
5409 
5410 .seealso: MatGetSeqNonzeroStructure()
5411 @*/
5412 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroySeqNonzeroStructure(Mat *mat[])
5413 {
5414   PetscErrorCode ierr;
5415 
5416   PetscFunctionBegin;
5417   PetscValidPointer(mat,1);
5418   ierr = MatDestroyMatrices(1,mat);CHKERRQ(ierr);
5419   PetscFunctionReturn(0);
5420 }
5421 
5422 #undef __FUNCT__
5423 #define __FUNCT__ "MatIncreaseOverlap"
5424 /*@
5425    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
5426    replaces the index sets by larger ones that represent submatrices with
5427    additional overlap.
5428 
5429    Collective on Mat
5430 
5431    Input Parameters:
5432 +  mat - the matrix
5433 .  n   - the number of index sets
5434 .  is  - the array of index sets (these index sets will changed during the call)
5435 -  ov  - the additional overlap requested
5436 
5437    Level: developer
5438 
5439    Concepts: overlap
5440    Concepts: ASM^computing overlap
5441 
5442 .seealso: MatGetSubMatrices()
5443 @*/
5444 PetscErrorCode PETSCMAT_DLLEXPORT MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
5445 {
5446   PetscErrorCode ierr;
5447 
5448   PetscFunctionBegin;
5449   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5450   PetscValidType(mat,1);
5451   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
5452   if (n) {
5453     PetscValidPointer(is,3);
5454     PetscValidHeaderSpecific(*is,IS_COOKIE,3);
5455   }
5456   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5457   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5458   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5459 
5460   if (!ov) PetscFunctionReturn(0);
5461   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5462   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
5463   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
5464   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
5465   PetscFunctionReturn(0);
5466 }
5467 
5468 #undef __FUNCT__
5469 #define __FUNCT__ "MatGetBlockSize"
5470 /*@
5471    MatGetBlockSize - Returns the matrix block size; useful especially for the
5472    block row and block diagonal formats.
5473 
5474    Not Collective
5475 
5476    Input Parameter:
5477 .  mat - the matrix
5478 
5479    Output Parameter:
5480 .  bs - block size
5481 
5482    Notes:
5483    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
5484 
5485    Level: intermediate
5486 
5487    Concepts: matrices^block size
5488 
5489 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
5490 @*/
5491 PetscErrorCode PETSCMAT_DLLEXPORT MatGetBlockSize(Mat mat,PetscInt *bs)
5492 {
5493   PetscErrorCode ierr;
5494 
5495   PetscFunctionBegin;
5496   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5497   PetscValidType(mat,1);
5498   PetscValidIntPointer(bs,2);
5499   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5500   *bs = mat->rmap.bs;
5501   PetscFunctionReturn(0);
5502 }
5503 
5504 #undef __FUNCT__
5505 #define __FUNCT__ "MatSetBlockSize"
5506 /*@
5507    MatSetBlockSize - Sets the matrix block size; for many matrix types you
5508      cannot use this and MUST set the blocksize when you preallocate the matrix
5509 
5510    Collective on Mat
5511 
5512    Input Parameters:
5513 +  mat - the matrix
5514 -  bs - block size
5515 
5516    Notes:
5517      Only works for shell and AIJ matrices
5518 
5519    Level: intermediate
5520 
5521    Concepts: matrices^block size
5522 
5523 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
5524 @*/
5525 PetscErrorCode PETSCMAT_DLLEXPORT MatSetBlockSize(Mat mat,PetscInt bs)
5526 {
5527   PetscErrorCode ierr;
5528 
5529   PetscFunctionBegin;
5530   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5531   PetscValidType(mat,1);
5532   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5533   if (mat->ops->setblocksize) {
5534     mat->rmap.bs = bs;
5535     ierr = (*mat->ops->setblocksize)(mat,bs);CHKERRQ(ierr);
5536   } else {
5537     SETERRQ1(PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
5538   }
5539   PetscFunctionReturn(0);
5540 }
5541 
5542 #undef __FUNCT__
5543 #define __FUNCT__ "MatGetRowIJ"
5544 /*@C
5545     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
5546 
5547    Collective on Mat
5548 
5549     Input Parameters:
5550 +   mat - the matrix
5551 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
5552 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5553                 symmetrized
5554 -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5555                  blockcompressed matrix is desired or not [inode, baij have blockcompressed
5556                  nonzero structure which is different than the full nonzero structure]
5557 
5558     Output Parameters:
5559 +   n - number of rows in the (possibly compressed) matrix
5560 .   ia - the row pointers [of length n+1]
5561 .   ja - the column indices
5562 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
5563            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
5564 
5565     Level: developer
5566 
5567     Notes: You CANNOT change any of the ia[] or ja[] values.
5568 
5569            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
5570 
5571     Fortran Node
5572 
5573            In Fortran use
5574 $           PetscInt ia(1), ja(1)
5575 $           PetscOffset iia, jja
5576 $      call MatGetRowIJ(mat,shift,symmetric,blockcompressed,n,ia,iia,ja,jja,done,ierr)
5577 
5578        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
5579 
5580 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
5581 @*/
5582 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5583 {
5584   PetscErrorCode ierr;
5585 
5586   PetscFunctionBegin;
5587   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5588   PetscValidType(mat,1);
5589   PetscValidIntPointer(n,4);
5590   if (ia) PetscValidIntPointer(ia,5);
5591   if (ja) PetscValidIntPointer(ja,6);
5592   PetscValidIntPointer(done,7);
5593   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5594   if (!mat->ops->getrowij) *done = PETSC_FALSE;
5595   else {
5596     *done = PETSC_TRUE;
5597     ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
5598     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);CHKERRQ(ierr);
5599     ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
5600   }
5601   PetscFunctionReturn(0);
5602 }
5603 
5604 #undef __FUNCT__
5605 #define __FUNCT__ "MatGetColumnIJ"
5606 /*@C
5607     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
5608 
5609     Collective on Mat
5610 
5611     Input Parameters:
5612 +   mat - the matrix
5613 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5614 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5615                 symmetrized
5616 -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5617                  blockcompressed matrix is desired or not [inode, baij have blockcompressed
5618                  nonzero structure which is different than the full nonzero structure]
5619 
5620     Output Parameters:
5621 +   n - number of columns in the (possibly compressed) matrix
5622 .   ia - the column pointers
5623 .   ja - the row indices
5624 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
5625 
5626     Level: developer
5627 
5628 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5629 @*/
5630 PetscErrorCode PETSCMAT_DLLEXPORT MatGetColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5631 {
5632   PetscErrorCode ierr;
5633 
5634   PetscFunctionBegin;
5635   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5636   PetscValidType(mat,1);
5637   PetscValidIntPointer(n,4);
5638   if (ia) PetscValidIntPointer(ia,5);
5639   if (ja) PetscValidIntPointer(ja,6);
5640   PetscValidIntPointer(done,7);
5641   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5642   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
5643   else {
5644     *done = PETSC_TRUE;
5645     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);CHKERRQ(ierr);
5646   }
5647   PetscFunctionReturn(0);
5648 }
5649 
5650 #undef __FUNCT__
5651 #define __FUNCT__ "MatRestoreRowIJ"
5652 /*@C
5653     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
5654     MatGetRowIJ().
5655 
5656     Collective on Mat
5657 
5658     Input Parameters:
5659 +   mat - the matrix
5660 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5661 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5662                 symmetrized
5663 -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5664                  blockcompressed matrix is desired or not [inode, baij have blockcompressed
5665                  nonzero structure which is different than the full nonzero structure]
5666 
5667     Output Parameters:
5668 +   n - size of (possibly compressed) matrix
5669 .   ia - the row pointers
5670 .   ja - the column indices
5671 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5672 
5673     Level: developer
5674 
5675 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5676 @*/
5677 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5678 {
5679   PetscErrorCode ierr;
5680 
5681   PetscFunctionBegin;
5682   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5683   PetscValidType(mat,1);
5684   if (ia) PetscValidIntPointer(ia,5);
5685   if (ja) PetscValidIntPointer(ja,6);
5686   PetscValidIntPointer(done,7);
5687   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5688 
5689   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
5690   else {
5691     *done = PETSC_TRUE;
5692     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);CHKERRQ(ierr);
5693   }
5694   PetscFunctionReturn(0);
5695 }
5696 
5697 #undef __FUNCT__
5698 #define __FUNCT__ "MatRestoreColumnIJ"
5699 /*@C
5700     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
5701     MatGetColumnIJ().
5702 
5703     Collective on Mat
5704 
5705     Input Parameters:
5706 +   mat - the matrix
5707 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5708 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5709                 symmetrized
5710 -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5711                  blockcompressed matrix is desired or not [inode, baij have blockcompressed
5712                  nonzero structure which is different than the full nonzero structure]
5713 
5714     Output Parameters:
5715 +   n - size of (possibly compressed) matrix
5716 .   ia - the column pointers
5717 .   ja - the row indices
5718 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5719 
5720     Level: developer
5721 
5722 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
5723 @*/
5724 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5725 {
5726   PetscErrorCode ierr;
5727 
5728   PetscFunctionBegin;
5729   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5730   PetscValidType(mat,1);
5731   if (ia) PetscValidIntPointer(ia,5);
5732   if (ja) PetscValidIntPointer(ja,6);
5733   PetscValidIntPointer(done,7);
5734   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5735 
5736   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
5737   else {
5738     *done = PETSC_TRUE;
5739     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);CHKERRQ(ierr);
5740   }
5741   PetscFunctionReturn(0);
5742 }
5743 
5744 #undef __FUNCT__
5745 #define __FUNCT__ "MatColoringPatch"
5746 /*@C
5747     MatColoringPatch -Used inside matrix coloring routines that
5748     use MatGetRowIJ() and/or MatGetColumnIJ().
5749 
5750     Collective on Mat
5751 
5752     Input Parameters:
5753 +   mat - the matrix
5754 .   ncolors - max color value
5755 .   n   - number of entries in colorarray
5756 -   colorarray - array indicating color for each column
5757 
5758     Output Parameters:
5759 .   iscoloring - coloring generated using colorarray information
5760 
5761     Level: developer
5762 
5763 .seealso: MatGetRowIJ(), MatGetColumnIJ()
5764 
5765 @*/
5766 PetscErrorCode PETSCMAT_DLLEXPORT MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
5767 {
5768   PetscErrorCode ierr;
5769 
5770   PetscFunctionBegin;
5771   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5772   PetscValidType(mat,1);
5773   PetscValidIntPointer(colorarray,4);
5774   PetscValidPointer(iscoloring,5);
5775   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5776 
5777   if (!mat->ops->coloringpatch){
5778     ierr = ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
5779   } else {
5780     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
5781   }
5782   PetscFunctionReturn(0);
5783 }
5784 
5785 
5786 #undef __FUNCT__
5787 #define __FUNCT__ "MatSetUnfactored"
5788 /*@
5789    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
5790 
5791    Collective on Mat
5792 
5793    Input Parameter:
5794 .  mat - the factored matrix to be reset
5795 
5796    Notes:
5797    This routine should be used only with factored matrices formed by in-place
5798    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
5799    format).  This option can save memory, for example, when solving nonlinear
5800    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
5801    ILU(0) preconditioner.
5802 
5803    Note that one can specify in-place ILU(0) factorization by calling
5804 .vb
5805      PCType(pc,PCILU);
5806      PCFactorSeUseInPlace(pc);
5807 .ve
5808    or by using the options -pc_type ilu -pc_factor_in_place
5809 
5810    In-place factorization ILU(0) can also be used as a local
5811    solver for the blocks within the block Jacobi or additive Schwarz
5812    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
5813    of these preconditioners in the users manual for details on setting
5814    local solver options.
5815 
5816    Most users should employ the simplified KSP interface for linear solvers
5817    instead of working directly with matrix algebra routines such as this.
5818    See, e.g., KSPCreate().
5819 
5820    Level: developer
5821 
5822 .seealso: PCFactorSetUseInPlace()
5823 
5824    Concepts: matrices^unfactored
5825 
5826 @*/
5827 PetscErrorCode PETSCMAT_DLLEXPORT MatSetUnfactored(Mat mat)
5828 {
5829   PetscErrorCode ierr;
5830 
5831   PetscFunctionBegin;
5832   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5833   PetscValidType(mat,1);
5834   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5835   mat->factor = MAT_FACTOR_NONE;
5836   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
5837   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
5838   PetscFunctionReturn(0);
5839 }
5840 
5841 /*MC
5842     MatGetArrayF90 - Accesses a matrix array from Fortran90.
5843 
5844     Synopsis:
5845     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
5846 
5847     Not collective
5848 
5849     Input Parameter:
5850 .   x - matrix
5851 
5852     Output Parameters:
5853 +   xx_v - the Fortran90 pointer to the array
5854 -   ierr - error code
5855 
5856     Example of Usage:
5857 .vb
5858       PetscScalar, pointer xx_v(:)
5859       ....
5860       call MatGetArrayF90(x,xx_v,ierr)
5861       a = xx_v(3)
5862       call MatRestoreArrayF90(x,xx_v,ierr)
5863 .ve
5864 
5865     Notes:
5866     Not yet supported for all F90 compilers
5867 
5868     Level: advanced
5869 
5870 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
5871 
5872     Concepts: matrices^accessing array
5873 
5874 M*/
5875 
5876 /*MC
5877     MatRestoreArrayF90 - Restores a matrix array that has been
5878     accessed with MatGetArrayF90().
5879 
5880     Synopsis:
5881     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
5882 
5883     Not collective
5884 
5885     Input Parameters:
5886 +   x - matrix
5887 -   xx_v - the Fortran90 pointer to the array
5888 
5889     Output Parameter:
5890 .   ierr - error code
5891 
5892     Example of Usage:
5893 .vb
5894        PetscScalar, pointer xx_v(:)
5895        ....
5896        call MatGetArrayF90(x,xx_v,ierr)
5897        a = xx_v(3)
5898        call MatRestoreArrayF90(x,xx_v,ierr)
5899 .ve
5900 
5901     Notes:
5902     Not yet supported for all F90 compilers
5903 
5904     Level: advanced
5905 
5906 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
5907 
5908 M*/
5909 
5910 
5911 #undef __FUNCT__
5912 #define __FUNCT__ "MatGetSubMatrix"
5913 /*@
5914     MatGetSubMatrix - Gets a single submatrix on the same number of processors
5915                       as the original matrix.
5916 
5917     Collective on Mat
5918 
5919     Input Parameters:
5920 +   mat - the original matrix
5921 .   isrow - rows this processor should obtain
5922 .   iscol - columns for all processors you wish to keep
5923 .   csize - number of columns "local" to this processor (does nothing for sequential
5924             matrices). This should match the result from VecGetLocalSize(x,...) if you
5925             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
5926 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
5927 
5928     Output Parameter:
5929 .   newmat - the new submatrix, of the same type as the old
5930 
5931     Level: advanced
5932 
5933     Notes: the iscol argument MUST be the same on each processor. You might be
5934     able to create the iscol argument with ISAllGather(). The rows is isrow will be
5935     sorted into the same order as the original matrix.
5936 
5937       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
5938    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
5939    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
5940    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
5941    you are finished using it.
5942 
5943     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
5944     the input matrix.
5945 
5946     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran), you should
5947     use csize = PETSC_DECIDE also in this case.
5948 
5949     Concepts: matrices^submatrices
5950 
5951 .seealso: MatGetSubMatrices(), ISAllGather()
5952 @*/
5953 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrix(Mat mat,IS isrow,IS iscol,PetscInt csize,MatReuse cll,Mat *newmat)
5954 {
5955   PetscErrorCode ierr;
5956   PetscMPIInt    size;
5957   Mat            *local;
5958   IS             iscoltmp;
5959 
5960   PetscFunctionBegin;
5961   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5962   PetscValidHeaderSpecific(isrow,IS_COOKIE,2);
5963   if (iscol) PetscValidHeaderSpecific(iscol,IS_COOKIE,3);
5964   PetscValidPointer(newmat,6);
5965   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_COOKIE,6);
5966   PetscValidType(mat,1);
5967   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5968   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5969   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5970 
5971   if (!iscol) {
5972     if (csize == PETSC_DECIDE) csize = mat->cmap.n;
5973     ierr = ISCreateStride(((PetscObject)mat)->comm,mat->cmap.N,0,1,&iscoltmp);CHKERRQ(ierr);
5974   } else {
5975     iscoltmp = iscol;
5976   }
5977 
5978   /* if original matrix is on just one processor then use submatrix generated */
5979   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
5980     ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
5981     PetscFunctionReturn(0);
5982   } else if (!mat->ops->getsubmatrix && size == 1) {
5983     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
5984     *newmat = *local;
5985     ierr    = PetscFree(local);CHKERRQ(ierr);
5986     if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
5987     PetscFunctionReturn(0);
5988   }
5989 
5990   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5991   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,csize,cll,newmat);CHKERRQ(ierr);
5992   if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
5993   ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);
5994   PetscFunctionReturn(0);
5995 }
5996 
5997 #undef __FUNCT__
5998 #define __FUNCT__ "MatGetSubMatrixRaw"
5999 /*@
6000     MatGetSubMatrixRaw - Gets a single submatrix on the same number of processors
6001                          as the original matrix.
6002 
6003     Collective on Mat
6004 
6005     Input Parameters:
6006 +   mat - the original matrix
6007 .   nrows - the number of rows this processor should obtain
6008 .   rows - rows this processor should obtain
6009 .   ncols - the number of columns for all processors you wish to keep
6010 .   cols - columns for all processors you wish to keep
6011 .   csize - number of columns "local" to this processor (does nothing for sequential
6012             matrices). This should match the result from VecGetLocalSize(x,...) if you
6013             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
6014 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6015 
6016     Output Parameter:
6017 .   newmat - the new submatrix, of the same type as the old
6018 
6019     Level: advanced
6020 
6021     Notes: the iscol argument MUST be the same on each processor. You might be
6022     able to create the iscol argument with ISAllGather().
6023 
6024       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
6025    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
6026    to this routine with a mat of the same nonzero structure and with a cll of MAT_REUSE_MATRIX
6027    will reuse the matrix generated the first time.
6028 
6029     Concepts: matrices^submatrices
6030 
6031 .seealso: MatGetSubMatrices(), ISAllGather()
6032 @*/
6033 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrixRaw(Mat mat,PetscInt nrows,const PetscInt rows[],PetscInt ncols,const PetscInt cols[],PetscInt csize,MatReuse cll,Mat *newmat)
6034 {
6035   IS             isrow, iscol;
6036   PetscErrorCode ierr;
6037 
6038   PetscFunctionBegin;
6039   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6040   PetscValidIntPointer(rows,2);
6041   PetscValidIntPointer(cols,3);
6042   PetscValidPointer(newmat,6);
6043   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_COOKIE,6);
6044   PetscValidType(mat,1);
6045   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6046   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6047   ierr = ISCreateGeneralWithArray(PETSC_COMM_SELF, nrows, (PetscInt *) rows, &isrow);CHKERRQ(ierr);
6048   ierr = ISCreateGeneralWithArray(PETSC_COMM_SELF, ncols, (PetscInt *) cols, &iscol);CHKERRQ(ierr);
6049   ierr = MatGetSubMatrix(mat, isrow, iscol, csize, cll, newmat);CHKERRQ(ierr);
6050   ierr = ISDestroy(isrow);CHKERRQ(ierr);
6051   ierr = ISDestroy(iscol);CHKERRQ(ierr);
6052   PetscFunctionReturn(0);
6053 }
6054 
6055 #undef __FUNCT__
6056 #define __FUNCT__ "MatStashSetInitialSize"
6057 /*@
6058    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
6059    used during the assembly process to store values that belong to
6060    other processors.
6061 
6062    Not Collective
6063 
6064    Input Parameters:
6065 +  mat   - the matrix
6066 .  size  - the initial size of the stash.
6067 -  bsize - the initial size of the block-stash(if used).
6068 
6069    Options Database Keys:
6070 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
6071 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
6072 
6073    Level: intermediate
6074 
6075    Notes:
6076      The block-stash is used for values set with MatSetValuesBlocked() while
6077      the stash is used for values set with MatSetValues()
6078 
6079      Run with the option -info and look for output of the form
6080      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
6081      to determine the appropriate value, MM, to use for size and
6082      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
6083      to determine the value, BMM to use for bsize
6084 
6085    Concepts: stash^setting matrix size
6086    Concepts: matrices^stash
6087 
6088 @*/
6089 PetscErrorCode PETSCMAT_DLLEXPORT MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
6090 {
6091   PetscErrorCode ierr;
6092 
6093   PetscFunctionBegin;
6094   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6095   PetscValidType(mat,1);
6096   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
6097   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
6098   PetscFunctionReturn(0);
6099 }
6100 
6101 #undef __FUNCT__
6102 #define __FUNCT__ "MatInterpolateAdd"
6103 /*@
6104    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
6105      the matrix
6106 
6107    Collective on Mat
6108 
6109    Input Parameters:
6110 +  mat   - the matrix
6111 .  x,y - the vectors
6112 -  w - where the result is stored
6113 
6114    Level: intermediate
6115 
6116    Notes:
6117     w may be the same vector as y.
6118 
6119     This allows one to use either the restriction or interpolation (its transpose)
6120     matrix to do the interpolation
6121 
6122     Concepts: interpolation
6123 
6124 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6125 
6126 @*/
6127 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
6128 {
6129   PetscErrorCode ierr;
6130   PetscInt       M,N;
6131 
6132   PetscFunctionBegin;
6133   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6134   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
6135   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
6136   PetscValidHeaderSpecific(w,VEC_COOKIE,4);
6137   PetscValidType(A,1);
6138   ierr = MatPreallocated(A);CHKERRQ(ierr);
6139   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6140   if (N > M) {
6141     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
6142   } else {
6143     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
6144   }
6145   PetscFunctionReturn(0);
6146 }
6147 
6148 #undef __FUNCT__
6149 #define __FUNCT__ "MatInterpolate"
6150 /*@
6151    MatInterpolate - y = A*x or A'*x depending on the shape of
6152      the matrix
6153 
6154    Collective on Mat
6155 
6156    Input Parameters:
6157 +  mat   - the matrix
6158 -  x,y - the vectors
6159 
6160    Level: intermediate
6161 
6162    Notes:
6163     This allows one to use either the restriction or interpolation (its transpose)
6164     matrix to do the interpolation
6165 
6166    Concepts: matrices^interpolation
6167 
6168 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6169 
6170 @*/
6171 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolate(Mat A,Vec x,Vec y)
6172 {
6173   PetscErrorCode ierr;
6174   PetscInt       M,N;
6175 
6176   PetscFunctionBegin;
6177   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6178   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
6179   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
6180   PetscValidType(A,1);
6181   ierr = MatPreallocated(A);CHKERRQ(ierr);
6182   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6183   if (N > M) {
6184     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
6185   } else {
6186     ierr = MatMult(A,x,y);CHKERRQ(ierr);
6187   }
6188   PetscFunctionReturn(0);
6189 }
6190 
6191 #undef __FUNCT__
6192 #define __FUNCT__ "MatRestrict"
6193 /*@
6194    MatRestrict - y = A*x or A'*x
6195 
6196    Collective on Mat
6197 
6198    Input Parameters:
6199 +  mat   - the matrix
6200 -  x,y - the vectors
6201 
6202    Level: intermediate
6203 
6204    Notes:
6205     This allows one to use either the restriction or interpolation (its transpose)
6206     matrix to do the restriction
6207 
6208    Concepts: matrices^restriction
6209 
6210 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
6211 
6212 @*/
6213 PetscErrorCode PETSCMAT_DLLEXPORT MatRestrict(Mat A,Vec x,Vec y)
6214 {
6215   PetscErrorCode ierr;
6216   PetscInt       M,N;
6217 
6218   PetscFunctionBegin;
6219   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6220   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
6221   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
6222   PetscValidType(A,1);
6223   ierr = MatPreallocated(A);CHKERRQ(ierr);
6224 
6225   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6226   if (N > M) {
6227     ierr = MatMult(A,x,y);CHKERRQ(ierr);
6228   } else {
6229     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
6230   }
6231   PetscFunctionReturn(0);
6232 }
6233 
6234 #undef __FUNCT__
6235 #define __FUNCT__ "MatNullSpaceAttach"
6236 /*@
6237    MatNullSpaceAttach - attaches a null space to a matrix.
6238         This null space will be removed from the resulting vector whenever
6239         MatMult() is called
6240 
6241    Collective on Mat
6242 
6243    Input Parameters:
6244 +  mat - the matrix
6245 -  nullsp - the null space object
6246 
6247    Level: developer
6248 
6249    Notes:
6250       Overwrites any previous null space that may have been attached
6251 
6252    Concepts: null space^attaching to matrix
6253 
6254 .seealso: MatCreate(), MatNullSpaceCreate()
6255 @*/
6256 PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
6257 {
6258   PetscErrorCode ierr;
6259 
6260   PetscFunctionBegin;
6261   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6262   PetscValidType(mat,1);
6263   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_COOKIE,2);
6264   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6265   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
6266   if (mat->nullsp) { ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr); }
6267   mat->nullsp = nullsp;
6268   PetscFunctionReturn(0);
6269 }
6270 
6271 #undef __FUNCT__
6272 #define __FUNCT__ "MatICCFactor"
6273 /*@
6274    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
6275 
6276    Collective on Mat
6277 
6278    Input Parameters:
6279 +  mat - the matrix
6280 .  row - row/column permutation
6281 .  fill - expected fill factor >= 1.0
6282 -  level - level of fill, for ICC(k)
6283 
6284    Notes:
6285    Probably really in-place only when level of fill is zero, otherwise allocates
6286    new space to store factored matrix and deletes previous memory.
6287 
6288    Most users should employ the simplified KSP interface for linear solvers
6289    instead of working directly with matrix algebra routines such as this.
6290    See, e.g., KSPCreate().
6291 
6292    Level: developer
6293 
6294    Concepts: matrices^incomplete Cholesky factorization
6295    Concepts: Cholesky factorization
6296 
6297 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6298 @*/
6299 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactor(Mat mat,IS row,MatFactorInfo* info)
6300 {
6301   PetscErrorCode ierr;
6302 
6303   PetscFunctionBegin;
6304   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6305   PetscValidType(mat,1);
6306   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
6307   PetscValidPointer(info,3);
6308   if (mat->rmap.N != mat->cmap.N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
6309   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6310   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6311   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6312   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6313   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
6314   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6315   PetscFunctionReturn(0);
6316 }
6317 
6318 #undef __FUNCT__
6319 #define __FUNCT__ "MatSetValuesAdic"
6320 /*@
6321    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
6322 
6323    Not Collective
6324 
6325    Input Parameters:
6326 +  mat - the matrix
6327 -  v - the values compute with ADIC
6328 
6329    Level: developer
6330 
6331    Notes:
6332      Must call MatSetColoring() before using this routine. Also this matrix must already
6333      have its nonzero pattern determined.
6334 
6335 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6336           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
6337 @*/
6338 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdic(Mat mat,void *v)
6339 {
6340   PetscErrorCode ierr;
6341 
6342   PetscFunctionBegin;
6343   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6344   PetscValidType(mat,1);
6345   PetscValidPointer(mat,2);
6346 
6347   if (!mat->assembled) {
6348     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6349   }
6350   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6351   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6352   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
6353   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6354   ierr = MatView_Private(mat);CHKERRQ(ierr);
6355   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6356   PetscFunctionReturn(0);
6357 }
6358 
6359 
6360 #undef __FUNCT__
6361 #define __FUNCT__ "MatSetColoring"
6362 /*@
6363    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
6364 
6365    Not Collective
6366 
6367    Input Parameters:
6368 +  mat - the matrix
6369 -  coloring - the coloring
6370 
6371    Level: developer
6372 
6373 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6374           MatSetValues(), MatSetValuesAdic()
6375 @*/
6376 PetscErrorCode PETSCMAT_DLLEXPORT MatSetColoring(Mat mat,ISColoring coloring)
6377 {
6378   PetscErrorCode ierr;
6379 
6380   PetscFunctionBegin;
6381   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6382   PetscValidType(mat,1);
6383   PetscValidPointer(coloring,2);
6384 
6385   if (!mat->assembled) {
6386     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6387   }
6388   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6389   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
6390   PetscFunctionReturn(0);
6391 }
6392 
6393 #undef __FUNCT__
6394 #define __FUNCT__ "MatSetValuesAdifor"
6395 /*@
6396    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
6397 
6398    Not Collective
6399 
6400    Input Parameters:
6401 +  mat - the matrix
6402 .  nl - leading dimension of v
6403 -  v - the values compute with ADIFOR
6404 
6405    Level: developer
6406 
6407    Notes:
6408      Must call MatSetColoring() before using this routine. Also this matrix must already
6409      have its nonzero pattern determined.
6410 
6411 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6412           MatSetValues(), MatSetColoring()
6413 @*/
6414 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
6415 {
6416   PetscErrorCode ierr;
6417 
6418   PetscFunctionBegin;
6419   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6420   PetscValidType(mat,1);
6421   PetscValidPointer(v,3);
6422 
6423   if (!mat->assembled) {
6424     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6425   }
6426   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6427   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6428   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
6429   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6430   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6431   PetscFunctionReturn(0);
6432 }
6433 
6434 #undef __FUNCT__
6435 #define __FUNCT__ "MatDiagonalScaleLocal"
6436 /*@
6437    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
6438          ghosted ones.
6439 
6440    Not Collective
6441 
6442    Input Parameters:
6443 +  mat - the matrix
6444 -  diag = the diagonal values, including ghost ones
6445 
6446    Level: developer
6447 
6448    Notes: Works only for MPIAIJ and MPIBAIJ matrices
6449 
6450 .seealso: MatDiagonalScale()
6451 @*/
6452 PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalScaleLocal(Mat mat,Vec diag)
6453 {
6454   PetscErrorCode ierr;
6455   PetscMPIInt    size;
6456 
6457   PetscFunctionBegin;
6458   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6459   PetscValidHeaderSpecific(diag,VEC_COOKIE,2);
6460   PetscValidType(mat,1);
6461 
6462   if (!mat->assembled) {
6463     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6464   }
6465   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
6466   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
6467   if (size == 1) {
6468     PetscInt n,m;
6469     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
6470     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
6471     if (m == n) {
6472       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
6473     } else {
6474       SETERRQ(PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
6475     }
6476   } else {
6477     PetscErrorCode (*f)(Mat,Vec);
6478     ierr = PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);CHKERRQ(ierr);
6479     if (f) {
6480       ierr = (*f)(mat,diag);CHKERRQ(ierr);
6481     } else {
6482       SETERRQ(PETSC_ERR_SUP,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
6483     }
6484   }
6485   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
6486   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6487   PetscFunctionReturn(0);
6488 }
6489 
6490 #undef __FUNCT__
6491 #define __FUNCT__ "MatGetInertia"
6492 /*@
6493    MatGetInertia - Gets the inertia from a factored matrix
6494 
6495    Collective on Mat
6496 
6497    Input Parameter:
6498 .  mat - the matrix
6499 
6500    Output Parameters:
6501 +   nneg - number of negative eigenvalues
6502 .   nzero - number of zero eigenvalues
6503 -   npos - number of positive eigenvalues
6504 
6505    Level: advanced
6506 
6507    Notes: Matrix must have been factored by MatCholeskyFactor()
6508 
6509 
6510 @*/
6511 PetscErrorCode PETSCMAT_DLLEXPORT MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
6512 {
6513   PetscErrorCode ierr;
6514 
6515   PetscFunctionBegin;
6516   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6517   PetscValidType(mat,1);
6518   if (!mat->factor)    SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6519   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
6520   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6521   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
6522   PetscFunctionReturn(0);
6523 }
6524 
6525 /* ----------------------------------------------------------------*/
6526 #undef __FUNCT__
6527 #define __FUNCT__ "MatSolves"
6528 /*@
6529    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
6530 
6531    Collective on Mat and Vecs
6532 
6533    Input Parameters:
6534 +  mat - the factored matrix
6535 -  b - the right-hand-side vectors
6536 
6537    Output Parameter:
6538 .  x - the result vectors
6539 
6540    Notes:
6541    The vectors b and x cannot be the same.  I.e., one cannot
6542    call MatSolves(A,x,x).
6543 
6544    Notes:
6545    Most users should employ the simplified KSP interface for linear solvers
6546    instead of working directly with matrix algebra routines such as this.
6547    See, e.g., KSPCreate().
6548 
6549    Level: developer
6550 
6551    Concepts: matrices^triangular solves
6552 
6553 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
6554 @*/
6555 PetscErrorCode PETSCMAT_DLLEXPORT MatSolves(Mat mat,Vecs b,Vecs x)
6556 {
6557   PetscErrorCode ierr;
6558 
6559   PetscFunctionBegin;
6560   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6561   PetscValidType(mat,1);
6562   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
6563   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6564   if (!mat->rmap.N && !mat->cmap.N) PetscFunctionReturn(0);
6565 
6566   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6567   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6568   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
6569   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
6570   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
6571   PetscFunctionReturn(0);
6572 }
6573 
6574 #undef __FUNCT__
6575 #define __FUNCT__ "MatIsSymmetric"
6576 /*@
6577    MatIsSymmetric - Test whether a matrix is symmetric
6578 
6579    Collective on Mat
6580 
6581    Input Parameter:
6582 +  A - the matrix to test
6583 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
6584 
6585    Output Parameters:
6586 .  flg - the result
6587 
6588    Level: intermediate
6589 
6590    Concepts: matrix^symmetry
6591 
6592 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6593 @*/
6594 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetric(Mat A,PetscReal tol,PetscTruth *flg)
6595 {
6596   PetscErrorCode ierr;
6597 
6598   PetscFunctionBegin;
6599   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6600   PetscValidPointer(flg,2);
6601   if (!A->symmetric_set) {
6602     if (!A->ops->issymmetric) {
6603       const MatType mattype;
6604       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
6605       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
6606     }
6607     ierr = (*A->ops->issymmetric)(A,tol,&A->symmetric);CHKERRQ(ierr);
6608     A->symmetric_set = PETSC_TRUE;
6609     if (A->symmetric) {
6610       A->structurally_symmetric_set = PETSC_TRUE;
6611       A->structurally_symmetric     = PETSC_TRUE;
6612     }
6613   }
6614   *flg = A->symmetric;
6615   PetscFunctionReturn(0);
6616 }
6617 
6618 #undef __FUNCT__
6619 #define __FUNCT__ "MatIsHermitian"
6620 /*@
6621    MatIsHermitian - Test whether a matrix is Hermitian
6622 
6623    Collective on Mat
6624 
6625    Input Parameter:
6626 +  A - the matrix to test
6627 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
6628 
6629    Output Parameters:
6630 .  flg - the result
6631 
6632    Level: intermediate
6633 
6634    Concepts: matrix^symmetry
6635 
6636 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6637 @*/
6638 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitian(Mat A,PetscReal tol,PetscTruth *flg)
6639 {
6640   PetscErrorCode ierr;
6641 
6642   PetscFunctionBegin;
6643   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6644   PetscValidPointer(flg,2);
6645   if (!A->hermitian_set) {
6646     if (!A->ops->ishermitian) {
6647       const MatType mattype;
6648       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
6649       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for Hermitian",mattype);
6650     }
6651     ierr = (*A->ops->ishermitian)(A,tol,&A->hermitian);CHKERRQ(ierr);
6652     A->hermitian_set = PETSC_TRUE;
6653     if (A->hermitian) {
6654       A->structurally_symmetric_set = PETSC_TRUE;
6655       A->structurally_symmetric     = PETSC_TRUE;
6656     }
6657   }
6658   *flg = A->hermitian;
6659   PetscFunctionReturn(0);
6660 }
6661 
6662 #undef __FUNCT__
6663 #define __FUNCT__ "MatIsSymmetricKnown"
6664 /*@
6665    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
6666 
6667    Collective on Mat
6668 
6669    Input Parameter:
6670 .  A - the matrix to check
6671 
6672    Output Parameters:
6673 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
6674 -  flg - the result
6675 
6676    Level: advanced
6677 
6678    Concepts: matrix^symmetry
6679 
6680    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
6681          if you want it explicitly checked
6682 
6683 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6684 @*/
6685 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetricKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6686 {
6687   PetscFunctionBegin;
6688   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6689   PetscValidPointer(set,2);
6690   PetscValidPointer(flg,3);
6691   if (A->symmetric_set) {
6692     *set = PETSC_TRUE;
6693     *flg = A->symmetric;
6694   } else {
6695     *set = PETSC_FALSE;
6696   }
6697   PetscFunctionReturn(0);
6698 }
6699 
6700 #undef __FUNCT__
6701 #define __FUNCT__ "MatIsHermitianKnown"
6702 /*@
6703    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
6704 
6705    Collective on Mat
6706 
6707    Input Parameter:
6708 .  A - the matrix to check
6709 
6710    Output Parameters:
6711 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
6712 -  flg - the result
6713 
6714    Level: advanced
6715 
6716    Concepts: matrix^symmetry
6717 
6718    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
6719          if you want it explicitly checked
6720 
6721 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6722 @*/
6723 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitianKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6724 {
6725   PetscFunctionBegin;
6726   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6727   PetscValidPointer(set,2);
6728   PetscValidPointer(flg,3);
6729   if (A->hermitian_set) {
6730     *set = PETSC_TRUE;
6731     *flg = A->hermitian;
6732   } else {
6733     *set = PETSC_FALSE;
6734   }
6735   PetscFunctionReturn(0);
6736 }
6737 
6738 #undef __FUNCT__
6739 #define __FUNCT__ "MatIsStructurallySymmetric"
6740 /*@
6741    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
6742 
6743    Collective on Mat
6744 
6745    Input Parameter:
6746 .  A - the matrix to test
6747 
6748    Output Parameters:
6749 .  flg - the result
6750 
6751    Level: intermediate
6752 
6753    Concepts: matrix^symmetry
6754 
6755 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
6756 @*/
6757 PetscErrorCode PETSCMAT_DLLEXPORT MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
6758 {
6759   PetscErrorCode ierr;
6760 
6761   PetscFunctionBegin;
6762   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6763   PetscValidPointer(flg,2);
6764   if (!A->structurally_symmetric_set) {
6765     if (!A->ops->isstructurallysymmetric) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
6766     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
6767     A->structurally_symmetric_set = PETSC_TRUE;
6768   }
6769   *flg = A->structurally_symmetric;
6770   PetscFunctionReturn(0);
6771 }
6772 
6773 #undef __FUNCT__
6774 #define __FUNCT__ "MatStashGetInfo"
6775 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
6776 /*@
6777    MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
6778        to be communicated to other processors during the MatAssemblyBegin/End() process
6779 
6780     Not collective
6781 
6782    Input Parameter:
6783 .   vec - the vector
6784 
6785    Output Parameters:
6786 +   nstash   - the size of the stash
6787 .   reallocs - the number of additional mallocs incurred.
6788 .   bnstash   - the size of the block stash
6789 -   breallocs - the number of additional mallocs incurred.in the block stash
6790 
6791    Level: advanced
6792 
6793 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
6794 
6795 @*/
6796 PetscErrorCode PETSCMAT_DLLEXPORT MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
6797 {
6798   PetscErrorCode ierr;
6799   PetscFunctionBegin;
6800   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
6801   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
6802   PetscFunctionReturn(0);
6803 }
6804 
6805 #undef __FUNCT__
6806 #define __FUNCT__ "MatGetVecs"
6807 /*@C
6808    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
6809      parallel layout
6810 
6811    Collective on Mat
6812 
6813    Input Parameter:
6814 .  mat - the matrix
6815 
6816    Output Parameter:
6817 +   right - (optional) vector that the matrix can be multiplied against
6818 -   left - (optional) vector that the matrix vector product can be stored in
6819 
6820   Level: advanced
6821 
6822 .seealso: MatCreate()
6823 @*/
6824 PetscErrorCode PETSCMAT_DLLEXPORT MatGetVecs(Mat mat,Vec *right,Vec *left)
6825 {
6826   PetscErrorCode ierr;
6827 
6828   PetscFunctionBegin;
6829   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6830   PetscValidType(mat,1);
6831   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6832   if (mat->ops->getvecs) {
6833     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
6834   } else {
6835     PetscMPIInt size;
6836     ierr = MPI_Comm_size(((PetscObject)mat)->comm, &size);CHKERRQ(ierr);
6837     if (right) {
6838       ierr = VecCreate(((PetscObject)mat)->comm,right);CHKERRQ(ierr);
6839       ierr = VecSetSizes(*right,mat->cmap.n,PETSC_DETERMINE);CHKERRQ(ierr);
6840       if (size > 1) {ierr = VecSetType(*right,VECMPI);CHKERRQ(ierr);}
6841       else {ierr = VecSetType(*right,VECSEQ);CHKERRQ(ierr);}
6842     }
6843     if (left) {
6844       ierr = VecCreate(((PetscObject)mat)->comm,left);CHKERRQ(ierr);
6845       ierr = VecSetSizes(*left,mat->rmap.n,PETSC_DETERMINE);CHKERRQ(ierr);
6846       if (size > 1) {ierr = VecSetType(*left,VECMPI);CHKERRQ(ierr);}
6847       else {ierr = VecSetType(*left,VECSEQ);CHKERRQ(ierr);}
6848     }
6849   }
6850   if (right) {ierr = VecSetBlockSize(*right,mat->rmap.bs);CHKERRQ(ierr);}
6851   if (left) {ierr = VecSetBlockSize(*left,mat->rmap.bs);CHKERRQ(ierr);}
6852   if (mat->mapping) {
6853     if (right) {ierr = VecSetLocalToGlobalMapping(*right,mat->mapping);CHKERRQ(ierr);}
6854     if (left) {ierr = VecSetLocalToGlobalMapping(*left,mat->mapping);CHKERRQ(ierr);}
6855   }
6856   if (mat->bmapping) {
6857     if (right) {ierr = VecSetLocalToGlobalMappingBlock(*right,mat->bmapping);CHKERRQ(ierr);}
6858     if (left) {ierr = VecSetLocalToGlobalMappingBlock(*left,mat->bmapping);CHKERRQ(ierr);}
6859   }
6860   PetscFunctionReturn(0);
6861 }
6862 
6863 #undef __FUNCT__
6864 #define __FUNCT__ "MatFactorInfoInitialize"
6865 /*@
6866    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
6867      with default values.
6868 
6869    Not Collective
6870 
6871    Input Parameters:
6872 .    info - the MatFactorInfo data structure
6873 
6874 
6875    Notes: The solvers are generally used through the KSP and PC objects, for example
6876           PCLU, PCILU, PCCHOLESKY, PCICC
6877 
6878    Level: developer
6879 
6880 .seealso: MatFactorInfo
6881 @*/
6882 
6883 PetscErrorCode PETSCMAT_DLLEXPORT MatFactorInfoInitialize(MatFactorInfo *info)
6884 {
6885   PetscErrorCode ierr;
6886 
6887   PetscFunctionBegin;
6888   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
6889   PetscFunctionReturn(0);
6890 }
6891 
6892 #undef __FUNCT__
6893 #define __FUNCT__ "MatPtAP"
6894 /*@
6895    MatPtAP - Creates the matrix projection C = P^T * A * P
6896 
6897    Collective on Mat
6898 
6899    Input Parameters:
6900 +  A - the matrix
6901 .  P - the projection matrix
6902 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6903 -  fill - expected fill as ratio of nnz(C)/nnz(A)
6904 
6905    Output Parameters:
6906 .  C - the product matrix
6907 
6908    Notes:
6909    C will be created and must be destroyed by the user with MatDestroy().
6910 
6911    This routine is currently only implemented for pairs of AIJ matrices and classes
6912    which inherit from AIJ.
6913 
6914    Level: intermediate
6915 
6916 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
6917 @*/
6918 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
6919 {
6920   PetscErrorCode ierr;
6921 
6922   PetscFunctionBegin;
6923   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6924   PetscValidType(A,1);
6925   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6926   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6927   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
6928   PetscValidType(P,2);
6929   MatPreallocated(P);
6930   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6931   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6932   PetscValidPointer(C,3);
6933   if (P->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap.N,A->cmap.N);
6934   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
6935   ierr = MatPreallocated(A);CHKERRQ(ierr);
6936 
6937   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
6938   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
6939   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
6940 
6941   PetscFunctionReturn(0);
6942 }
6943 
6944 #undef __FUNCT__
6945 #define __FUNCT__ "MatPtAPNumeric"
6946 /*@
6947    MatPtAPNumeric - Computes the matrix projection C = P^T * A * P
6948 
6949    Collective on Mat
6950 
6951    Input Parameters:
6952 +  A - the matrix
6953 -  P - the projection matrix
6954 
6955    Output Parameters:
6956 .  C - the product matrix
6957 
6958    Notes:
6959    C must have been created by calling MatPtAPSymbolic and must be destroyed by
6960    the user using MatDeatroy().
6961 
6962    This routine is currently only implemented for pairs of AIJ matrices and classes
6963    which inherit from AIJ.  C will be of type MATAIJ.
6964 
6965    Level: intermediate
6966 
6967 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
6968 @*/
6969 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPNumeric(Mat A,Mat P,Mat C)
6970 {
6971   PetscErrorCode ierr;
6972 
6973   PetscFunctionBegin;
6974   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6975   PetscValidType(A,1);
6976   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6977   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6978   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
6979   PetscValidType(P,2);
6980   MatPreallocated(P);
6981   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6982   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6983   PetscValidHeaderSpecific(C,MAT_COOKIE,3);
6984   PetscValidType(C,3);
6985   MatPreallocated(C);
6986   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6987   if (P->cmap.N!=C->rmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap.N,C->rmap.N);
6988   if (P->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap.N,A->cmap.N);
6989   if (A->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap.N,A->cmap.N);
6990   if (P->cmap.N!=C->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap.N,C->cmap.N);
6991   ierr = MatPreallocated(A);CHKERRQ(ierr);
6992 
6993   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
6994   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
6995   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
6996   PetscFunctionReturn(0);
6997 }
6998 
6999 #undef __FUNCT__
7000 #define __FUNCT__ "MatPtAPSymbolic"
7001 /*@
7002    MatPtAPSymbolic - Creates the (i,j) structure of the matrix projection C = P^T * A * P
7003 
7004    Collective on Mat
7005 
7006    Input Parameters:
7007 +  A - the matrix
7008 -  P - the projection matrix
7009 
7010    Output Parameters:
7011 .  C - the (i,j) structure of the product matrix
7012 
7013    Notes:
7014    C will be created and must be destroyed by the user with MatDestroy().
7015 
7016    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
7017    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
7018    this (i,j) structure by calling MatPtAPNumeric().
7019 
7020    Level: intermediate
7021 
7022 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
7023 @*/
7024 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
7025 {
7026   PetscErrorCode ierr;
7027 
7028   PetscFunctionBegin;
7029   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7030   PetscValidType(A,1);
7031   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7032   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7033   if (fill <1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7034   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
7035   PetscValidType(P,2);
7036   MatPreallocated(P);
7037   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7038   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7039   PetscValidPointer(C,3);
7040 
7041   if (P->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap.N,A->cmap.N);
7042   if (A->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap.N,A->cmap.N);
7043   ierr = MatPreallocated(A);CHKERRQ(ierr);
7044   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
7045   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
7046   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
7047 
7048   ierr = MatSetBlockSize(*C,A->rmap.bs);CHKERRQ(ierr);
7049 
7050   PetscFunctionReturn(0);
7051 }
7052 
7053 #undef __FUNCT__
7054 #define __FUNCT__ "MatMatMult"
7055 /*@
7056    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
7057 
7058    Collective on Mat
7059 
7060    Input Parameters:
7061 +  A - the left matrix
7062 .  B - the right matrix
7063 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7064 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
7065           if the result is a dense matrix this is irrelevent
7066 
7067    Output Parameters:
7068 .  C - the product matrix
7069 
7070    Notes:
7071    Unless scall is MAT_REUSE_MATRIX C will be created.
7072 
7073    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7074 
7075    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7076    actually needed.
7077 
7078    If you have many matrices with the same non-zero structure to multiply, you
7079    should either
7080 $   1) use MAT_REUSE_MATRIX in all calls but the first or
7081 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
7082 
7083    Level: intermediate
7084 
7085 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
7086 @*/
7087 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7088 {
7089   PetscErrorCode ierr;
7090   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7091   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7092   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
7093 
7094   PetscFunctionBegin;
7095   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7096   PetscValidType(A,1);
7097   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7098   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7099   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7100   PetscValidType(B,2);
7101   MatPreallocated(B);
7102   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7103   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7104   PetscValidPointer(C,3);
7105   if (B->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->cmap.N);
7106   if (scall == MAT_REUSE_MATRIX){
7107     PetscValidPointer(*C,5);
7108     PetscValidHeaderSpecific(*C,MAT_COOKIE,5);
7109   }
7110   if (fill == PETSC_DEFAULT) fill = 2.0;
7111   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7112   ierr = MatPreallocated(A);CHKERRQ(ierr);
7113 
7114   fA = A->ops->matmult;
7115   fB = B->ops->matmult;
7116   if (fB == fA) {
7117     if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
7118     mult = fB;
7119   } else {
7120     /* dispatch based on the type of A and B */
7121     char  multname[256];
7122     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
7123     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7124     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
7125     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7126     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
7127     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
7128     if (!mult) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7129   }
7130   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
7131   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
7132   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
7133   PetscFunctionReturn(0);
7134 }
7135 
7136 #undef __FUNCT__
7137 #define __FUNCT__ "MatMatMultSymbolic"
7138 /*@
7139    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
7140    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
7141 
7142    Collective on Mat
7143 
7144    Input Parameters:
7145 +  A - the left matrix
7146 .  B - the right matrix
7147 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
7148       if C is a dense matrix this is irrelevent
7149 
7150    Output Parameters:
7151 .  C - the product matrix
7152 
7153    Notes:
7154    Unless scall is MAT_REUSE_MATRIX C will be created.
7155 
7156    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7157    actually needed.
7158 
7159    This routine is currently implemented for
7160     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
7161     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7162     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7163 
7164    Level: intermediate
7165 
7166 .seealso: MatMatMult(), MatMatMultNumeric()
7167 @*/
7168 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
7169 {
7170   PetscErrorCode ierr;
7171   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
7172   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
7173   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
7174 
7175   PetscFunctionBegin;
7176   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7177   PetscValidType(A,1);
7178   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7179   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7180 
7181   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7182   PetscValidType(B,2);
7183   MatPreallocated(B);
7184   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7185   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7186   PetscValidPointer(C,3);
7187 
7188   if (B->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->cmap.N);
7189   if (fill == PETSC_DEFAULT) fill = 2.0;
7190   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7191   ierr = MatPreallocated(A);CHKERRQ(ierr);
7192 
7193   Asymbolic = A->ops->matmultsymbolic;
7194   Bsymbolic = B->ops->matmultsymbolic;
7195   if (Asymbolic == Bsymbolic){
7196     if (!Bsymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
7197     symbolic = Bsymbolic;
7198   } else { /* dispatch based on the type of A and B */
7199     char  symbolicname[256];
7200     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
7201     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7202     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
7203     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7204     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
7205     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
7206     if (!symbolic) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7207   }
7208   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
7209   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
7210   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
7211   PetscFunctionReturn(0);
7212 }
7213 
7214 #undef __FUNCT__
7215 #define __FUNCT__ "MatMatMultNumeric"
7216 /*@
7217    MatMatMultNumeric - Performs the numeric matrix-matrix product.
7218    Call this routine after first calling MatMatMultSymbolic().
7219 
7220    Collective on Mat
7221 
7222    Input Parameters:
7223 +  A - the left matrix
7224 -  B - the right matrix
7225 
7226    Output Parameters:
7227 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
7228 
7229    Notes:
7230    C must have been created with MatMatMultSymbolic().
7231 
7232    This routine is currently implemented for
7233     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
7234     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7235     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7236 
7237    Level: intermediate
7238 
7239 .seealso: MatMatMult(), MatMatMultSymbolic()
7240 @*/
7241 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultNumeric(Mat A,Mat B,Mat C)
7242 {
7243   PetscErrorCode ierr;
7244   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
7245   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
7246   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
7247 
7248   PetscFunctionBegin;
7249   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7250   PetscValidType(A,1);
7251   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7252   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7253 
7254   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7255   PetscValidType(B,2);
7256   MatPreallocated(B);
7257   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7258   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7259 
7260   PetscValidHeaderSpecific(C,MAT_COOKIE,3);
7261   PetscValidType(C,3);
7262   MatPreallocated(C);
7263   if (!C->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7264   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7265 
7266   if (B->cmap.N!=C->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap.N,C->cmap.N);
7267   if (B->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->cmap.N);
7268   if (A->rmap.N!=C->rmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap.N,C->rmap.N);
7269   ierr = MatPreallocated(A);CHKERRQ(ierr);
7270 
7271   Anumeric = A->ops->matmultnumeric;
7272   Bnumeric = B->ops->matmultnumeric;
7273   if (Anumeric == Bnumeric){
7274     if (!Bnumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
7275     numeric = Bnumeric;
7276   } else {
7277     char  numericname[256];
7278     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
7279     ierr = PetscStrcat(numericname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7280     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
7281     ierr = PetscStrcat(numericname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7282     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
7283     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
7284     if (!numeric)
7285       SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7286   }
7287   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
7288   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
7289   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
7290   PetscFunctionReturn(0);
7291 }
7292 
7293 #undef __FUNCT__
7294 #define __FUNCT__ "MatMatMultTranspose"
7295 /*@
7296    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
7297 
7298    Collective on Mat
7299 
7300    Input Parameters:
7301 +  A - the left matrix
7302 .  B - the right matrix
7303 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7304 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
7305 
7306    Output Parameters:
7307 .  C - the product matrix
7308 
7309    Notes:
7310    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
7311 
7312    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7313 
7314   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7315    actually needed.
7316 
7317    This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
7318    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
7319 
7320    Level: intermediate
7321 
7322 .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
7323 @*/
7324 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7325 {
7326   PetscErrorCode ierr;
7327   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7328   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7329 
7330   PetscFunctionBegin;
7331   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7332   PetscValidType(A,1);
7333   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7334   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7335   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7336   PetscValidType(B,2);
7337   MatPreallocated(B);
7338   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7339   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7340   PetscValidPointer(C,3);
7341   if (B->rmap.N!=A->rmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->rmap.N);
7342   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7343   ierr = MatPreallocated(A);CHKERRQ(ierr);
7344 
7345   fA = A->ops->matmulttranspose;
7346   if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
7347   fB = B->ops->matmulttranspose;
7348   if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
7349   if (fB!=fA) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultTranspose requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7350 
7351   ierr = PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
7352   ierr = (*A->ops->matmulttranspose)(A,B,scall,fill,C);CHKERRQ(ierr);
7353   ierr = PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
7354 
7355   PetscFunctionReturn(0);
7356 }
7357 
7358 #undef __FUNCT__
7359 #define __FUNCT__ "MatGetRedundantMatrix"
7360 /*@C
7361    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
7362 
7363    Collective on Mat
7364 
7365    Input Parameters:
7366 +  mat - the matrix
7367 .  nsubcomm - the number of subcommunicators (= number of redundant pareallel or sequential matrices)
7368 .  subcomm - MPI communicator split from the communicator where mat resides in
7369 .  mlocal_red - number of local rows of the redundant matrix
7370 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7371 
7372    Output Parameter:
7373 .  matredundant - redundant matrix
7374 
7375    Notes:
7376    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
7377    original matrix has not changed from that last call to MatGetRedundantMatrix().
7378 
7379    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
7380    calling it.
7381 
7382    Only MPIAIJ matrix is supported.
7383 
7384    Level: advanced
7385 
7386    Concepts: subcommunicator
7387    Concepts: duplicate matrix
7388 
7389 .seealso: MatDestroy()
7390 @*/
7391 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
7392 {
7393   PetscErrorCode ierr;
7394 
7395   PetscFunctionBegin;
7396   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
7397   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
7398     PetscValidPointer(*matredundant,6);
7399     PetscValidHeaderSpecific(*matredundant,MAT_COOKIE,6);
7400   }
7401   if (!mat->ops->getredundantmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7402   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7403   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7404   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7405 
7406   ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
7407   ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr);
7408   ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
7409   PetscFunctionReturn(0);
7410 }
7411