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