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