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