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