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