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