xref: /petsc/src/mat/interface/matrix.c (revision b29801fcf26fbf6d208dd8c8ba676caeae7da2a8)
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     ierr = PetscObjectReference((PetscObject)mapping);CHKERRQ(ierr);
1371     x->mapping = mapping;
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   ierr = PetscObjectReference((PetscObject)mapping);CHKERRQ(ierr);
1409   x->bmapping = mapping;
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   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
5717   if (mat->nullsp) { ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr); }
5718   mat->nullsp = nullsp;
5719   PetscFunctionReturn(0);
5720 }
5721 
5722 #undef __FUNCT__
5723 #define __FUNCT__ "MatICCFactor"
5724 /*@
5725    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
5726 
5727    Collective on Mat
5728 
5729    Input Parameters:
5730 +  mat - the matrix
5731 .  row - row/column permutation
5732 .  fill - expected fill factor >= 1.0
5733 -  level - level of fill, for ICC(k)
5734 
5735    Notes:
5736    Probably really in-place only when level of fill is zero, otherwise allocates
5737    new space to store factored matrix and deletes previous memory.
5738 
5739    Most users should employ the simplified KSP interface for linear solvers
5740    instead of working directly with matrix algebra routines such as this.
5741    See, e.g., KSPCreate().
5742 
5743    Level: developer
5744 
5745    Concepts: matrices^incomplete Cholesky factorization
5746    Concepts: Cholesky factorization
5747 
5748 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5749 @*/
5750 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactor(Mat mat,IS row,MatFactorInfo* info)
5751 {
5752   PetscErrorCode ierr;
5753 
5754   PetscFunctionBegin;
5755   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5756   PetscValidType(mat,1);
5757   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
5758   PetscValidPointer(info,3);
5759   if (mat->rmap.N != mat->cmap.N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
5760   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5761   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5762   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5763   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5764   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
5765   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5766   PetscFunctionReturn(0);
5767 }
5768 
5769 #undef __FUNCT__
5770 #define __FUNCT__ "MatSetValuesAdic"
5771 /*@
5772    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
5773 
5774    Not Collective
5775 
5776    Input Parameters:
5777 +  mat - the matrix
5778 -  v - the values compute with ADIC
5779 
5780    Level: developer
5781 
5782    Notes:
5783      Must call MatSetColoring() before using this routine. Also this matrix must already
5784      have its nonzero pattern determined.
5785 
5786 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5787           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
5788 @*/
5789 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdic(Mat mat,void *v)
5790 {
5791   PetscErrorCode ierr;
5792 
5793   PetscFunctionBegin;
5794   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5795   PetscValidType(mat,1);
5796   PetscValidPointer(mat,2);
5797 
5798   if (!mat->assembled) {
5799     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
5800   }
5801   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5802   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5803   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
5804   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5805   ierr = MatView_Private(mat);CHKERRQ(ierr);
5806   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5807   PetscFunctionReturn(0);
5808 }
5809 
5810 
5811 #undef __FUNCT__
5812 #define __FUNCT__ "MatSetColoring"
5813 /*@
5814    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
5815 
5816    Not Collective
5817 
5818    Input Parameters:
5819 +  mat - the matrix
5820 -  coloring - the coloring
5821 
5822    Level: developer
5823 
5824 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5825           MatSetValues(), MatSetValuesAdic()
5826 @*/
5827 PetscErrorCode PETSCMAT_DLLEXPORT MatSetColoring(Mat mat,ISColoring coloring)
5828 {
5829   PetscErrorCode ierr;
5830 
5831   PetscFunctionBegin;
5832   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5833   PetscValidType(mat,1);
5834   PetscValidPointer(coloring,2);
5835 
5836   if (!mat->assembled) {
5837     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
5838   }
5839   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5840   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
5841   PetscFunctionReturn(0);
5842 }
5843 
5844 #undef __FUNCT__
5845 #define __FUNCT__ "MatSetValuesAdifor"
5846 /*@
5847    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
5848 
5849    Not Collective
5850 
5851    Input Parameters:
5852 +  mat - the matrix
5853 .  nl - leading dimension of v
5854 -  v - the values compute with ADIFOR
5855 
5856    Level: developer
5857 
5858    Notes:
5859      Must call MatSetColoring() before using this routine. Also this matrix must already
5860      have its nonzero pattern determined.
5861 
5862 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5863           MatSetValues(), MatSetColoring()
5864 @*/
5865 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
5866 {
5867   PetscErrorCode ierr;
5868 
5869   PetscFunctionBegin;
5870   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5871   PetscValidType(mat,1);
5872   PetscValidPointer(v,3);
5873 
5874   if (!mat->assembled) {
5875     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
5876   }
5877   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5878   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5879   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
5880   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5881   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5882   PetscFunctionReturn(0);
5883 }
5884 
5885 #undef __FUNCT__
5886 #define __FUNCT__ "MatDiagonalScaleLocal"
5887 /*@
5888    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
5889          ghosted ones.
5890 
5891    Not Collective
5892 
5893    Input Parameters:
5894 +  mat - the matrix
5895 -  diag = the diagonal values, including ghost ones
5896 
5897    Level: developer
5898 
5899    Notes: Works only for MPIAIJ and MPIBAIJ matrices
5900 
5901 .seealso: MatDiagonalScale()
5902 @*/
5903 PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalScaleLocal(Mat mat,Vec diag)
5904 {
5905   PetscErrorCode ierr;
5906   PetscMPIInt    size;
5907 
5908   PetscFunctionBegin;
5909   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5910   PetscValidHeaderSpecific(diag,VEC_COOKIE,2);
5911   PetscValidType(mat,1);
5912 
5913   if (!mat->assembled) {
5914     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
5915   }
5916   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5917   ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr);
5918   if (size == 1) {
5919     PetscInt n,m;
5920     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
5921     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
5922     if (m == n) {
5923       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
5924     } else {
5925       SETERRQ(PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
5926     }
5927   } else {
5928     PetscErrorCode (*f)(Mat,Vec);
5929     ierr = PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);CHKERRQ(ierr);
5930     if (f) {
5931       ierr = (*f)(mat,diag);CHKERRQ(ierr);
5932     } else {
5933       SETERRQ(PETSC_ERR_SUP,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
5934     }
5935   }
5936   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5937   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5938   PetscFunctionReturn(0);
5939 }
5940 
5941 #undef __FUNCT__
5942 #define __FUNCT__ "MatGetInertia"
5943 /*@
5944    MatGetInertia - Gets the inertia from a factored matrix
5945 
5946    Collective on Mat
5947 
5948    Input Parameter:
5949 .  mat - the matrix
5950 
5951    Output Parameters:
5952 +   nneg - number of negative eigenvalues
5953 .   nzero - number of zero eigenvalues
5954 -   npos - number of positive eigenvalues
5955 
5956    Level: advanced
5957 
5958    Notes: Matrix must have been factored by MatCholeskyFactor()
5959 
5960 
5961 @*/
5962 PetscErrorCode PETSCMAT_DLLEXPORT MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
5963 {
5964   PetscErrorCode ierr;
5965 
5966   PetscFunctionBegin;
5967   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5968   PetscValidType(mat,1);
5969   if (!mat->factor)    SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
5970   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
5971   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5972   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
5973   PetscFunctionReturn(0);
5974 }
5975 
5976 /* ----------------------------------------------------------------*/
5977 #undef __FUNCT__
5978 #define __FUNCT__ "MatSolves"
5979 /*@
5980    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
5981 
5982    Collective on Mat and Vecs
5983 
5984    Input Parameters:
5985 +  mat - the factored matrix
5986 -  b - the right-hand-side vectors
5987 
5988    Output Parameter:
5989 .  x - the result vectors
5990 
5991    Notes:
5992    The vectors b and x cannot be the same.  I.e., one cannot
5993    call MatSolves(A,x,x).
5994 
5995    Notes:
5996    Most users should employ the simplified KSP interface for linear solvers
5997    instead of working directly with matrix algebra routines such as this.
5998    See, e.g., KSPCreate().
5999 
6000    Level: developer
6001 
6002    Concepts: matrices^triangular solves
6003 
6004 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
6005 @*/
6006 PetscErrorCode PETSCMAT_DLLEXPORT MatSolves(Mat mat,Vecs b,Vecs x)
6007 {
6008   PetscErrorCode ierr;
6009 
6010   PetscFunctionBegin;
6011   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6012   PetscValidType(mat,1);
6013   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
6014   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6015   if (!mat->rmap.N && !mat->cmap.N) PetscFunctionReturn(0);
6016 
6017   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
6018   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6019   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
6020   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
6021   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
6022   PetscFunctionReturn(0);
6023 }
6024 
6025 #undef __FUNCT__
6026 #define __FUNCT__ "MatIsSymmetric"
6027 /*@
6028    MatIsSymmetric - Test whether a matrix is symmetric
6029 
6030    Collective on Mat
6031 
6032    Input Parameter:
6033 +  A - the matrix to test
6034 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
6035 
6036    Output Parameters:
6037 .  flg - the result
6038 
6039    Level: intermediate
6040 
6041    Concepts: matrix^symmetry
6042 
6043 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6044 @*/
6045 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetric(Mat A,PetscReal tol,PetscTruth *flg)
6046 {
6047   PetscErrorCode ierr;
6048 
6049   PetscFunctionBegin;
6050   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6051   PetscValidPointer(flg,2);
6052   if (!A->symmetric_set) {
6053     if (!A->ops->issymmetric) {
6054       MatType mattype;
6055       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
6056       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
6057     }
6058     ierr = (*A->ops->issymmetric)(A,tol,&A->symmetric);CHKERRQ(ierr);
6059     A->symmetric_set = PETSC_TRUE;
6060     if (A->symmetric) {
6061       A->structurally_symmetric_set = PETSC_TRUE;
6062       A->structurally_symmetric     = PETSC_TRUE;
6063     }
6064   }
6065   *flg = A->symmetric;
6066   PetscFunctionReturn(0);
6067 }
6068 
6069 #undef __FUNCT__
6070 #define __FUNCT__ "MatIsSymmetricKnown"
6071 /*@
6072    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
6073 
6074    Collective on Mat
6075 
6076    Input Parameter:
6077 .  A - the matrix to check
6078 
6079    Output Parameters:
6080 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
6081 -  flg - the result
6082 
6083    Level: advanced
6084 
6085    Concepts: matrix^symmetry
6086 
6087    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
6088          if you want it explicitly checked
6089 
6090 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6091 @*/
6092 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetricKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6093 {
6094   PetscFunctionBegin;
6095   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6096   PetscValidPointer(set,2);
6097   PetscValidPointer(flg,3);
6098   if (A->symmetric_set) {
6099     *set = PETSC_TRUE;
6100     *flg = A->symmetric;
6101   } else {
6102     *set = PETSC_FALSE;
6103   }
6104   PetscFunctionReturn(0);
6105 }
6106 
6107 #undef __FUNCT__
6108 #define __FUNCT__ "MatIsHermitianKnown"
6109 /*@
6110    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
6111 
6112    Collective on Mat
6113 
6114    Input Parameter:
6115 .  A - the matrix to check
6116 
6117    Output Parameters:
6118 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
6119 -  flg - the result
6120 
6121    Level: advanced
6122 
6123    Concepts: matrix^symmetry
6124 
6125    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
6126          if you want it explicitly checked
6127 
6128 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6129 @*/
6130 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitianKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6131 {
6132   PetscFunctionBegin;
6133   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6134   PetscValidPointer(set,2);
6135   PetscValidPointer(flg,3);
6136   if (A->hermitian_set) {
6137     *set = PETSC_TRUE;
6138     *flg = A->hermitian;
6139   } else {
6140     *set = PETSC_FALSE;
6141   }
6142   PetscFunctionReturn(0);
6143 }
6144 
6145 #undef __FUNCT__
6146 #define __FUNCT__ "MatIsStructurallySymmetric"
6147 /*@
6148    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
6149 
6150    Collective on Mat
6151 
6152    Input Parameter:
6153 .  A - the matrix to test
6154 
6155    Output Parameters:
6156 .  flg - the result
6157 
6158    Level: intermediate
6159 
6160    Concepts: matrix^symmetry
6161 
6162 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
6163 @*/
6164 PetscErrorCode PETSCMAT_DLLEXPORT MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
6165 {
6166   PetscErrorCode ierr;
6167 
6168   PetscFunctionBegin;
6169   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6170   PetscValidPointer(flg,2);
6171   if (!A->structurally_symmetric_set) {
6172     if (!A->ops->isstructurallysymmetric) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
6173     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
6174     A->structurally_symmetric_set = PETSC_TRUE;
6175   }
6176   *flg = A->structurally_symmetric;
6177   PetscFunctionReturn(0);
6178 }
6179 
6180 #undef __FUNCT__
6181 #define __FUNCT__ "MatIsHermitian"
6182 /*@
6183    MatIsHermitian - Test whether a matrix is Hermitian, i.e. it is the complex conjugate of its transpose.
6184 
6185    Collective on Mat
6186 
6187    Input Parameter:
6188 .  A - the matrix to test
6189 
6190    Output Parameters:
6191 .  flg - the result
6192 
6193    Level: intermediate
6194 
6195    Concepts: matrix^symmetry
6196 
6197 .seealso: MatTranspose(), MatIsTranspose(), MatIsSymmetric(), MatIsStructurallySymmetric(), MatSetOption()
6198 @*/
6199 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitian(Mat A,PetscTruth *flg)
6200 {
6201   PetscErrorCode ierr;
6202 
6203   PetscFunctionBegin;
6204   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6205   PetscValidPointer(flg,2);
6206   if (!A->hermitian_set) {
6207     if (!A->ops->ishermitian) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for being Hermitian");
6208     ierr = (*A->ops->ishermitian)(A,&A->hermitian);CHKERRQ(ierr);
6209     A->hermitian_set = PETSC_TRUE;
6210     if (A->hermitian) {
6211       A->structurally_symmetric_set = PETSC_TRUE;
6212       A->structurally_symmetric     = PETSC_TRUE;
6213     }
6214   }
6215   *flg = A->hermitian;
6216   PetscFunctionReturn(0);
6217 }
6218 
6219 #undef __FUNCT__
6220 #define __FUNCT__ "MatStashGetInfo"
6221 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
6222 /*@
6223    MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
6224        to be communicated to other processors during the MatAssemblyBegin/End() process
6225 
6226     Not collective
6227 
6228    Input Parameter:
6229 .   vec - the vector
6230 
6231    Output Parameters:
6232 +   nstash   - the size of the stash
6233 .   reallocs - the number of additional mallocs incurred.
6234 .   bnstash   - the size of the block stash
6235 -   breallocs - the number of additional mallocs incurred.in the block stash
6236 
6237    Level: advanced
6238 
6239 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
6240 
6241 @*/
6242 PetscErrorCode PETSCMAT_DLLEXPORT MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
6243 {
6244   PetscErrorCode ierr;
6245   PetscFunctionBegin;
6246   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
6247   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
6248   PetscFunctionReturn(0);
6249 }
6250 
6251 #undef __FUNCT__
6252 #define __FUNCT__ "MatGetVecs"
6253 /*@
6254    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
6255      parallel layout
6256 
6257    Collective on Mat
6258 
6259    Input Parameter:
6260 .  mat - the matrix
6261 
6262    Output Parameter:
6263 +   right - (optional) vector that the matrix can be multiplied against
6264 -   left - (optional) vector that the matrix vector product can be stored in
6265 
6266   Level: advanced
6267 
6268 .seealso: MatCreate()
6269 @*/
6270 PetscErrorCode PETSCMAT_DLLEXPORT MatGetVecs(Mat mat,Vec *right,Vec *left)
6271 {
6272   PetscErrorCode ierr;
6273 
6274   PetscFunctionBegin;
6275   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6276   PetscValidType(mat,1);
6277   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6278   if (mat->ops->getvecs) {
6279     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
6280   } else {
6281     PetscMPIInt size;
6282     ierr = MPI_Comm_size(mat->comm, &size);CHKERRQ(ierr);
6283     if (right) {
6284       ierr = VecCreate(mat->comm,right);CHKERRQ(ierr);
6285       ierr = VecSetSizes(*right,mat->cmap.n,PETSC_DETERMINE);CHKERRQ(ierr);
6286       if (size > 1) {ierr = VecSetType(*right,VECMPI);CHKERRQ(ierr);}
6287       else {ierr = VecSetType(*right,VECSEQ);CHKERRQ(ierr);}
6288     }
6289     if (left) {
6290       ierr = VecCreate(mat->comm,left);CHKERRQ(ierr);
6291       ierr = VecSetSizes(*left,mat->rmap.n,PETSC_DETERMINE);CHKERRQ(ierr);
6292       if (size > 1) {ierr = VecSetType(*left,VECMPI);CHKERRQ(ierr);}
6293       else {ierr = VecSetType(*left,VECSEQ);CHKERRQ(ierr);}
6294     }
6295   }
6296   if (right) {ierr = VecSetBlockSize(*right,mat->rmap.bs);CHKERRQ(ierr);}
6297   if (left) {ierr = VecSetBlockSize(*left,mat->rmap.bs);CHKERRQ(ierr);}
6298   PetscFunctionReturn(0);
6299 }
6300 
6301 #undef __FUNCT__
6302 #define __FUNCT__ "MatFactorInfoInitialize"
6303 /*@
6304    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
6305      with default values.
6306 
6307    Not Collective
6308 
6309    Input Parameters:
6310 .    info - the MatFactorInfo data structure
6311 
6312 
6313    Notes: The solvers are generally used through the KSP and PC objects, for example
6314           PCLU, PCILU, PCCHOLESKY, PCICC
6315 
6316    Level: developer
6317 
6318 .seealso: MatFactorInfo
6319 @*/
6320 
6321 PetscErrorCode PETSCMAT_DLLEXPORT MatFactorInfoInitialize(MatFactorInfo *info)
6322 {
6323   PetscErrorCode ierr;
6324 
6325   PetscFunctionBegin;
6326   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
6327   PetscFunctionReturn(0);
6328 }
6329 
6330 #undef __FUNCT__
6331 #define __FUNCT__ "MatPtAP"
6332 /*@
6333    MatPtAP - Creates the matrix projection C = P^T * A * P
6334 
6335    Collective on Mat
6336 
6337    Input Parameters:
6338 +  A - the matrix
6339 .  P - the projection matrix
6340 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6341 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))
6342 
6343    Output Parameters:
6344 .  C - the product matrix
6345 
6346    Notes:
6347    C will be created and must be destroyed by the user with MatDestroy().
6348 
6349    This routine is currently only implemented for pairs of AIJ matrices and classes
6350    which inherit from AIJ.
6351 
6352    Level: intermediate
6353 
6354 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
6355 @*/
6356 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
6357 {
6358   PetscErrorCode ierr;
6359 
6360   PetscFunctionBegin;
6361   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6362   PetscValidType(A,1);
6363   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6364   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6365   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
6366   PetscValidType(P,2);
6367   MatPreallocated(P);
6368   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6369   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6370   PetscValidPointer(C,3);
6371   if (P->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap.N,A->cmap.N);
6372   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
6373   ierr = MatPreallocated(A);CHKERRQ(ierr);
6374 
6375   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
6376   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
6377   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
6378 
6379   PetscFunctionReturn(0);
6380 }
6381 
6382 #undef __FUNCT__
6383 #define __FUNCT__ "MatPtAPNumeric"
6384 /*@
6385    MatPtAPNumeric - Computes the matrix projection C = P^T * A * P
6386 
6387    Collective on Mat
6388 
6389    Input Parameters:
6390 +  A - the matrix
6391 -  P - the projection matrix
6392 
6393    Output Parameters:
6394 .  C - the product matrix
6395 
6396    Notes:
6397    C must have been created by calling MatPtAPSymbolic and must be destroyed by
6398    the user using MatDeatroy().
6399 
6400    This routine is currently only implemented for pairs of AIJ matrices and classes
6401    which inherit from AIJ.  C will be of type MATAIJ.
6402 
6403    Level: intermediate
6404 
6405 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
6406 @*/
6407 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPNumeric(Mat A,Mat P,Mat C)
6408 {
6409   PetscErrorCode ierr;
6410 
6411   PetscFunctionBegin;
6412   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6413   PetscValidType(A,1);
6414   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6415   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6416   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
6417   PetscValidType(P,2);
6418   MatPreallocated(P);
6419   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6420   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6421   PetscValidHeaderSpecific(C,MAT_COOKIE,3);
6422   PetscValidType(C,3);
6423   MatPreallocated(C);
6424   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6425   if (P->cmap.N!=C->rmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap.N,C->rmap.N);
6426   if (P->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap.N,A->cmap.N);
6427   if (A->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap.N,A->cmap.N);
6428   if (P->cmap.N!=C->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap.N,C->cmap.N);
6429   ierr = MatPreallocated(A);CHKERRQ(ierr);
6430 
6431   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
6432   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
6433   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
6434   PetscFunctionReturn(0);
6435 }
6436 
6437 #undef __FUNCT__
6438 #define __FUNCT__ "MatPtAPSymbolic"
6439 /*@
6440    MatPtAPSymbolic - Creates the (i,j) structure of the matrix projection C = P^T * A * P
6441 
6442    Collective on Mat
6443 
6444    Input Parameters:
6445 +  A - the matrix
6446 -  P - the projection matrix
6447 
6448    Output Parameters:
6449 .  C - the (i,j) structure of the product matrix
6450 
6451    Notes:
6452    C will be created and must be destroyed by the user with MatDestroy().
6453 
6454    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
6455    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
6456    this (i,j) structure by calling MatPtAPNumeric().
6457 
6458    Level: intermediate
6459 
6460 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
6461 @*/
6462 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
6463 {
6464   PetscErrorCode ierr;
6465 
6466   PetscFunctionBegin;
6467   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6468   PetscValidType(A,1);
6469   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6470   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6471   if (fill <1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
6472   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
6473   PetscValidType(P,2);
6474   MatPreallocated(P);
6475   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6476   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6477   PetscValidPointer(C,3);
6478 
6479   if (P->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap.N,A->cmap.N);
6480   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);
6481   ierr = MatPreallocated(A);CHKERRQ(ierr);
6482   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
6483   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
6484   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
6485 
6486   ierr = MatSetBlockSize(*C,A->rmap.bs);CHKERRQ(ierr);
6487 
6488   PetscFunctionReturn(0);
6489 }
6490 
6491 #undef __FUNCT__
6492 #define __FUNCT__ "MatMatMult"
6493 /*@
6494    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
6495 
6496    Collective on Mat
6497 
6498    Input Parameters:
6499 +  A - the left matrix
6500 .  B - the right matrix
6501 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6502 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B))
6503 
6504    Output Parameters:
6505 .  C - the product matrix
6506 
6507    Notes:
6508    C will be created and must be destroyed by the user with MatDestroy().
6509    Unless scall is MAT_REUSE_MATRIX
6510 
6511    If you have many matrices with the same non-zero structure to multiply, you
6512    should either
6513 $   1) use MAT_REUSE_MATRIX in all calls but the first or
6514 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
6515 
6516    Level: intermediate
6517 
6518 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
6519 @*/
6520 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
6521 {
6522   PetscErrorCode ierr;
6523   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
6524   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
6525   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
6526 
6527   PetscFunctionBegin;
6528   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6529   PetscValidType(A,1);
6530   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6531   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6532   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
6533   PetscValidType(B,2);
6534   MatPreallocated(B);
6535   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6536   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6537   PetscValidPointer(C,3);
6538   if (B->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->cmap.N);
6539   if (fill == PETSC_DEFAULT) fill = 2.0;
6540   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
6541   ierr = MatPreallocated(A);CHKERRQ(ierr);
6542 
6543   fA = A->ops->matmult;
6544   fB = B->ops->matmult;
6545   if (fB == fA) {
6546     if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",B->type_name);
6547     mult = fB;
6548   } else {
6549     /* dispatch based on the type of A and B */
6550     char  multname[256];
6551     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
6552     ierr = PetscStrcat(multname,A->type_name);CHKERRQ(ierr);
6553     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
6554     ierr = PetscStrcat(multname,B->type_name);CHKERRQ(ierr);
6555     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_aij_dense_C" */
6556     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
6557     if (!mult) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",A->type_name,B->type_name);
6558   }
6559   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
6560   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
6561   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
6562   PetscFunctionReturn(0);
6563 }
6564 
6565 #undef __FUNCT__
6566 #define __FUNCT__ "MatMatMultSymbolic"
6567 /*@
6568    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
6569    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
6570 
6571    Collective on Mat
6572 
6573    Input Parameters:
6574 +  A - the left matrix
6575 .  B - the right matrix
6576 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B))
6577 
6578    Output Parameters:
6579 .  C - the matrix containing the ij structure of product matrix
6580 
6581    Notes:
6582    C will be created and must be destroyed by the user with MatDestroy().
6583 
6584    This routine is currently implemented for
6585     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
6586     - pairs of AIJ (A) and Dense (B) matrix, C will be of type MATDENSE.
6587 
6588    Level: intermediate
6589 
6590 .seealso: MatMatMult(), MatMatMultNumeric()
6591 @*/
6592 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
6593 {
6594   PetscErrorCode ierr;
6595   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
6596   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
6597   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
6598 
6599   PetscFunctionBegin;
6600   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6601   PetscValidType(A,1);
6602   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6603   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6604 
6605   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
6606   PetscValidType(B,2);
6607   MatPreallocated(B);
6608   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6609   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6610   PetscValidPointer(C,3);
6611 
6612   if (B->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->cmap.N);
6613   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
6614   ierr = MatPreallocated(A);CHKERRQ(ierr);
6615 
6616   Asymbolic = A->ops->matmultsymbolic;
6617   Bsymbolic = B->ops->matmultsymbolic;
6618   if (Asymbolic == Bsymbolic){
6619     if (!Bsymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",B->type_name);
6620     symbolic = Bsymbolic;
6621   } else { /* dispatch based on the type of A and B */
6622     char  symbolicname[256];
6623     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
6624     ierr = PetscStrcat(symbolicname,A->type_name);CHKERRQ(ierr);
6625     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
6626     ierr = PetscStrcat(symbolicname,B->type_name);CHKERRQ(ierr);
6627     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
6628     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
6629     if (!symbolic) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",A->type_name,B->type_name);
6630   }
6631   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
6632   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
6633   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
6634   PetscFunctionReturn(0);
6635 }
6636 
6637 #undef __FUNCT__
6638 #define __FUNCT__ "MatMatMultNumeric"
6639 /*@
6640    MatMatMultNumeric - Performs the numeric matrix-matrix product.
6641    Call this routine after first calling MatMatMultSymbolic().
6642 
6643    Collective on Mat
6644 
6645    Input Parameters:
6646 +  A - the left matrix
6647 -  B - the right matrix
6648 
6649    Output Parameters:
6650 .  C - the product matrix, whose ij structure was defined from MatMatMultSymbolic().
6651 
6652    Notes:
6653    C must have been created with MatMatMultSymbolic.
6654 
6655    This routine is currently implemented for
6656     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
6657     - pairs of AIJ (A) and Dense (B) matrix, C will be of type MATDENSE.
6658 
6659    Level: intermediate
6660 
6661 .seealso: MatMatMult(), MatMatMultSymbolic()
6662 @*/
6663 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultNumeric(Mat A,Mat B,Mat C)
6664 {
6665   PetscErrorCode ierr;
6666   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
6667   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
6668   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
6669 
6670   PetscFunctionBegin;
6671   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6672   PetscValidType(A,1);
6673   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6674   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6675 
6676   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
6677   PetscValidType(B,2);
6678   MatPreallocated(B);
6679   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6680   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6681 
6682   PetscValidHeaderSpecific(C,MAT_COOKIE,3);
6683   PetscValidType(C,3);
6684   MatPreallocated(C);
6685   if (!C->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6686   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6687 
6688   if (B->cmap.N!=C->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap.N,C->cmap.N);
6689   if (B->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->cmap.N);
6690   if (A->rmap.N!=C->rmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap.N,C->rmap.N);
6691   ierr = MatPreallocated(A);CHKERRQ(ierr);
6692 
6693   Anumeric = A->ops->matmultnumeric;
6694   Bnumeric = B->ops->matmultnumeric;
6695   if (Anumeric == Bnumeric){
6696     if (!Bnumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",B->type_name);
6697     numeric = Bnumeric;
6698   } else {
6699     char  numericname[256];
6700     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
6701     ierr = PetscStrcat(numericname,A->type_name);CHKERRQ(ierr);
6702     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
6703     ierr = PetscStrcat(numericname,B->type_name);CHKERRQ(ierr);
6704     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
6705     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
6706     if (!numeric)
6707       SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",A->type_name,B->type_name);
6708   }
6709   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
6710   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
6711   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
6712   PetscFunctionReturn(0);
6713 }
6714 
6715 #undef __FUNCT__
6716 #define __FUNCT__ "MatMatMultTranspose"
6717 /*@
6718    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
6719 
6720    Collective on Mat
6721 
6722    Input Parameters:
6723 +  A - the left matrix
6724 .  B - the right matrix
6725 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6726 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B))
6727 
6728    Output Parameters:
6729 .  C - the product matrix
6730 
6731    Notes:
6732    C will be created and must be destroyed by the user with MatDestroy().
6733 
6734    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
6735    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
6736 
6737    Level: intermediate
6738 
6739 .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
6740 @*/
6741 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
6742 {
6743   PetscErrorCode ierr;
6744   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
6745   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
6746 
6747   PetscFunctionBegin;
6748   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6749   PetscValidType(A,1);
6750   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6751   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6752   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
6753   PetscValidType(B,2);
6754   MatPreallocated(B);
6755   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6756   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6757   PetscValidPointer(C,3);
6758   if (B->rmap.N!=A->rmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->rmap.N);
6759   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
6760   ierr = MatPreallocated(A);CHKERRQ(ierr);
6761 
6762   fA = A->ops->matmulttranspose;
6763   if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",A->type_name);
6764   fB = B->ops->matmulttranspose;
6765   if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",B->type_name);
6766   if (fB!=fA) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultTranspose requires A, %s, to be compatible with B, %s",A->type_name,B->type_name);
6767 
6768   ierr = PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
6769   ierr = (*A->ops->matmulttranspose)(A,B,scall,fill,C);CHKERRQ(ierr);
6770   ierr = PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
6771 
6772   PetscFunctionReturn(0);
6773 }
6774