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