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