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