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