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