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