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