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