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