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