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