xref: /petsc/src/mat/interface/matrix.c (revision 3c8e0aa7b286f773d91ee9d90491a3ecc803b931)
1 #define PETSCMAT_DLL
2 
3 /*
4    This is where the abstract matrix operations are defined
5 */
6 
7 #include "src/mat/matimpl.h"        /*I "petscmat.h" I*/
8 #include "private/vecimpl.h"
9 
10 /* Logging support */
11 PetscCookie PETSCMAT_DLLEXPORT MAT_COOKIE = 0;
12 PetscEvent  MAT_Mult = 0, MAT_Mults = 0, MAT_MultConstrained = 0, MAT_MultAdd = 0, MAT_MultTranspose = 0;
13 PetscEvent  MAT_MultTransposeConstrained = 0, MAT_MultTransposeAdd = 0, MAT_Solve = 0, MAT_Solves = 0, MAT_SolveAdd = 0, MAT_SolveTranspose = 0;
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 .  x - solution vector (or PETSC_NULL)
574 -  b - right hand side 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 x,Vec b)
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,x,b);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 .  x - solution vector (or PETSC_NULL)
619 -  b - right hand side 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 x,Vec b)
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,x,b);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 
704   PetscFunctionBegin;
705   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
706   if (--A->refct > 0) PetscFunctionReturn(0);
707 
708   PetscValidType(A,1);
709   ierr = MatPreallocated(A);CHKERRQ(ierr);
710   /* if memory was published with AMS then destroy it */
711   ierr = PetscObjectDepublish(A);CHKERRQ(ierr);
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   if (A->rmap) {
719     ierr = PetscMapDestroy(A->rmap);CHKERRQ(ierr);
720   }
721   if (A->cmap) {
722     ierr = PetscMapDestroy(A->cmap);CHKERRQ(ierr);
723   }
724   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
725   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
726   PetscFunctionReturn(0);
727 }
728 
729 #undef __FUNCT__
730 #define __FUNCT__ "MatValid"
731 /*@
732    MatValid - Checks whether a matrix object is valid.
733 
734    Collective on Mat
735 
736    Input Parameter:
737 .  m - the matrix to check
738 
739    Output Parameter:
740    flg - flag indicating matrix status, either
741    PETSC_TRUE if matrix is valid, or PETSC_FALSE otherwise.
742 
743    Level: developer
744 
745    Concepts: matrices^validity
746 @*/
747 PetscErrorCode PETSCMAT_DLLEXPORT MatValid(Mat m,PetscTruth *flg)
748 {
749   PetscFunctionBegin;
750   PetscValidIntPointer(flg,1);
751   if (!m)                           *flg = PETSC_FALSE;
752   else if (m->cookie != MAT_COOKIE) *flg = PETSC_FALSE;
753   else                              *flg = PETSC_TRUE;
754   PetscFunctionReturn(0);
755 }
756 
757 #undef __FUNCT__
758 #define __FUNCT__ "MatSetValues"
759 /*@
760    MatSetValues - Inserts or adds a block of values into a matrix.
761    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
762    MUST be called after all calls to MatSetValues() have been completed.
763 
764    Not Collective
765 
766    Input Parameters:
767 +  mat - the matrix
768 .  v - a logically two-dimensional array of values
769 .  m, idxm - the number of rows and their global indices
770 .  n, idxn - the number of columns and their global indices
771 -  addv - either ADD_VALUES or INSERT_VALUES, where
772    ADD_VALUES adds values to any existing entries, and
773    INSERT_VALUES replaces existing entries with new values
774 
775    Notes:
776    By default the values, v, are row-oriented and unsorted.
777    See MatSetOption() for other options.
778 
779    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
780    options cannot be mixed without intervening calls to the assembly
781    routines.
782 
783    MatSetValues() uses 0-based row and column numbers in Fortran
784    as well as in C.
785 
786    Negative indices may be passed in idxm and idxn, these rows and columns are
787    simply ignored. This allows easily inserting element stiffness matrices
788    with homogeneous Dirchlet boundary conditions that you don't want represented
789    in the matrix.
790 
791    Efficiency Alert:
792    The routine MatSetValuesBlocked() may offer much better efficiency
793    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
794 
795    Level: beginner
796 
797    Concepts: matrices^putting entries in
798 
799 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
800           InsertMode, INSERT_VALUES, ADD_VALUES
801 @*/
802 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
803 {
804   PetscErrorCode ierr;
805 
806   PetscFunctionBegin;
807   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
808   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
809   PetscValidType(mat,1);
810   PetscValidIntPointer(idxm,3);
811   PetscValidIntPointer(idxn,5);
812   PetscValidScalarPointer(v,6);
813   ierr = MatPreallocated(mat);CHKERRQ(ierr);
814   if (mat->insertmode == NOT_SET_VALUES) {
815     mat->insertmode = addv;
816   }
817 #if defined(PETSC_USE_DEBUG)
818   else if (mat->insertmode != addv) {
819     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
820   }
821   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
822 #endif
823 
824   if (mat->assembled) {
825     mat->was_assembled = PETSC_TRUE;
826     mat->assembled     = PETSC_FALSE;
827   }
828   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
829   if (!mat->ops->setvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
830   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
831   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
832   PetscFunctionReturn(0);
833 }
834 
835 
836 #undef __FUNCT__
837 #define __FUNCT__ "MatSetValuesRowLocal"
838 /*@
839    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
840         values into a matrix
841 
842    Not Collective
843 
844    Input Parameters:
845 +  mat - the matrix
846 .  row - the (block) row to set
847 -  v - a logically two-dimensional array of values
848 
849    Notes:
850    By the values, v, are column-oriented (for the block version) and sorted
851 
852    All the nonzeros in the row must be provided
853 
854    The matrix must have previously had its column indices set
855 
856    The row must belong to this process
857 
858    Level: intermediate
859 
860    Concepts: matrices^putting entries in
861 
862 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
863           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
864 @*/
865 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
866 {
867   PetscErrorCode ierr;
868 
869   PetscFunctionBegin;
870   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
871   PetscValidType(mat,1);
872   PetscValidScalarPointer(v,2);
873   ierr = MatSetValuesRow(mat, mat->mapping->indices[row],v);CHKERRQ(ierr);
874   PetscFunctionReturn(0);
875 }
876 
877 #undef __FUNCT__
878 #define __FUNCT__ "MatSetValuesRow"
879 /*@
880    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
881         values into a matrix
882 
883    Not Collective
884 
885    Input Parameters:
886 +  mat - the matrix
887 .  row - the (block) row to set
888 -  v - a logically two-dimensional array of values
889 
890    Notes:
891    By the values, v, are column-oriented (for the block version) and sorted
892 
893    All the nonzeros in the row must be provided
894 
895    The matrix must have previously had its column indices set
896 
897    The row must belong to this process
898 
899    Level: intermediate
900 
901    Concepts: matrices^putting entries in
902 
903 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
904           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
905 @*/
906 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
907 {
908   PetscErrorCode ierr;
909 
910   PetscFunctionBegin;
911   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
912   PetscValidType(mat,1);
913   PetscValidScalarPointer(v,2);
914 #if defined(PETSC_USE_DEBUG)
915   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
916   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
917 #endif
918   mat->insertmode = INSERT_VALUES;
919 
920   if (mat->assembled) {
921     mat->was_assembled = PETSC_TRUE;
922     mat->assembled     = PETSC_FALSE;
923   }
924   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
925   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
926   ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
927   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
928   PetscFunctionReturn(0);
929 }
930 
931 #undef __FUNCT__
932 #define __FUNCT__ "MatSetValuesStencil"
933 /*@
934    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
935      Using structured grid indexing
936 
937    Not Collective
938 
939    Input Parameters:
940 +  mat - the matrix
941 .  v - a logically two-dimensional array of values
942 .  m - number of rows being entered
943 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
944 .  n - number of columns being entered
945 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
946 -  addv - either ADD_VALUES or INSERT_VALUES, where
947    ADD_VALUES adds values to any existing entries, and
948    INSERT_VALUES replaces existing entries with new values
949 
950    Notes:
951    By default the values, v, are row-oriented and unsorted.
952    See MatSetOption() for other options.
953 
954    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
955    options cannot be mixed without intervening calls to the assembly
956    routines.
957 
958    The grid coordinates are across the entire grid, not just the local portion
959 
960    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
961    as well as in C.
962 
963    For setting/accessing vector values via array coordinates you can use the DAVecGetArray() routine
964 
965    In order to use this routine you must either obtain the matrix with DAGetMatrix()
966    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
967 
968    The columns and rows in the stencil passed in MUST be contained within the
969    ghost region of the given process as set with DACreateXXX() or MatSetStencil(). For example,
970    if you create a DA with an overlap of one grid level and on a particular process its first
971    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
972    first i index you can use in your column and row indices in MatSetStencil() is 5.
973 
974    In Fortran idxm and idxn should be declared as
975 $     MatStencil idxm(4,m),idxn(4,n)
976    and the values inserted using
977 $    idxm(MatStencil_i,1) = i
978 $    idxm(MatStencil_j,1) = j
979 $    idxm(MatStencil_k,1) = k
980 $    idxm(MatStencil_c,1) = c
981    etc
982 
983    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
984    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
985    etc to obtain values that obtained by wrapping the values from the left edge.
986 
987    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
988    a single value per point) you can skip filling those indices.
989 
990    Inspired by the structured grid interface to the HYPRE package
991    (http://www.llnl.gov/CASC/hypre)
992 
993    Efficiency Alert:
994    The routine MatSetValuesBlockedStencil() may offer much better efficiency
995    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
996 
997    Level: beginner
998 
999    Concepts: matrices^putting entries in
1000 
1001 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1002           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DAGetMatrix(), DAVecGetArray(), MatStencil
1003 @*/
1004 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1005 {
1006   PetscErrorCode ierr;
1007   PetscInt       j,i,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1008   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1009 
1010   PetscFunctionBegin;
1011   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1012   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1013   PetscValidType(mat,1);
1014   PetscValidIntPointer(idxm,3);
1015   PetscValidIntPointer(idxn,5);
1016   PetscValidScalarPointer(v,6);
1017 
1018   if (m > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 128 rows at a time; trying to set %D",m);
1019   if (n > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 256 columns at a time; trying to set %D",n);
1020 
1021   for (i=0; i<m; i++) {
1022     for (j=0; j<3-sdim; j++) dxm++;
1023     tmp = *dxm++ - starts[0];
1024     for (j=0; j<dim-1; j++) {
1025       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1026       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1027     }
1028     if (mat->stencil.noc) dxm++;
1029     jdxm[i] = tmp;
1030   }
1031   for (i=0; i<n; i++) {
1032     for (j=0; j<3-sdim; j++) dxn++;
1033     tmp = *dxn++ - starts[0];
1034     for (j=0; j<dim-1; j++) {
1035       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1036       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1037     }
1038     if (mat->stencil.noc) dxn++;
1039     jdxn[i] = tmp;
1040   }
1041   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1042   PetscFunctionReturn(0);
1043 }
1044 
1045 #undef __FUNCT__
1046 #define __FUNCT__ "MatSetValuesBlockedStencil"
1047 /*@C
1048    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1049      Using structured grid indexing
1050 
1051    Not Collective
1052 
1053    Input Parameters:
1054 +  mat - the matrix
1055 .  v - a logically two-dimensional array of values
1056 .  m - number of rows being entered
1057 .  idxm - grid coordinates for matrix rows being entered
1058 .  n - number of columns being entered
1059 .  idxn - grid coordinates for matrix columns being entered
1060 -  addv - either ADD_VALUES or INSERT_VALUES, where
1061    ADD_VALUES adds values to any existing entries, and
1062    INSERT_VALUES replaces existing entries with new values
1063 
1064    Notes:
1065    By default the values, v, are row-oriented and unsorted.
1066    See MatSetOption() for other options.
1067 
1068    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1069    options cannot be mixed without intervening calls to the assembly
1070    routines.
1071 
1072    The grid coordinates are across the entire grid, not just the local portion
1073 
1074    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1075    as well as in C.
1076 
1077    For setting/accessing vector values via array coordinates you can use the DAVecGetArray() routine
1078 
1079    In order to use this routine you must either obtain the matrix with DAGetMatrix()
1080    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1081 
1082    The columns and rows in the stencil passed in MUST be contained within the
1083    ghost region of the given process as set with DACreateXXX() or MatSetStencil(). For example,
1084    if you create a DA with an overlap of one grid level and on a particular process its first
1085    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1086    first i index you can use in your column and row indices in MatSetStencil() is 5.
1087 
1088    In Fortran idxm and idxn should be declared as
1089 $     MatStencil idxm(4,m),idxn(4,n)
1090    and the values inserted using
1091 $    idxm(MatStencil_i,1) = i
1092 $    idxm(MatStencil_j,1) = j
1093 $    idxm(MatStencil_k,1) = k
1094    etc
1095 
1096    Negative indices may be passed in idxm and idxn, these rows and columns are
1097    simply ignored. This allows easily inserting element stiffness matrices
1098    with homogeneous Dirchlet boundary conditions that you don't want represented
1099    in the matrix.
1100 
1101    Inspired by the structured grid interface to the HYPRE package
1102    (http://www.llnl.gov/CASC/hypre)
1103 
1104    Level: beginner
1105 
1106    Concepts: matrices^putting entries in
1107 
1108 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1109           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DAGetMatrix(), DAVecGetArray(), MatStencil
1110 @*/
1111 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1112 {
1113   PetscErrorCode ierr;
1114   PetscInt       j,i,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1115   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1116 
1117   PetscFunctionBegin;
1118   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1119   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1120   PetscValidType(mat,1);
1121   PetscValidIntPointer(idxm,3);
1122   PetscValidIntPointer(idxn,5);
1123   PetscValidScalarPointer(v,6);
1124 
1125   if (m > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 128 rows at a time; trying to set %D",m);
1126   if (n > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 256 columns at a time; trying to set %D",n);
1127 
1128   for (i=0; i<m; i++) {
1129     for (j=0; j<3-sdim; j++) dxm++;
1130     tmp = *dxm++ - starts[0];
1131     for (j=0; j<sdim-1; j++) {
1132       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1133       else                                      tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1134     }
1135     dxm++;
1136     jdxm[i] = tmp;
1137   }
1138   for (i=0; i<n; i++) {
1139     for (j=0; j<3-sdim; j++) dxn++;
1140     tmp = *dxn++ - starts[0];
1141     for (j=0; j<sdim-1; j++) {
1142       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1143       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1144     }
1145     dxn++;
1146     jdxn[i] = tmp;
1147   }
1148   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1149   PetscFunctionReturn(0);
1150 }
1151 
1152 #undef __FUNCT__
1153 #define __FUNCT__ "MatSetStencil"
1154 /*@
1155    MatSetStencil - Sets the grid information for setting values into a matrix via
1156         MatSetValuesStencil()
1157 
1158    Not Collective
1159 
1160    Input Parameters:
1161 +  mat - the matrix
1162 .  dim - dimension of the grid 1, 2, or 3
1163 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1164 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1165 -  dof - number of degrees of freedom per node
1166 
1167 
1168    Inspired by the structured grid interface to the HYPRE package
1169    (www.llnl.gov/CASC/hyper)
1170 
1171    For matrices generated with DAGetMatrix() this routine is automatically called and so not needed by the
1172    user.
1173 
1174    Level: beginner
1175 
1176    Concepts: matrices^putting entries in
1177 
1178 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1179           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1180 @*/
1181 PetscErrorCode PETSCMAT_DLLEXPORT MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1182 {
1183   PetscInt i;
1184 
1185   PetscFunctionBegin;
1186   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1187   PetscValidIntPointer(dims,3);
1188   PetscValidIntPointer(starts,4);
1189 
1190   mat->stencil.dim = dim + (dof > 1);
1191   for (i=0; i<dim; i++) {
1192     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1193     mat->stencil.starts[i] = starts[dim-i-1];
1194   }
1195   mat->stencil.dims[dim]   = dof;
1196   mat->stencil.starts[dim] = 0;
1197   mat->stencil.noc         = (PetscTruth)(dof == 1);
1198   PetscFunctionReturn(0);
1199 }
1200 
1201 #undef __FUNCT__
1202 #define __FUNCT__ "MatSetValuesBlocked"
1203 /*@
1204    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1205 
1206    Not Collective
1207 
1208    Input Parameters:
1209 +  mat - the matrix
1210 .  v - a logically two-dimensional array of values
1211 .  m, idxm - the number of block rows and their global block indices
1212 .  n, idxn - the number of block columns and their global block indices
1213 -  addv - either ADD_VALUES or INSERT_VALUES, where
1214    ADD_VALUES adds values to any existing entries, and
1215    INSERT_VALUES replaces existing entries with new values
1216 
1217    Notes:
1218    The m and n count the NUMBER of blocks in the row direction and column direction,
1219    NOT the total number of rows/columns; for example, if the block size is 2 and
1220    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1221 
1222    By default the values, v, are row-oriented and unsorted. So the layout of
1223    v is the same as for MatSetValues(). See MatSetOption() for other options.
1224 
1225    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1226    options cannot be mixed without intervening calls to the assembly
1227    routines.
1228 
1229    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1230    as well as in C.
1231 
1232    Negative indices may be passed in idxm and idxn, these rows and columns are
1233    simply ignored. This allows easily inserting element stiffness matrices
1234    with homogeneous Dirchlet boundary conditions that you don't want represented
1235    in the matrix.
1236 
1237    Each time an entry is set within a sparse matrix via MatSetValues(),
1238    internal searching must be done to determine where to place the the
1239    data in the matrix storage space.  By instead inserting blocks of
1240    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1241    reduced.
1242 
1243    Restrictions:
1244    MatSetValuesBlocked() is currently supported only for the BAIJ and SBAIJ formats
1245 
1246    Level: intermediate
1247 
1248    Concepts: matrices^putting entries in blocked
1249 
1250 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1251 @*/
1252 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1253 {
1254   PetscErrorCode ierr;
1255 
1256   PetscFunctionBegin;
1257   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1258   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1259   PetscValidType(mat,1);
1260   PetscValidIntPointer(idxm,3);
1261   PetscValidIntPointer(idxn,5);
1262   PetscValidScalarPointer(v,6);
1263   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1264   if (mat->insertmode == NOT_SET_VALUES) {
1265     mat->insertmode = addv;
1266   }
1267 #if defined(PETSC_USE_DEBUG)
1268   else if (mat->insertmode != addv) {
1269     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1270   }
1271   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1272 #endif
1273 
1274   if (mat->assembled) {
1275     mat->was_assembled = PETSC_TRUE;
1276     mat->assembled     = PETSC_FALSE;
1277   }
1278   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1279   if (!mat->ops->setvaluesblocked) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1280   ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1281   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1282   PetscFunctionReturn(0);
1283 }
1284 
1285 #undef __FUNCT__
1286 #define __FUNCT__ "MatGetValues"
1287 /*@
1288    MatGetValues - Gets a block of values from a matrix.
1289 
1290    Not Collective; currently only returns a local block
1291 
1292    Input Parameters:
1293 +  mat - the matrix
1294 .  v - a logically two-dimensional array for storing the values
1295 .  m, idxm - the number of rows and their global indices
1296 -  n, idxn - the number of columns and their global indices
1297 
1298    Notes:
1299    The user must allocate space (m*n PetscScalars) for the values, v.
1300    The values, v, are then returned in a row-oriented format,
1301    analogous to that used by default in MatSetValues().
1302 
1303    MatGetValues() uses 0-based row and column numbers in
1304    Fortran as well as in C.
1305 
1306    MatGetValues() requires that the matrix has been assembled
1307    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1308    MatSetValues() and MatGetValues() CANNOT be made in succession
1309    without intermediate matrix assembly.
1310 
1311    Level: advanced
1312 
1313    Concepts: matrices^accessing values
1314 
1315 .seealso: MatGetRow(), MatGetSubmatrices(), MatSetValues()
1316 @*/
1317 PetscErrorCode PETSCMAT_DLLEXPORT MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1318 {
1319   PetscErrorCode ierr;
1320 
1321   PetscFunctionBegin;
1322   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1323   PetscValidType(mat,1);
1324   PetscValidIntPointer(idxm,3);
1325   PetscValidIntPointer(idxn,5);
1326   PetscValidScalarPointer(v,6);
1327   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1328   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1329   if (!mat->ops->getvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1330   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1331 
1332   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1333   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1334   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1335   PetscFunctionReturn(0);
1336 }
1337 
1338 #undef __FUNCT__
1339 #define __FUNCT__ "MatSetLocalToGlobalMapping"
1340 /*@
1341    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1342    the routine MatSetValuesLocal() to allow users to insert matrix entries
1343    using a local (per-processor) numbering.
1344 
1345    Not Collective
1346 
1347    Input Parameters:
1348 +  x - the matrix
1349 -  mapping - mapping created with ISLocalToGlobalMappingCreate()
1350              or ISLocalToGlobalMappingCreateIS()
1351 
1352    Level: intermediate
1353 
1354    Concepts: matrices^local to global mapping
1355    Concepts: local to global mapping^for matrices
1356 
1357 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1358 @*/
1359 PetscErrorCode PETSCMAT_DLLEXPORT MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping mapping)
1360 {
1361   PetscErrorCode ierr;
1362   PetscFunctionBegin;
1363   PetscValidHeaderSpecific(x,MAT_COOKIE,1);
1364   PetscValidType(x,1);
1365   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE,2);
1366   if (x->mapping) {
1367     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1368   }
1369   ierr = MatPreallocated(x);CHKERRQ(ierr);
1370 
1371   if (x->ops->setlocaltoglobalmapping) {
1372     ierr = (*x->ops->setlocaltoglobalmapping)(x,mapping);CHKERRQ(ierr);
1373   } else {
1374     x->mapping = mapping;
1375     ierr = PetscObjectReference((PetscObject)mapping);CHKERRQ(ierr);
1376   }
1377   PetscFunctionReturn(0);
1378 }
1379 
1380 #undef __FUNCT__
1381 #define __FUNCT__ "MatSetLocalToGlobalMappingBlock"
1382 /*@
1383    MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
1384    by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
1385    entries using a local (per-processor) numbering.
1386 
1387    Not Collective
1388 
1389    Input Parameters:
1390 +  x - the matrix
1391 -  mapping - mapping created with ISLocalToGlobalMappingCreate() or
1392              ISLocalToGlobalMappingCreateIS()
1393 
1394    Level: intermediate
1395 
1396    Concepts: matrices^local to global mapping blocked
1397    Concepts: local to global mapping^for matrices, blocked
1398 
1399 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1400            MatSetValuesBlocked(), MatSetValuesLocal()
1401 @*/
1402 PetscErrorCode PETSCMAT_DLLEXPORT MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping mapping)
1403 {
1404   PetscErrorCode ierr;
1405   PetscFunctionBegin;
1406   PetscValidHeaderSpecific(x,MAT_COOKIE,1);
1407   PetscValidType(x,1);
1408   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE,2);
1409   if (x->bmapping) {
1410     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1411   }
1412   x->bmapping = mapping;
1413   ierr = PetscObjectReference((PetscObject)mapping);CHKERRQ(ierr);
1414   PetscFunctionReturn(0);
1415 }
1416 
1417 #undef __FUNCT__
1418 #define __FUNCT__ "MatSetValuesLocal"
1419 /*@
1420    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1421    using a local ordering of the nodes.
1422 
1423    Not Collective
1424 
1425    Input Parameters:
1426 +  x - the matrix
1427 .  nrow, irow - number of rows and their local indices
1428 .  ncol, icol - number of columns and their local indices
1429 .  y -  a logically two-dimensional array of values
1430 -  addv - either INSERT_VALUES or ADD_VALUES, where
1431    ADD_VALUES adds values to any existing entries, and
1432    INSERT_VALUES replaces existing entries with new values
1433 
1434    Notes:
1435    Before calling MatSetValuesLocal(), the user must first set the
1436    local-to-global mapping by calling MatSetLocalToGlobalMapping().
1437 
1438    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
1439    options cannot be mixed without intervening calls to the assembly
1440    routines.
1441 
1442    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1443    MUST be called after all calls to MatSetValuesLocal() have been completed.
1444 
1445    Level: intermediate
1446 
1447    Concepts: matrices^putting entries in with local numbering
1448 
1449 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1450            MatSetValueLocal()
1451 @*/
1452 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1453 {
1454   PetscErrorCode ierr;
1455   PetscInt       irowm[2048],icolm[2048];
1456 
1457   PetscFunctionBegin;
1458   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1459   PetscValidType(mat,1);
1460   PetscValidIntPointer(irow,3);
1461   PetscValidIntPointer(icol,5);
1462   PetscValidScalarPointer(y,6);
1463   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1464   if (mat->insertmode == NOT_SET_VALUES) {
1465     mat->insertmode = addv;
1466   }
1467 #if defined(PETSC_USE_DEBUG)
1468   else if (mat->insertmode != addv) {
1469     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1470   }
1471   if (!mat->ops->setvalueslocal && (nrow > 2048 || ncol > 2048)) {
1472     SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %D %D",nrow,ncol);
1473   }
1474   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1475 #endif
1476 
1477   if (mat->assembled) {
1478     mat->was_assembled = PETSC_TRUE;
1479     mat->assembled     = PETSC_FALSE;
1480   }
1481   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1482   if (!mat->ops->setvalueslocal) {
1483     ierr = ISLocalToGlobalMappingApply(mat->mapping,nrow,irow,irowm);CHKERRQ(ierr);
1484     ierr = ISLocalToGlobalMappingApply(mat->mapping,ncol,icol,icolm);CHKERRQ(ierr);
1485     ierr = (*mat->ops->setvalues)(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
1486   } else {
1487     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
1488   }
1489   mat->same_nonzero = PETSC_FALSE;
1490   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1491   PetscFunctionReturn(0);
1492 }
1493 
1494 #undef __FUNCT__
1495 #define __FUNCT__ "MatSetValuesBlockedLocal"
1496 /*@
1497    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
1498    using a local ordering of the nodes a block at a time.
1499 
1500    Not Collective
1501 
1502    Input Parameters:
1503 +  x - the matrix
1504 .  nrow, irow - number of rows and their local indices
1505 .  ncol, icol - number of columns and their local indices
1506 .  y -  a logically two-dimensional array of values
1507 -  addv - either INSERT_VALUES or ADD_VALUES, where
1508    ADD_VALUES adds values to any existing entries, and
1509    INSERT_VALUES replaces existing entries with new values
1510 
1511    Notes:
1512    Before calling MatSetValuesBlockedLocal(), the user must first set the
1513    local-to-global mapping by calling MatSetLocalToGlobalMappingBlock(),
1514    where the mapping MUST be set for matrix blocks, not for matrix elements.
1515 
1516    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
1517    options cannot be mixed without intervening calls to the assembly
1518    routines.
1519 
1520    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1521    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
1522 
1523    Level: intermediate
1524 
1525    Concepts: matrices^putting blocked values in with local numbering
1526 
1527 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
1528 @*/
1529 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1530 {
1531   PetscErrorCode ierr;
1532   PetscInt       irowm[2048],icolm[2048];
1533 
1534   PetscFunctionBegin;
1535   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1536   PetscValidType(mat,1);
1537   PetscValidIntPointer(irow,3);
1538   PetscValidIntPointer(icol,5);
1539   PetscValidScalarPointer(y,6);
1540   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1541   if (mat->insertmode == NOT_SET_VALUES) {
1542     mat->insertmode = addv;
1543   }
1544 #if defined(PETSC_USE_DEBUG)
1545   else if (mat->insertmode != addv) {
1546     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1547   }
1548   if (!mat->bmapping) {
1549     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with MatSetLocalToGlobalMappingBlock()");
1550   }
1551   if (nrow > 2048 || ncol > 2048) {
1552     SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %D %D",nrow,ncol);
1553   }
1554   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1555 #endif
1556 
1557   if (mat->assembled) {
1558     mat->was_assembled = PETSC_TRUE;
1559     mat->assembled     = PETSC_FALSE;
1560   }
1561   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1562   ierr = ISLocalToGlobalMappingApply(mat->bmapping,nrow,irow,irowm);CHKERRQ(ierr);
1563   ierr = ISLocalToGlobalMappingApply(mat->bmapping,ncol,icol,icolm);CHKERRQ(ierr);
1564   ierr = (*mat->ops->setvaluesblocked)(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
1565   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1566   PetscFunctionReturn(0);
1567 }
1568 
1569 /* --------------------------------------------------------*/
1570 #undef __FUNCT__
1571 #define __FUNCT__ "MatMult"
1572 /*@
1573    MatMult - Computes the matrix-vector product, y = Ax.
1574 
1575    Collective on Mat and Vec
1576 
1577    Input Parameters:
1578 +  mat - the matrix
1579 -  x   - the vector to be multiplied
1580 
1581    Output Parameters:
1582 .  y - the result
1583 
1584    Notes:
1585    The vectors x and y cannot be the same.  I.e., one cannot
1586    call MatMult(A,y,y).
1587 
1588    Level: beginner
1589 
1590    Concepts: matrix-vector product
1591 
1592 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
1593 @*/
1594 PetscErrorCode PETSCMAT_DLLEXPORT MatMult(Mat mat,Vec x,Vec y)
1595 {
1596   PetscErrorCode ierr;
1597 
1598   PetscFunctionBegin;
1599   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1600   PetscValidType(mat,1);
1601   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1602   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1603 
1604   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1605   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1606   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1607 #ifndef PETSC_HAVE_CONSTRAINTS
1608   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->N,x->N);
1609   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->M,y->N);
1610   if (mat->m != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->m,y->n);
1611 #endif
1612   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1613 
1614   if (mat->nullsp) {
1615     ierr = MatNullSpaceRemove(mat->nullsp,x,&x);CHKERRQ(ierr);
1616   }
1617 
1618   if (!mat->ops->mult) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
1619   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
1620   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
1621   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
1622 
1623   if (mat->nullsp) {
1624     ierr = MatNullSpaceRemove(mat->nullsp,y,PETSC_NULL);CHKERRQ(ierr);
1625   }
1626   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
1627   PetscFunctionReturn(0);
1628 }
1629 
1630 #undef __FUNCT__
1631 #define __FUNCT__ "MatMultTranspose"
1632 /*@
1633    MatMultTranspose - Computes matrix transpose times a vector.
1634 
1635    Collective on Mat and Vec
1636 
1637    Input Parameters:
1638 +  mat - the matrix
1639 -  x   - the vector to be multilplied
1640 
1641    Output Parameters:
1642 .  y - the result
1643 
1644    Notes:
1645    The vectors x and y cannot be the same.  I.e., one cannot
1646    call MatMultTranspose(A,y,y).
1647 
1648    Level: beginner
1649 
1650    Concepts: matrix vector product^transpose
1651 
1652 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd()
1653 @*/
1654 PetscErrorCode PETSCMAT_DLLEXPORT MatMultTranspose(Mat mat,Vec x,Vec y)
1655 {
1656   PetscErrorCode ierr;
1657 
1658   PetscFunctionBegin;
1659   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1660   PetscValidType(mat,1);
1661   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1662   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1663 
1664   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1665   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1666   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1667 #ifndef PETSC_HAVE_CONSTRAINTS
1668   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->M,x->N);
1669   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->N,y->N);
1670 #endif
1671   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1672 
1673   if (!mat->ops->multtranspose) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
1674   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
1675   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
1676   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
1677   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
1678   PetscFunctionReturn(0);
1679 }
1680 
1681 #undef __FUNCT__
1682 #define __FUNCT__ "MatMultAdd"
1683 /*@
1684     MatMultAdd -  Computes v3 = v2 + A * v1.
1685 
1686     Collective on Mat and Vec
1687 
1688     Input Parameters:
1689 +   mat - the matrix
1690 -   v1, v2 - the vectors
1691 
1692     Output Parameters:
1693 .   v3 - the result
1694 
1695     Notes:
1696     The vectors v1 and v3 cannot be the same.  I.e., one cannot
1697     call MatMultAdd(A,v1,v2,v1).
1698 
1699     Level: beginner
1700 
1701     Concepts: matrix vector product^addition
1702 
1703 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
1704 @*/
1705 PetscErrorCode PETSCMAT_DLLEXPORT MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1706 {
1707   PetscErrorCode ierr;
1708 
1709   PetscFunctionBegin;
1710   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1711   PetscValidType(mat,1);
1712   PetscValidHeaderSpecific(v1,VEC_COOKIE,2);
1713   PetscValidHeaderSpecific(v2,VEC_COOKIE,3);
1714   PetscValidHeaderSpecific(v3,VEC_COOKIE,4);
1715 
1716   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1717   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1718   if (mat->N != v1->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->N,v1->N);
1719   if (mat->M != v2->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->M,v2->N);
1720   if (mat->M != v3->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->M,v3->N);
1721   if (mat->m != v3->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %D %D",mat->m,v3->n);
1722   if (mat->m != v2->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %D %D",mat->m,v2->n);
1723   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1724   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1725 
1726   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1727   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
1728   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1729   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
1730   PetscFunctionReturn(0);
1731 }
1732 
1733 #undef __FUNCT__
1734 #define __FUNCT__ "MatMultTransposeAdd"
1735 /*@
1736    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
1737 
1738    Collective on Mat and Vec
1739 
1740    Input Parameters:
1741 +  mat - the matrix
1742 -  v1, v2 - the vectors
1743 
1744    Output Parameters:
1745 .  v3 - the result
1746 
1747    Notes:
1748    The vectors v1 and v3 cannot be the same.  I.e., one cannot
1749    call MatMultTransposeAdd(A,v1,v2,v1).
1750 
1751    Level: beginner
1752 
1753    Concepts: matrix vector product^transpose and addition
1754 
1755 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
1756 @*/
1757 PetscErrorCode PETSCMAT_DLLEXPORT MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1758 {
1759   PetscErrorCode ierr;
1760 
1761   PetscFunctionBegin;
1762   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1763   PetscValidType(mat,1);
1764   PetscValidHeaderSpecific(v1,VEC_COOKIE,2);
1765   PetscValidHeaderSpecific(v2,VEC_COOKIE,3);
1766   PetscValidHeaderSpecific(v3,VEC_COOKIE,4);
1767 
1768   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1769   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1770   if (!mat->ops->multtransposeadd) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1771   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1772   if (mat->M != v1->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->M,v1->N);
1773   if (mat->N != v2->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->N,v2->N);
1774   if (mat->N != v3->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->N,v3->N);
1775   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1776 
1777   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1778   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
1779   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1780   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
1781   PetscFunctionReturn(0);
1782 }
1783 
1784 #undef __FUNCT__
1785 #define __FUNCT__ "MatMultConstrained"
1786 /*@
1787    MatMultConstrained - The inner multiplication routine for a
1788    constrained matrix P^T A P.
1789 
1790    Collective on Mat and Vec
1791 
1792    Input Parameters:
1793 +  mat - the matrix
1794 -  x   - the vector to be multilplied
1795 
1796    Output Parameters:
1797 .  y - the result
1798 
1799    Notes:
1800    The vectors x and y cannot be the same.  I.e., one cannot
1801    call MatMult(A,y,y).
1802 
1803    Level: beginner
1804 
1805 .keywords: matrix, multiply, matrix-vector product, constraint
1806 .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1807 @*/
1808 PetscErrorCode PETSCMAT_DLLEXPORT MatMultConstrained(Mat mat,Vec x,Vec y)
1809 {
1810   PetscErrorCode ierr;
1811 
1812   PetscFunctionBegin;
1813   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1814   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1815   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1816   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1817   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1818   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1819   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->N,x->N);
1820   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->M,y->N);
1821   if (mat->m != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->m,y->n);
1822 
1823   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1824   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
1825   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1826   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
1827 
1828   PetscFunctionReturn(0);
1829 }
1830 
1831 #undef __FUNCT__
1832 #define __FUNCT__ "MatMultTransposeConstrained"
1833 /*@
1834    MatMultTransposeConstrained - The inner multiplication routine for a
1835    constrained matrix P^T A^T P.
1836 
1837    Collective on Mat and Vec
1838 
1839    Input Parameters:
1840 +  mat - the matrix
1841 -  x   - the vector to be multilplied
1842 
1843    Output Parameters:
1844 .  y - the result
1845 
1846    Notes:
1847    The vectors x and y cannot be the same.  I.e., one cannot
1848    call MatMult(A,y,y).
1849 
1850    Level: beginner
1851 
1852 .keywords: matrix, multiply, matrix-vector product, constraint
1853 .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1854 @*/
1855 PetscErrorCode PETSCMAT_DLLEXPORT MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
1856 {
1857   PetscErrorCode ierr;
1858 
1859   PetscFunctionBegin;
1860   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1861   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1862   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1863   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1864   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1865   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1866   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->N,x->N);
1867   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->M,y->N);
1868 
1869   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1870   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
1871   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1872   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
1873 
1874   PetscFunctionReturn(0);
1875 }
1876 /* ------------------------------------------------------------*/
1877 #undef __FUNCT__
1878 #define __FUNCT__ "MatGetInfo"
1879 /*@
1880    MatGetInfo - Returns information about matrix storage (number of
1881    nonzeros, memory, etc.).
1882 
1883    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used
1884    as the flag
1885 
1886    Input Parameters:
1887 .  mat - the matrix
1888 
1889    Output Parameters:
1890 +  flag - flag indicating the type of parameters to be returned
1891    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
1892    MAT_GLOBAL_SUM - sum over all processors)
1893 -  info - matrix information context
1894 
1895    Notes:
1896    The MatInfo context contains a variety of matrix data, including
1897    number of nonzeros allocated and used, number of mallocs during
1898    matrix assembly, etc.  Additional information for factored matrices
1899    is provided (such as the fill ratio, number of mallocs during
1900    factorization, etc.).  Much of this info is printed to STDOUT
1901    when using the runtime options
1902 $       -log_info -mat_view_info
1903 
1904    Example for C/C++ Users:
1905    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
1906    data within the MatInfo context.  For example,
1907 .vb
1908       MatInfo info;
1909       Mat     A;
1910       double  mal, nz_a, nz_u;
1911 
1912       MatGetInfo(A,MAT_LOCAL,&info);
1913       mal  = info.mallocs;
1914       nz_a = info.nz_allocated;
1915 .ve
1916 
1917    Example for Fortran Users:
1918    Fortran users should declare info as a double precision
1919    array of dimension MAT_INFO_SIZE, and then extract the parameters
1920    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
1921    a complete list of parameter names.
1922 .vb
1923       double  precision info(MAT_INFO_SIZE)
1924       double  precision mal, nz_a
1925       Mat     A
1926       integer ierr
1927 
1928       call MatGetInfo(A,MAT_LOCAL,info,ierr)
1929       mal = info(MAT_INFO_MALLOCS)
1930       nz_a = info(MAT_INFO_NZ_ALLOCATED)
1931 .ve
1932 
1933     Level: intermediate
1934 
1935     Concepts: matrices^getting information on
1936 
1937 @*/
1938 PetscErrorCode PETSCMAT_DLLEXPORT MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
1939 {
1940   PetscErrorCode ierr;
1941 
1942   PetscFunctionBegin;
1943   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1944   PetscValidType(mat,1);
1945   PetscValidPointer(info,3);
1946   if (!mat->ops->getinfo) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1947   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1948   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
1949   PetscFunctionReturn(0);
1950 }
1951 
1952 /* ----------------------------------------------------------*/
1953 #undef __FUNCT__
1954 #define __FUNCT__ "MatILUDTFactor"
1955 /*@C
1956    MatILUDTFactor - Performs a drop tolerance ILU factorization.
1957 
1958    Collective on Mat
1959 
1960    Input Parameters:
1961 +  mat - the matrix
1962 .  row - row permutation
1963 .  col - column permutation
1964 -  info - information about the factorization to be done
1965 
1966    Output Parameters:
1967 .  fact - the factored matrix
1968 
1969    Level: developer
1970 
1971    Notes:
1972    Most users should employ the simplified KSP interface for linear solvers
1973    instead of working directly with matrix algebra routines such as this.
1974    See, e.g., KSPCreate().
1975 
1976    This is currently only supported for the SeqAIJ matrix format using code
1977    from Yousef Saad's SPARSEKIT2  package (translated to C with f2c) and/or
1978    Matlab. SPARSEKIT2 is copyrighted by Yousef Saad with the GNU copyright
1979    and thus can be distributed with PETSc.
1980 
1981     Concepts: matrices^ILUDT factorization
1982 
1983 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
1984 @*/
1985 PetscErrorCode PETSCMAT_DLLEXPORT MatILUDTFactor(Mat mat,IS row,IS col,MatFactorInfo *info,Mat *fact)
1986 {
1987   PetscErrorCode ierr;
1988 
1989   PetscFunctionBegin;
1990   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1991   PetscValidType(mat,1);
1992   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
1993   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
1994   PetscValidPointer(info,4);
1995   PetscValidPointer(fact,5);
1996   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1997   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1998   if (!mat->ops->iludtfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1999   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2000   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2001   ierr = (*mat->ops->iludtfactor)(mat,row,col,info,fact);CHKERRQ(ierr);
2002   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2003   ierr = PetscObjectStateIncrease((PetscObject)*fact);CHKERRQ(ierr);
2004 
2005   PetscFunctionReturn(0);
2006 }
2007 
2008 #undef __FUNCT__
2009 #define __FUNCT__ "MatLUFactor"
2010 /*@
2011    MatLUFactor - Performs in-place LU factorization of matrix.
2012 
2013    Collective on Mat
2014 
2015    Input Parameters:
2016 +  mat - the matrix
2017 .  row - row permutation
2018 .  col - column permutation
2019 -  info - options for factorization, includes
2020 $          fill - expected fill as ratio of original fill.
2021 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2022 $                   Run with the option -log_info to determine an optimal value to use
2023 
2024    Notes:
2025    Most users should employ the simplified KSP interface for linear solvers
2026    instead of working directly with matrix algebra routines such as this.
2027    See, e.g., KSPCreate().
2028 
2029    This changes the state of the matrix to a factored matrix; it cannot be used
2030    for example with MatSetValues() unless one first calls MatSetUnfactored().
2031 
2032    Level: developer
2033 
2034    Concepts: matrices^LU factorization
2035 
2036 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2037           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo
2038 
2039 @*/
2040 PetscErrorCode PETSCMAT_DLLEXPORT MatLUFactor(Mat mat,IS row,IS col,MatFactorInfo *info)
2041 {
2042   PetscErrorCode ierr;
2043 
2044   PetscFunctionBegin;
2045   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2046   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
2047   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
2048   PetscValidPointer(info,4);
2049   PetscValidType(mat,1);
2050   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2051   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2052   if (!mat->ops->lufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2053   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2054 
2055   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2056   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
2057   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2058   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2059   PetscFunctionReturn(0);
2060 }
2061 
2062 #undef __FUNCT__
2063 #define __FUNCT__ "MatILUFactor"
2064 /*@
2065    MatILUFactor - Performs in-place ILU factorization of matrix.
2066 
2067    Collective on Mat
2068 
2069    Input Parameters:
2070 +  mat - the matrix
2071 .  row - row permutation
2072 .  col - column permutation
2073 -  info - structure containing
2074 $      levels - number of levels of fill.
2075 $      expected fill - as ratio of original fill.
2076 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2077                 missing diagonal entries)
2078 
2079    Notes:
2080    Probably really in-place only when level of fill is zero, otherwise allocates
2081    new space to store factored matrix and deletes previous memory.
2082 
2083    Most users should employ the simplified KSP interface for linear solvers
2084    instead of working directly with matrix algebra routines such as this.
2085    See, e.g., KSPCreate().
2086 
2087    Level: developer
2088 
2089    Concepts: matrices^ILU factorization
2090 
2091 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2092 @*/
2093 PetscErrorCode PETSCMAT_DLLEXPORT MatILUFactor(Mat mat,IS row,IS col,MatFactorInfo *info)
2094 {
2095   PetscErrorCode ierr;
2096 
2097   PetscFunctionBegin;
2098   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2099   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
2100   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
2101   PetscValidPointer(info,4);
2102   PetscValidType(mat,1);
2103   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
2104   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2105   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2106   if (!mat->ops->ilufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2107   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2108 
2109   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2110   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
2111   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2112   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2113   PetscFunctionReturn(0);
2114 }
2115 
2116 #undef __FUNCT__
2117 #define __FUNCT__ "MatLUFactorSymbolic"
2118 /*@
2119    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2120    Call this routine before calling MatLUFactorNumeric().
2121 
2122    Collective on Mat
2123 
2124    Input Parameters:
2125 +  mat - the matrix
2126 .  row, col - row and column permutations
2127 -  info - options for factorization, includes
2128 $          fill - expected fill as ratio of original fill.
2129 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2130 $                   Run with the option -log_info to determine an optimal value to use
2131 
2132    Output Parameter:
2133 .  fact - new matrix that has been symbolically factored
2134 
2135    Notes:
2136    See the users manual for additional information about
2137    choosing the fill factor for better efficiency.
2138 
2139    Most users should employ the simplified KSP interface for linear solvers
2140    instead of working directly with matrix algebra routines such as this.
2141    See, e.g., KSPCreate().
2142 
2143    Level: developer
2144 
2145    Concepts: matrices^LU symbolic factorization
2146 
2147 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2148 @*/
2149 PetscErrorCode PETSCMAT_DLLEXPORT MatLUFactorSymbolic(Mat mat,IS row,IS col,MatFactorInfo *info,Mat *fact)
2150 {
2151   PetscErrorCode ierr;
2152 
2153   PetscFunctionBegin;
2154   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2155   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
2156   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
2157   PetscValidPointer(info,4);
2158   PetscValidType(mat,1);
2159   PetscValidPointer(fact,5);
2160   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2161   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2162   if (!mat->ops->lufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic LU",mat->type_name);
2163   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2164 
2165   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
2166   ierr = (*mat->ops->lufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
2167   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
2168   ierr = PetscObjectStateIncrease((PetscObject)*fact);CHKERRQ(ierr);
2169   PetscFunctionReturn(0);
2170 }
2171 
2172 #undef __FUNCT__
2173 #define __FUNCT__ "MatLUFactorNumeric"
2174 /*@
2175    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2176    Call this routine after first calling MatLUFactorSymbolic().
2177 
2178    Collective on Mat
2179 
2180    Input Parameters:
2181 +  mat - the matrix
2182 .  info - options for factorization
2183 -  fact - the matrix generated for the factor, from MatLUFactorSymbolic()
2184 
2185    Notes:
2186    See MatLUFactor() for in-place factorization.  See
2187    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
2188 
2189    Most users should employ the simplified KSP interface for linear solvers
2190    instead of working directly with matrix algebra routines such as this.
2191    See, e.g., KSPCreate().
2192 
2193    Level: developer
2194 
2195    Concepts: matrices^LU numeric factorization
2196 
2197 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
2198 @*/
2199 PetscErrorCode PETSCMAT_DLLEXPORT MatLUFactorNumeric(Mat mat,MatFactorInfo *info,Mat *fact)
2200 {
2201   PetscErrorCode ierr;
2202 
2203   PetscFunctionBegin;
2204   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2205   PetscValidType(mat,1);
2206   PetscValidPointer(fact,2);
2207   PetscValidHeaderSpecific(*fact,MAT_COOKIE,2);
2208   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2209   if (mat->M != (*fact)->M || mat->N != (*fact)->N) {
2210     SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat *fact: global dimensions are different %D should = %D %D should = %D",mat->M,(*fact)->M,mat->N,(*fact)->N);
2211   }
2212   if (!(*fact)->ops->lufactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2213   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2214   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
2215   ierr = (*(*fact)->ops->lufactornumeric)(mat,info,fact);CHKERRQ(ierr);
2216   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
2217 
2218   ierr = MatView_Private(*fact);CHKERRQ(ierr);
2219   ierr = PetscObjectStateIncrease((PetscObject)*fact);CHKERRQ(ierr);
2220   PetscFunctionReturn(0);
2221 }
2222 
2223 #undef __FUNCT__
2224 #define __FUNCT__ "MatCholeskyFactor"
2225 /*@
2226    MatCholeskyFactor - Performs in-place Cholesky factorization of a
2227    symmetric matrix.
2228 
2229    Collective on Mat
2230 
2231    Input Parameters:
2232 +  mat - the matrix
2233 .  perm - row and column permutations
2234 -  f - expected fill as ratio of original fill
2235 
2236    Notes:
2237    See MatLUFactor() for the nonsymmetric case.  See also
2238    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
2239 
2240    Most users should employ the simplified KSP interface for linear solvers
2241    instead of working directly with matrix algebra routines such as this.
2242    See, e.g., KSPCreate().
2243 
2244    Level: developer
2245 
2246    Concepts: matrices^Cholesky factorization
2247 
2248 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2249           MatGetOrdering()
2250 
2251 @*/
2252 PetscErrorCode PETSCMAT_DLLEXPORT MatCholeskyFactor(Mat mat,IS perm,MatFactorInfo *info)
2253 {
2254   PetscErrorCode ierr;
2255 
2256   PetscFunctionBegin;
2257   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2258   PetscValidType(mat,1);
2259   PetscValidHeaderSpecific(perm,IS_COOKIE,2);
2260   PetscValidPointer(info,3);
2261   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
2262   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2263   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2264   if (!mat->ops->choleskyfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2265   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2266 
2267   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
2268   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
2269   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
2270   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2271   PetscFunctionReturn(0);
2272 }
2273 
2274 #undef __FUNCT__
2275 #define __FUNCT__ "MatCholeskyFactorSymbolic"
2276 /*@
2277    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2278    of a symmetric matrix.
2279 
2280    Collective on Mat
2281 
2282    Input Parameters:
2283 +  mat - the matrix
2284 .  perm - row and column permutations
2285 -  info - options for factorization, includes
2286 $          fill - expected fill as ratio of original fill.
2287 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2288 $                   Run with the option -log_info to determine an optimal value to use
2289 
2290    Output Parameter:
2291 .  fact - the factored matrix
2292 
2293    Notes:
2294    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
2295    MatCholeskyFactor() and MatCholeskyFactorNumeric().
2296 
2297    Most users should employ the simplified KSP interface for linear solvers
2298    instead of working directly with matrix algebra routines such as this.
2299    See, e.g., KSPCreate().
2300 
2301    Level: developer
2302 
2303    Concepts: matrices^Cholesky symbolic factorization
2304 
2305 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2306           MatGetOrdering()
2307 
2308 @*/
2309 PetscErrorCode PETSCMAT_DLLEXPORT MatCholeskyFactorSymbolic(Mat mat,IS perm,MatFactorInfo *info,Mat *fact)
2310 {
2311   PetscErrorCode ierr;
2312 
2313   PetscFunctionBegin;
2314   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2315   PetscValidType(mat,1);
2316   if (perm) PetscValidHeaderSpecific(perm,IS_COOKIE,2);
2317   PetscValidPointer(info,3);
2318   PetscValidPointer(fact,4);
2319   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
2320   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2321   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2322   if (!mat->ops->choleskyfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2323   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2324 
2325   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
2326   ierr = (*mat->ops->choleskyfactorsymbolic)(mat,perm,info,fact);CHKERRQ(ierr);
2327   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
2328   ierr = PetscObjectStateIncrease((PetscObject)*fact);CHKERRQ(ierr);
2329   PetscFunctionReturn(0);
2330 }
2331 
2332 #undef __FUNCT__
2333 #define __FUNCT__ "MatCholeskyFactorNumeric"
2334 /*@
2335    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
2336    of a symmetric matrix. Call this routine after first calling
2337    MatCholeskyFactorSymbolic().
2338 
2339    Collective on Mat
2340 
2341    Input Parameter:
2342 .  mat - the initial matrix
2343 .  info - options for factorization
2344 -  fact - the symbolic factor of mat
2345 
2346    Output Parameter:
2347 .  fact - the factored matrix
2348 
2349    Notes:
2350    Most users should employ the simplified KSP interface for linear solvers
2351    instead of working directly with matrix algebra routines such as this.
2352    See, e.g., KSPCreate().
2353 
2354    Level: developer
2355 
2356    Concepts: matrices^Cholesky numeric factorization
2357 
2358 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
2359 @*/
2360 PetscErrorCode PETSCMAT_DLLEXPORT MatCholeskyFactorNumeric(Mat mat,MatFactorInfo *info,Mat *fact)
2361 {
2362   PetscErrorCode ierr;
2363 
2364   PetscFunctionBegin;
2365   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2366   PetscValidType(mat,1);
2367   PetscValidPointer(fact,2);
2368   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2369   if (!(*fact)->ops->choleskyfactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2370   if (mat->M != (*fact)->M || mat->N != (*fact)->N) {
2371     SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat *fact: global dim %D should = %D %D should = %D",mat->M,(*fact)->M,mat->N,(*fact)->N);
2372   }
2373   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2374 
2375   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
2376   ierr = (*(*fact)->ops->choleskyfactornumeric)(mat,info,fact);CHKERRQ(ierr);
2377   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
2378   ierr = PetscObjectStateIncrease((PetscObject)*fact);CHKERRQ(ierr);
2379   PetscFunctionReturn(0);
2380 }
2381 
2382 /* ----------------------------------------------------------------*/
2383 #undef __FUNCT__
2384 #define __FUNCT__ "MatSolve"
2385 /*@
2386    MatSolve - Solves A x = b, given a factored matrix.
2387 
2388    Collective on Mat and Vec
2389 
2390    Input Parameters:
2391 +  mat - the factored matrix
2392 -  b - the right-hand-side vector
2393 
2394    Output Parameter:
2395 .  x - the result vector
2396 
2397    Notes:
2398    The vectors b and x cannot be the same.  I.e., one cannot
2399    call MatSolve(A,x,x).
2400 
2401    Notes:
2402    Most users should employ the simplified KSP interface for linear solvers
2403    instead of working directly with matrix algebra routines such as this.
2404    See, e.g., KSPCreate().
2405 
2406    Level: developer
2407 
2408    Concepts: matrices^triangular solves
2409 
2410 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
2411 @*/
2412 PetscErrorCode PETSCMAT_DLLEXPORT MatSolve(Mat mat,Vec b,Vec x)
2413 {
2414   PetscErrorCode ierr;
2415 
2416   PetscFunctionBegin;
2417   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2418   PetscValidType(mat,1);
2419   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2420   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2421   PetscCheckSameComm(mat,1,b,2);
2422   PetscCheckSameComm(mat,1,x,3);
2423   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2424   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2425   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->N,x->N);
2426   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->M,b->N);
2427   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->m,b->n);
2428   if (!mat->M && !mat->N) PetscFunctionReturn(0);
2429   if (!mat->ops->solve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2430   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2431 
2432   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
2433   ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
2434   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
2435   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2436   PetscFunctionReturn(0);
2437 }
2438 
2439 #undef __FUNCT__
2440 #define __FUNCT__ "MatForwardSolve"
2441 /* @
2442    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU.
2443 
2444    Collective on Mat and Vec
2445 
2446    Input Parameters:
2447 +  mat - the factored matrix
2448 -  b - the right-hand-side vector
2449 
2450    Output Parameter:
2451 .  x - the result vector
2452 
2453    Notes:
2454    MatSolve() should be used for most applications, as it performs
2455    a forward solve followed by a backward solve.
2456 
2457    The vectors b and x cannot be the same.  I.e., one cannot
2458    call MatForwardSolve(A,x,x).
2459 
2460    Most users should employ the simplified KSP interface for linear solvers
2461    instead of working directly with matrix algebra routines such as this.
2462    See, e.g., KSPCreate().
2463 
2464    Level: developer
2465 
2466    Concepts: matrices^forward solves
2467 
2468 .seealso: MatSolve(), MatBackwardSolve()
2469 @ */
2470 PetscErrorCode PETSCMAT_DLLEXPORT MatForwardSolve(Mat mat,Vec b,Vec x)
2471 {
2472   PetscErrorCode ierr;
2473 
2474   PetscFunctionBegin;
2475   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2476   PetscValidType(mat,1);
2477   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2478   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2479   PetscCheckSameComm(mat,1,b,2);
2480   PetscCheckSameComm(mat,1,x,3);
2481   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2482   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2483   if (!mat->ops->forwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2484   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->N,x->N);
2485   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->M,b->N);
2486   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->m,b->n);
2487   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2488   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
2489   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
2490   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
2491   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2492   PetscFunctionReturn(0);
2493 }
2494 
2495 #undef __FUNCT__
2496 #define __FUNCT__ "MatBackwardSolve"
2497 /* @
2498    MatBackwardSolve - Solves U 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 MatBackwardSolve(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^backward solves
2523 
2524 .seealso: MatSolve(), MatForwardSolve()
2525 @ */
2526 PetscErrorCode PETSCMAT_DLLEXPORT MatBackwardSolve(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->backwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2540   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->N,x->N);
2541   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->M,b->N);
2542   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->m,b->n);
2543   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2544 
2545   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
2546   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
2547   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
2548   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2549   PetscFunctionReturn(0);
2550 }
2551 
2552 #undef __FUNCT__
2553 #define __FUNCT__ "MatSolveAdd"
2554 /*@
2555    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
2556 
2557    Collective on Mat and Vec
2558 
2559    Input Parameters:
2560 +  mat - the factored matrix
2561 .  b - the right-hand-side vector
2562 -  y - the vector to be added to
2563 
2564    Output Parameter:
2565 .  x - the result vector
2566 
2567    Notes:
2568    The vectors b and x cannot be the same.  I.e., one cannot
2569    call MatSolveAdd(A,x,y,x).
2570 
2571    Most users should employ the simplified KSP interface for linear solvers
2572    instead of working directly with matrix algebra routines such as this.
2573    See, e.g., KSPCreate().
2574 
2575    Level: developer
2576 
2577    Concepts: matrices^triangular solves
2578 
2579 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
2580 @*/
2581 PetscErrorCode PETSCMAT_DLLEXPORT MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
2582 {
2583   PetscScalar    one = 1.0;
2584   Vec            tmp;
2585   PetscErrorCode ierr;
2586 
2587   PetscFunctionBegin;
2588   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2589   PetscValidType(mat,1);
2590   PetscValidHeaderSpecific(y,VEC_COOKIE,2);
2591   PetscValidHeaderSpecific(b,VEC_COOKIE,3);
2592   PetscValidHeaderSpecific(x,VEC_COOKIE,4);
2593   PetscCheckSameComm(mat,1,b,2);
2594   PetscCheckSameComm(mat,1,y,2);
2595   PetscCheckSameComm(mat,1,x,3);
2596   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2597   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2598   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->N,x->N);
2599   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->M,b->N);
2600   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->M,y->N);
2601   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->m,b->n);
2602   if (x->n != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->n,y->n);
2603   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2604 
2605   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
2606   if (mat->ops->solveadd)  {
2607     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
2608   } else {
2609     /* do the solve then the add manually */
2610     if (x != y) {
2611       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
2612       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
2613     } else {
2614       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
2615       ierr = PetscLogObjectParent(mat,tmp);CHKERRQ(ierr);
2616       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
2617       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
2618       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
2619       ierr = VecDestroy(tmp);CHKERRQ(ierr);
2620     }
2621   }
2622   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
2623   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2624   PetscFunctionReturn(0);
2625 }
2626 
2627 #undef __FUNCT__
2628 #define __FUNCT__ "MatSolveTranspose"
2629 /*@
2630    MatSolveTranspose - Solves A' x = b, given a factored matrix.
2631 
2632    Collective on Mat and Vec
2633 
2634    Input Parameters:
2635 +  mat - the factored matrix
2636 -  b - the right-hand-side vector
2637 
2638    Output Parameter:
2639 .  x - the result vector
2640 
2641    Notes:
2642    The vectors b and x cannot be the same.  I.e., one cannot
2643    call MatSolveTranspose(A,x,x).
2644 
2645    Most users should employ the simplified KSP interface for linear solvers
2646    instead of working directly with matrix algebra routines such as this.
2647    See, e.g., KSPCreate().
2648 
2649    Level: developer
2650 
2651    Concepts: matrices^triangular solves
2652 
2653 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
2654 @*/
2655 PetscErrorCode PETSCMAT_DLLEXPORT MatSolveTranspose(Mat mat,Vec b,Vec x)
2656 {
2657   PetscErrorCode ierr;
2658 
2659   PetscFunctionBegin;
2660   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2661   PetscValidType(mat,1);
2662   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2663   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2664   PetscCheckSameComm(mat,1,b,2);
2665   PetscCheckSameComm(mat,1,x,3);
2666   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2667   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2668   if (!mat->ops->solvetranspose) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s",mat->type_name);
2669   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->M,x->N);
2670   if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->N,b->N);
2671   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2672   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
2673   ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
2674   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
2675   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2676   PetscFunctionReturn(0);
2677 }
2678 
2679 #undef __FUNCT__
2680 #define __FUNCT__ "MatSolveTransposeAdd"
2681 /*@
2682    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
2683                       factored matrix.
2684 
2685    Collective on Mat and Vec
2686 
2687    Input Parameters:
2688 +  mat - the factored matrix
2689 .  b - the right-hand-side vector
2690 -  y - the vector to be added to
2691 
2692    Output Parameter:
2693 .  x - the result vector
2694 
2695    Notes:
2696    The vectors b and x cannot be the same.  I.e., one cannot
2697    call MatSolveTransposeAdd(A,x,y,x).
2698 
2699    Most users should employ the simplified KSP interface for linear solvers
2700    instead of working directly with matrix algebra routines such as this.
2701    See, e.g., KSPCreate().
2702 
2703    Level: developer
2704 
2705    Concepts: matrices^triangular solves
2706 
2707 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
2708 @*/
2709 PetscErrorCode PETSCMAT_DLLEXPORT MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
2710 {
2711   PetscScalar    one = 1.0;
2712   PetscErrorCode ierr;
2713   Vec            tmp;
2714 
2715   PetscFunctionBegin;
2716   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2717   PetscValidType(mat,1);
2718   PetscValidHeaderSpecific(y,VEC_COOKIE,2);
2719   PetscValidHeaderSpecific(b,VEC_COOKIE,3);
2720   PetscValidHeaderSpecific(x,VEC_COOKIE,4);
2721   PetscCheckSameComm(mat,1,b,2);
2722   PetscCheckSameComm(mat,1,y,3);
2723   PetscCheckSameComm(mat,1,x,4);
2724   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2725   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2726   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->M,x->N);
2727   if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->N,b->N);
2728   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->N,y->N);
2729   if (x->n != y->n)   SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->n,y->n);
2730   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2731 
2732   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
2733   if (mat->ops->solvetransposeadd) {
2734     ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
2735   } else {
2736     /* do the solve then the add manually */
2737     if (x != y) {
2738       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
2739       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
2740     } else {
2741       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
2742       ierr = PetscLogObjectParent(mat,tmp);CHKERRQ(ierr);
2743       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
2744       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
2745       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
2746       ierr = VecDestroy(tmp);CHKERRQ(ierr);
2747     }
2748   }
2749   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
2750   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2751   PetscFunctionReturn(0);
2752 }
2753 /* ----------------------------------------------------------------*/
2754 
2755 #undef __FUNCT__
2756 #define __FUNCT__ "MatRelax"
2757 /*@
2758    MatRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.
2759 
2760    Collective on Mat and Vec
2761 
2762    Input Parameters:
2763 +  mat - the matrix
2764 .  b - the right hand side
2765 .  omega - the relaxation factor
2766 .  flag - flag indicating the type of SOR (see below)
2767 .  shift -  diagonal shift
2768 -  its - the number of iterations
2769 -  lits - the number of local iterations
2770 
2771    Output Parameters:
2772 .  x - the solution (can contain an initial guess)
2773 
2774    SOR Flags:
2775 .     SOR_FORWARD_SWEEP - forward SOR
2776 .     SOR_BACKWARD_SWEEP - backward SOR
2777 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
2778 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
2779 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
2780 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
2781 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
2782          upper/lower triangular part of matrix to
2783          vector (with omega)
2784 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
2785 
2786    Notes:
2787    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
2788    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
2789    on each processor.
2790 
2791    Application programmers will not generally use MatRelax() directly,
2792    but instead will employ the KSP/PC interface.
2793 
2794    Notes for Advanced Users:
2795    The flags are implemented as bitwise inclusive or operations.
2796    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
2797    to specify a zero initial guess for SSOR.
2798 
2799    Most users should employ the simplified KSP interface for linear solvers
2800    instead of working directly with matrix algebra routines such as this.
2801    See, e.g., KSPCreate().
2802 
2803    See also, MatPBRelax(). This routine will automatically call the point block
2804    version if the point version is not available.
2805 
2806    Level: developer
2807 
2808    Concepts: matrices^relaxation
2809    Concepts: matrices^SOR
2810    Concepts: matrices^Gauss-Seidel
2811 
2812 @*/
2813 PetscErrorCode PETSCMAT_DLLEXPORT MatRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
2814 {
2815   PetscErrorCode ierr;
2816 
2817   PetscFunctionBegin;
2818   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2819   PetscValidType(mat,1);
2820   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2821   PetscValidHeaderSpecific(x,VEC_COOKIE,8);
2822   PetscCheckSameComm(mat,1,b,2);
2823   PetscCheckSameComm(mat,1,x,8);
2824   if (!mat->ops->relax && !mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2825   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2826   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2827   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->N,x->N);
2828   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->M,b->N);
2829   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->m,b->n);
2830   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2831   ierr = PetscLogEventBegin(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2832   if (mat->ops->relax) {
2833     ierr =(*mat->ops->relax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
2834   } else {
2835     ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
2836   }
2837   ierr = PetscLogEventEnd(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2838   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2839   PetscFunctionReturn(0);
2840 }
2841 
2842 #undef __FUNCT__
2843 #define __FUNCT__ "MatPBRelax"
2844 /*@
2845    MatPBRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.
2846 
2847    Collective on Mat and Vec
2848 
2849    See MatRelax() for usage
2850 
2851    For multi-component PDEs where the Jacobian is stored in a point block format
2852    (with the PETSc BAIJ matrix formats) the relaxation is done one point block at
2853    a time. That is, the small (for example, 4 by 4) blocks along the diagonal are solved
2854    simultaneously (that is a 4 by 4 linear solve is done) to update all the values at a point.
2855 
2856    Level: developer
2857 
2858 @*/
2859 PetscErrorCode PETSCMAT_DLLEXPORT MatPBRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
2860 {
2861   PetscErrorCode ierr;
2862 
2863   PetscFunctionBegin;
2864   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2865   PetscValidType(mat,1);
2866   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2867   PetscValidHeaderSpecific(x,VEC_COOKIE,8);
2868   PetscCheckSameComm(mat,1,b,2);
2869   PetscCheckSameComm(mat,1,x,8);
2870   if (!mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2871   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2872   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2873   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->N,x->N);
2874   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->M,b->N);
2875   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->m,b->n);
2876   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2877 
2878   ierr = PetscLogEventBegin(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2879   ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
2880   ierr = PetscLogEventEnd(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2881   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2882   PetscFunctionReturn(0);
2883 }
2884 
2885 #undef __FUNCT__
2886 #define __FUNCT__ "MatCopy_Basic"
2887 /*
2888       Default matrix copy routine.
2889 */
2890 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
2891 {
2892   PetscErrorCode    ierr;
2893   PetscInt          i,rstart,rend,nz;
2894   const PetscInt    *cwork;
2895   const PetscScalar *vwork;
2896 
2897   PetscFunctionBegin;
2898   if (B->assembled) {
2899     ierr = MatZeroEntries(B);CHKERRQ(ierr);
2900   }
2901   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
2902   for (i=rstart; i<rend; i++) {
2903     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
2904     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
2905     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
2906   }
2907   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2908   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2909   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
2910   PetscFunctionReturn(0);
2911 }
2912 
2913 #undef __FUNCT__
2914 #define __FUNCT__ "MatCopy"
2915 /*@
2916    MatCopy - Copys a matrix to another matrix.
2917 
2918    Collective on Mat
2919 
2920    Input Parameters:
2921 +  A - the matrix
2922 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
2923 
2924    Output Parameter:
2925 .  B - where the copy is put
2926 
2927    Notes:
2928    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
2929    same nonzero pattern or the routine will crash.
2930 
2931    MatCopy() copies the matrix entries of a matrix to another existing
2932    matrix (after first zeroing the second matrix).  A related routine is
2933    MatConvert(), which first creates a new matrix and then copies the data.
2934 
2935    Level: intermediate
2936 
2937    Concepts: matrices^copying
2938 
2939 .seealso: MatConvert(), MatDuplicate()
2940 
2941 @*/
2942 PetscErrorCode PETSCMAT_DLLEXPORT MatCopy(Mat A,Mat B,MatStructure str)
2943 {
2944   PetscErrorCode ierr;
2945 
2946   PetscFunctionBegin;
2947   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
2948   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
2949   PetscValidType(A,1);
2950   PetscValidType(B,2);
2951   MatPreallocated(B);
2952   PetscCheckSameComm(A,1,B,2);
2953   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2954   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2955   if (A->M != B->M || A->N != B->N) SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%D,%D) (%D,%D)",A->M,B->M,A->N,B->N);
2956   ierr = MatPreallocated(A);CHKERRQ(ierr);
2957 
2958   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
2959   if (A->ops->copy) {
2960     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
2961   } else { /* generic conversion */
2962     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2963   }
2964   if (A->mapping) {
2965     if (B->mapping) {ierr = ISLocalToGlobalMappingDestroy(B->mapping);CHKERRQ(ierr);B->mapping = 0;}
2966     ierr = MatSetLocalToGlobalMapping(B,A->mapping);CHKERRQ(ierr);
2967   }
2968   if (A->bmapping) {
2969     if (B->bmapping) {ierr = ISLocalToGlobalMappingDestroy(B->bmapping);CHKERRQ(ierr);B->bmapping = 0;}
2970     ierr = MatSetLocalToGlobalMappingBlock(B,A->mapping);CHKERRQ(ierr);
2971   }
2972   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
2973   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
2974   PetscFunctionReturn(0);
2975 }
2976 
2977 #include "petscsys.h"
2978 PetscTruth MatConvertRegisterAllCalled = PETSC_FALSE;
2979 PetscFList MatConvertList              = 0;
2980 
2981 #undef __FUNCT__
2982 #define __FUNCT__ "MatConvertRegister"
2983 /*@C
2984     MatConvertRegister - Allows one to register a routine that converts a sparse matrix
2985         from one format to another.
2986 
2987   Not Collective
2988 
2989   Input Parameters:
2990 +   type - the type of matrix (defined in include/petscmat.h), for example, MATSEQAIJ.
2991 -   Converter - the function that reads the matrix from the binary file.
2992 
2993   Level: developer
2994 
2995 .seealso: MatConvertRegisterAll(), MatConvert()
2996 
2997 @*/
2998 PetscErrorCode PETSCMAT_DLLEXPORT MatConvertRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(Mat,MatType,MatReuse,Mat*))
2999 {
3000   PetscErrorCode ierr;
3001   char           fullname[PETSC_MAX_PATH_LEN];
3002 
3003   PetscFunctionBegin;
3004   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3005   ierr = PetscFListAdd(&MatConvertList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3006   PetscFunctionReturn(0);
3007 }
3008 
3009 #undef __FUNCT__
3010 #define __FUNCT__ "MatConvert"
3011 /*@C
3012    MatConvert - Converts a matrix to another matrix, either of the same
3013    or different type.
3014 
3015    Collective on Mat
3016 
3017    Input Parameters:
3018 +  mat - the matrix
3019 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3020    same type as the original matrix.
3021 -  reuse - denotes if the destination matrix is to be created or reused.  Currently
3022    MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3023    MAT_INITIAL_MATRIX.
3024    Output Parameter:
3025 .  M - pointer to place new matrix
3026 
3027    Notes:
3028    MatConvert() first creates a new matrix and then copies the data from
3029    the first matrix.  A related routine is MatCopy(), which copies the matrix
3030    entries of one matrix to another already existing matrix context.
3031 
3032    Level: intermediate
3033 
3034    Concepts: matrices^converting between storage formats
3035 
3036 .seealso: MatCopy(), MatDuplicate()
3037 @*/
3038 PetscErrorCode PETSCMAT_DLLEXPORT MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3039 {
3040   PetscErrorCode         ierr;
3041   PetscTruth             sametype,issame,flg;
3042   char                   convname[256],mtype[256];
3043   Mat                    B;
3044 
3045   PetscFunctionBegin;
3046   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3047   PetscValidType(mat,1);
3048   PetscValidPointer(M,3);
3049   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3050   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3051   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3052 
3053   ierr = PetscOptionsGetString(PETSC_NULL,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
3054   if (flg) {
3055     newtype = mtype;
3056   }
3057   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3058 
3059   ierr = PetscTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
3060   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
3061   if ((reuse==MAT_REUSE_MATRIX) && (mat != *M)) {
3062     SETERRQ(PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for inplace convertion currently");
3063   }
3064   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3065     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
3066   } else {
3067     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=PETSC_NULL;
3068     /*
3069        Order of precedence:
3070        1) See if a specialized converter is known to the current matrix.
3071        2) See if a specialized converter is known to the desired matrix class.
3072        3) See if a good general converter is registered for the desired class
3073           (as of 6/27/03 only MATMPIADJ falls into this category).
3074        4) See if a good general converter is known for the current matrix.
3075        5) Use a really basic converter.
3076     */
3077     ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
3078     ierr = PetscStrcat(convname,mat->type_name);CHKERRQ(ierr);
3079     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3080     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
3081     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3082     ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3083 
3084     if (!conv) {
3085       ierr = MatCreate(mat->comm,&B);CHKERRQ(ierr);
3086       ierr = MatSetSizes(B,0,0,0,0);CHKERRQ(ierr);
3087       ierr = MatSetType(B,newtype);CHKERRQ(ierr);
3088       ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3089       ierr = MatDestroy(B);CHKERRQ(ierr);
3090       if (!conv) {
3091         if (!MatConvertRegisterAllCalled) {
3092           ierr = MatConvertRegisterAll(PETSC_NULL);CHKERRQ(ierr);
3093         }
3094         ierr = PetscFListFind(mat->comm,MatConvertList,newtype,(void(**)(void))&conv);CHKERRQ(ierr);
3095         if (!conv) {
3096           if (mat->ops->convert) {
3097             conv = mat->ops->convert;
3098           } else {
3099             conv = MatConvert_Basic;
3100           }
3101         }
3102       }
3103     }
3104     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
3105   }
3106   B = *M;
3107   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3108   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3109   PetscFunctionReturn(0);
3110 }
3111 
3112 
3113 #undef __FUNCT__
3114 #define __FUNCT__ "MatDuplicate"
3115 /*@
3116    MatDuplicate - Duplicates a matrix including the non-zero structure.
3117 
3118    Collective on Mat
3119 
3120    Input Parameters:
3121 +  mat - the matrix
3122 -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
3123         values as well or not
3124 
3125    Output Parameter:
3126 .  M - pointer to place new matrix
3127 
3128    Level: intermediate
3129 
3130    Concepts: matrices^duplicating
3131 
3132 .seealso: MatCopy(), MatConvert()
3133 @*/
3134 PetscErrorCode PETSCMAT_DLLEXPORT MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
3135 {
3136   PetscErrorCode ierr;
3137   Mat            B;
3138 
3139   PetscFunctionBegin;
3140   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3141   PetscValidType(mat,1);
3142   PetscValidPointer(M,3);
3143   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3144   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3145   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3146 
3147   *M  = 0;
3148   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3149   if (!mat->ops->duplicate) {
3150     SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type");
3151   }
3152   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
3153   B = *M;
3154   if (mat->mapping) {
3155     ierr = MatSetLocalToGlobalMapping(B,mat->mapping);CHKERRQ(ierr);
3156   }
3157   if (mat->bmapping) {
3158     ierr = MatSetLocalToGlobalMappingBlock(B,mat->bmapping);CHKERRQ(ierr);
3159   }
3160   if (mat->rmap){
3161     if (!B->rmap){
3162       ierr = PetscMapCreateMPI(B->comm,B->m,B->M,&B->rmap);CHKERRQ(ierr);
3163     }
3164     ierr = PetscMemcpy(B->rmap,mat->rmap,sizeof(PetscMap));CHKERRQ(ierr);
3165   }
3166   if (mat->cmap){
3167     if (!B->cmap){
3168       ierr = PetscMapCreateMPI(B->comm,B->n,B->N,&B->cmap);CHKERRQ(ierr);
3169     }
3170     ierr = PetscMemcpy(B->cmap,mat->cmap,sizeof(PetscMap));CHKERRQ(ierr);
3171   }
3172   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3173   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3174   PetscFunctionReturn(0);
3175 }
3176 
3177 #undef __FUNCT__
3178 #define __FUNCT__ "MatGetDiagonal"
3179 /*@
3180    MatGetDiagonal - Gets the diagonal of a matrix.
3181 
3182    Collective on Mat and Vec
3183 
3184    Input Parameters:
3185 +  mat - the matrix
3186 -  v - the vector for storing the diagonal
3187 
3188    Output Parameter:
3189 .  v - the diagonal of the matrix
3190 
3191    Notes:
3192    For the SeqAIJ matrix format, this routine may also be called
3193    on a LU factored matrix; in that case it routines the reciprocal of
3194    the diagonal entries in U. It returns the entries permuted by the
3195    row and column permutation used during the symbolic factorization.
3196 
3197    Level: intermediate
3198 
3199    Concepts: matrices^accessing diagonals
3200 
3201 .seealso: MatGetRow(), MatGetSubmatrices(), MatGetSubmatrix(), MatGetRowMax()
3202 @*/
3203 PetscErrorCode PETSCMAT_DLLEXPORT MatGetDiagonal(Mat mat,Vec v)
3204 {
3205   PetscErrorCode ierr;
3206 
3207   PetscFunctionBegin;
3208   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3209   PetscValidType(mat,1);
3210   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3211   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3212   if (!mat->ops->getdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3213   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3214 
3215   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
3216   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3217   PetscFunctionReturn(0);
3218 }
3219 
3220 #undef __FUNCT__
3221 #define __FUNCT__ "MatGetRowMax"
3222 /*@
3223    MatGetRowMax - Gets the maximum value (in absolute value) of each
3224         row of the matrix
3225 
3226    Collective on Mat and Vec
3227 
3228    Input Parameters:
3229 .  mat - the matrix
3230 
3231    Output Parameter:
3232 .  v - the vector for storing the maximums
3233 
3234    Level: intermediate
3235 
3236    Concepts: matrices^getting row maximums
3237 
3238 .seealso: MatGetDiagonal(), MatGetSubmatrices(), MatGetSubmatrix()
3239 @*/
3240 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMax(Mat mat,Vec v)
3241 {
3242   PetscErrorCode ierr;
3243 
3244   PetscFunctionBegin;
3245   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3246   PetscValidType(mat,1);
3247   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3248   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3249   if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3250   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3251 
3252   ierr = (*mat->ops->getrowmax)(mat,v);CHKERRQ(ierr);
3253   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3254   PetscFunctionReturn(0);
3255 }
3256 
3257 #undef __FUNCT__
3258 #define __FUNCT__ "MatTranspose"
3259 /*@C
3260    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
3261 
3262    Collective on Mat
3263 
3264    Input Parameter:
3265 .  mat - the matrix to transpose
3266 
3267    Output Parameters:
3268 .  B - the transpose (or pass in PETSC_NULL for an in-place transpose)
3269 
3270    Level: intermediate
3271 
3272    Concepts: matrices^transposing
3273 
3274 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose()
3275 @*/
3276 PetscErrorCode PETSCMAT_DLLEXPORT MatTranspose(Mat mat,Mat *B)
3277 {
3278   PetscErrorCode ierr;
3279 
3280   PetscFunctionBegin;
3281   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3282   PetscValidType(mat,1);
3283   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3284   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3285   if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3286   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3287 
3288   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
3289   ierr = (*mat->ops->transpose)(mat,B);CHKERRQ(ierr);
3290   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
3291   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
3292   PetscFunctionReturn(0);
3293 }
3294 
3295 #undef __FUNCT__
3296 #define __FUNCT__ "MatIsTranspose"
3297 /*@C
3298    MatIsTranspose - Test whether a matrix is another one's transpose,
3299         or its own, in which case it tests symmetry.
3300 
3301    Collective on Mat
3302 
3303    Input Parameter:
3304 +  A - the matrix to test
3305 -  B - the matrix to test against, this can equal the first parameter
3306 
3307    Output Parameters:
3308 .  flg - the result
3309 
3310    Notes:
3311    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
3312    has a running time of the order of the number of nonzeros; the parallel
3313    test involves parallel copies of the block-offdiagonal parts of the matrix.
3314 
3315    Level: intermediate
3316 
3317    Concepts: matrices^transposing, matrix^symmetry
3318 
3319 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
3320 @*/
3321 PetscErrorCode PETSCMAT_DLLEXPORT MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
3322 {
3323   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);
3324 
3325   PetscFunctionBegin;
3326   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
3327   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
3328   PetscValidPointer(flg,3);
3329   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
3330   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
3331   if (f && g) {
3332     if (f==g) {
3333       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
3334     } else {
3335       SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
3336     }
3337   }
3338   PetscFunctionReturn(0);
3339 }
3340 
3341 #undef __FUNCT__
3342 #define __FUNCT__ "MatPermute"
3343 /*@C
3344    MatPermute - Creates a new matrix with rows and columns permuted from the
3345    original.
3346 
3347    Collective on Mat
3348 
3349    Input Parameters:
3350 +  mat - the matrix to permute
3351 .  row - row permutation, each processor supplies only the permutation for its rows
3352 -  col - column permutation, each processor needs the entire column permutation, that is
3353          this is the same size as the total number of columns in the matrix
3354 
3355    Output Parameters:
3356 .  B - the permuted matrix
3357 
3358    Level: advanced
3359 
3360    Concepts: matrices^permuting
3361 
3362 .seealso: MatGetOrdering()
3363 @*/
3364 PetscErrorCode PETSCMAT_DLLEXPORT MatPermute(Mat mat,IS row,IS col,Mat *B)
3365 {
3366   PetscErrorCode ierr;
3367 
3368   PetscFunctionBegin;
3369   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3370   PetscValidType(mat,1);
3371   PetscValidHeaderSpecific(row,IS_COOKIE,2);
3372   PetscValidHeaderSpecific(col,IS_COOKIE,3);
3373   PetscValidPointer(B,4);
3374   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3375   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3376   if (!mat->ops->permute) SETERRQ1(PETSC_ERR_SUP,"MatPermute not available for Mat type %s",mat->type_name);
3377   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3378 
3379   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
3380   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
3381   PetscFunctionReturn(0);
3382 }
3383 
3384 #undef __FUNCT__
3385 #define __FUNCT__ "MatPermuteSparsify"
3386 /*@C
3387   MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the
3388   original and sparsified to the prescribed tolerance.
3389 
3390   Collective on Mat
3391 
3392   Input Parameters:
3393 + A    - The matrix to permute
3394 . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
3395 . frac - The half-bandwidth as a fraction of the total size, or 0.0
3396 . tol  - The drop tolerance
3397 . rowp - The row permutation
3398 - colp - The column permutation
3399 
3400   Output Parameter:
3401 . B    - The permuted, sparsified matrix
3402 
3403   Level: advanced
3404 
3405   Note:
3406   The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
3407   restrict the half-bandwidth of the resulting matrix to 5% of the
3408   total matrix size.
3409 
3410 .keywords: matrix, permute, sparsify
3411 
3412 .seealso: MatGetOrdering(), MatPermute()
3413 @*/
3414 PetscErrorCode PETSCMAT_DLLEXPORT MatPermuteSparsify(Mat A, PetscInt band, PetscReal frac, PetscReal tol, IS rowp, IS colp, Mat *B)
3415 {
3416   IS                irowp, icolp;
3417   PetscInt          *rows, *cols;
3418   PetscInt          M, N, locRowStart, locRowEnd;
3419   PetscInt          nz, newNz;
3420   const PetscInt    *cwork;
3421   PetscInt          *cnew;
3422   const PetscScalar *vwork;
3423   PetscScalar       *vnew;
3424   PetscInt          bw, issize;
3425   PetscInt          row, locRow, newRow, col, newCol;
3426   PetscErrorCode    ierr;
3427 
3428   PetscFunctionBegin;
3429   PetscValidHeaderSpecific(A,    MAT_COOKIE,1);
3430   PetscValidHeaderSpecific(rowp, IS_COOKIE,5);
3431   PetscValidHeaderSpecific(colp, IS_COOKIE,6);
3432   PetscValidPointer(B,7);
3433   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
3434   if (A->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
3435   if (!A->ops->permutesparsify) {
3436     ierr = MatGetSize(A, &M, &N);CHKERRQ(ierr);
3437     ierr = MatGetOwnershipRange(A, &locRowStart, &locRowEnd);CHKERRQ(ierr);
3438     ierr = ISGetSize(rowp, &issize);CHKERRQ(ierr);
3439     if (issize != M) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for row permutation, should be %D", issize, M);
3440     ierr = ISGetSize(colp, &issize);CHKERRQ(ierr);
3441     if (issize != N) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for column permutation, should be %D", issize, N);
3442     ierr = ISInvertPermutation(rowp, 0, &irowp);CHKERRQ(ierr);
3443     ierr = ISGetIndices(irowp, &rows);CHKERRQ(ierr);
3444     ierr = ISInvertPermutation(colp, 0, &icolp);CHKERRQ(ierr);
3445     ierr = ISGetIndices(icolp, &cols);CHKERRQ(ierr);
3446     ierr = PetscMalloc(N * sizeof(PetscInt),         &cnew);CHKERRQ(ierr);
3447     ierr = PetscMalloc(N * sizeof(PetscScalar), &vnew);CHKERRQ(ierr);
3448 
3449     /* Setup bandwidth to include */
3450     if (band == PETSC_DECIDE) {
3451       if (frac <= 0.0)
3452         bw = (PetscInt) (M * 0.05);
3453       else
3454         bw = (PetscInt) (M * frac);
3455     } else {
3456       if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
3457       bw = band;
3458     }
3459 
3460     /* Put values into new matrix */
3461     ierr = MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B);CHKERRQ(ierr);
3462     for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) {
3463       ierr = MatGetRow(A, row, &nz, &cwork, &vwork);CHKERRQ(ierr);
3464       newRow   = rows[locRow]+locRowStart;
3465       for(col = 0, newNz = 0; col < nz; col++) {
3466         newCol = cols[cwork[col]];
3467         if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (PetscAbsScalar(vwork[col]) >= tol)) {
3468           cnew[newNz] = newCol;
3469           vnew[newNz] = vwork[col];
3470           newNz++;
3471         }
3472       }
3473       ierr = MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES);CHKERRQ(ierr);
3474       ierr = MatRestoreRow(A, row, &nz, &cwork, &vwork);CHKERRQ(ierr);
3475     }
3476     ierr = PetscFree(cnew);CHKERRQ(ierr);
3477     ierr = PetscFree(vnew);CHKERRQ(ierr);
3478     ierr = MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3479     ierr = MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3480     ierr = ISRestoreIndices(irowp, &rows);CHKERRQ(ierr);
3481     ierr = ISRestoreIndices(icolp, &cols);CHKERRQ(ierr);
3482     ierr = ISDestroy(irowp);CHKERRQ(ierr);
3483     ierr = ISDestroy(icolp);CHKERRQ(ierr);
3484   } else {
3485     ierr = (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B);CHKERRQ(ierr);
3486   }
3487   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
3488   PetscFunctionReturn(0);
3489 }
3490 
3491 #undef __FUNCT__
3492 #define __FUNCT__ "MatEqual"
3493 /*@
3494    MatEqual - Compares two matrices.
3495 
3496    Collective on Mat
3497 
3498    Input Parameters:
3499 +  A - the first matrix
3500 -  B - the second matrix
3501 
3502    Output Parameter:
3503 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
3504 
3505    Level: intermediate
3506 
3507    Concepts: matrices^equality between
3508 @*/
3509 PetscErrorCode PETSCMAT_DLLEXPORT MatEqual(Mat A,Mat B,PetscTruth *flg)
3510 {
3511   PetscErrorCode ierr;
3512 
3513   PetscFunctionBegin;
3514   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
3515   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
3516   PetscValidType(A,1);
3517   PetscValidType(B,2);
3518   MatPreallocated(B);
3519   PetscValidIntPointer(flg,3);
3520   PetscCheckSameComm(A,1,B,2);
3521   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3522   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3523   if (A->M != B->M || A->N != B->N) SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D %D %D",A->M,B->M,A->N,B->N);
3524   if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",A->type_name);
3525   if (!B->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",B->type_name);
3526   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);
3527   ierr = MatPreallocated(A);CHKERRQ(ierr);
3528 
3529   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
3530   PetscFunctionReturn(0);
3531 }
3532 
3533 #undef __FUNCT__
3534 #define __FUNCT__ "MatDiagonalScale"
3535 /*@
3536    MatDiagonalScale - Scales a matrix on the left and right by diagonal
3537    matrices that are stored as vectors.  Either of the two scaling
3538    matrices can be PETSC_NULL.
3539 
3540    Collective on Mat
3541 
3542    Input Parameters:
3543 +  mat - the matrix to be scaled
3544 .  l - the left scaling vector (or PETSC_NULL)
3545 -  r - the right scaling vector (or PETSC_NULL)
3546 
3547    Notes:
3548    MatDiagonalScale() computes A = LAR, where
3549    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
3550 
3551    Level: intermediate
3552 
3553    Concepts: matrices^diagonal scaling
3554    Concepts: diagonal scaling of matrices
3555 
3556 .seealso: MatScale()
3557 @*/
3558 PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalScale(Mat mat,Vec l,Vec r)
3559 {
3560   PetscErrorCode ierr;
3561 
3562   PetscFunctionBegin;
3563   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3564   PetscValidType(mat,1);
3565   if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3566   if (l) {PetscValidHeaderSpecific(l,VEC_COOKIE,2);PetscCheckSameComm(mat,1,l,2);}
3567   if (r) {PetscValidHeaderSpecific(r,VEC_COOKIE,3);PetscCheckSameComm(mat,1,r,3);}
3568   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3569   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3570   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3571 
3572   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3573   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
3574   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3575   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3576   PetscFunctionReturn(0);
3577 }
3578 
3579 #undef __FUNCT__
3580 #define __FUNCT__ "MatScale"
3581 /*@
3582     MatScale - Scales all elements of a matrix by a given number.
3583 
3584     Collective on Mat
3585 
3586     Input Parameters:
3587 +   mat - the matrix to be scaled
3588 -   a  - the scaling value
3589 
3590     Output Parameter:
3591 .   mat - the scaled matrix
3592 
3593     Level: intermediate
3594 
3595     Concepts: matrices^scaling all entries
3596 
3597 .seealso: MatDiagonalScale()
3598 @*/
3599 PetscErrorCode PETSCMAT_DLLEXPORT MatScale(Mat mat,PetscScalar a)
3600 {
3601   PetscErrorCode ierr;
3602 
3603   PetscFunctionBegin;
3604   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3605   PetscValidType(mat,1);
3606   if (!mat->ops->scale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
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->scale)(mat,a);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__ "MatNorm"
3620 /*@
3621    MatNorm - Calculates various norms of a matrix.
3622 
3623    Collective on Mat
3624 
3625    Input Parameters:
3626 +  mat - the matrix
3627 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
3628 
3629    Output Parameters:
3630 .  nrm - the resulting norm
3631 
3632    Level: intermediate
3633 
3634    Concepts: matrices^norm
3635    Concepts: norm^of matrix
3636 @*/
3637 PetscErrorCode PETSCMAT_DLLEXPORT MatNorm(Mat mat,NormType type,PetscReal *nrm)
3638 {
3639   PetscErrorCode ierr;
3640 
3641   PetscFunctionBegin;
3642   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3643   PetscValidType(mat,1);
3644   PetscValidScalarPointer(nrm,3);
3645 
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   if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3649   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3650 
3651   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
3652   PetscFunctionReturn(0);
3653 }
3654 
3655 /*
3656      This variable is used to prevent counting of MatAssemblyBegin() that
3657    are called from within a MatAssemblyEnd().
3658 */
3659 static PetscInt MatAssemblyEnd_InUse = 0;
3660 #undef __FUNCT__
3661 #define __FUNCT__ "MatAssemblyBegin"
3662 /*@
3663    MatAssemblyBegin - Begins assembling the matrix.  This routine should
3664    be called after completing all calls to MatSetValues().
3665 
3666    Collective on Mat
3667 
3668    Input Parameters:
3669 +  mat - the matrix
3670 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
3671 
3672    Notes:
3673    MatSetValues() generally caches the values.  The matrix is ready to
3674    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
3675    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
3676    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
3677    using the matrix.
3678 
3679    Level: beginner
3680 
3681    Concepts: matrices^assembling
3682 
3683 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
3684 @*/
3685 PetscErrorCode PETSCMAT_DLLEXPORT MatAssemblyBegin(Mat mat,MatAssemblyType type)
3686 {
3687   PetscErrorCode ierr;
3688 
3689   PetscFunctionBegin;
3690   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3691   PetscValidType(mat,1);
3692   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3693   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
3694   if (mat->assembled) {
3695     mat->was_assembled = PETSC_TRUE;
3696     mat->assembled     = PETSC_FALSE;
3697   }
3698   if (!MatAssemblyEnd_InUse) {
3699     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
3700     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
3701     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
3702   } else {
3703     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
3704   }
3705   PetscFunctionReturn(0);
3706 }
3707 
3708 #undef __FUNCT__
3709 #define __FUNCT__ "MatAssembed"
3710 /*@
3711    MatAssembled - Indicates if a matrix has been assembled and is ready for
3712      use; for example, in matrix-vector product.
3713 
3714    Collective on Mat
3715 
3716    Input Parameter:
3717 .  mat - the matrix
3718 
3719    Output Parameter:
3720 .  assembled - PETSC_TRUE or PETSC_FALSE
3721 
3722    Level: advanced
3723 
3724    Concepts: matrices^assembled?
3725 
3726 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
3727 @*/
3728 PetscErrorCode PETSCMAT_DLLEXPORT MatAssembled(Mat mat,PetscTruth *assembled)
3729 {
3730   PetscFunctionBegin;
3731   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3732   PetscValidType(mat,1);
3733   PetscValidPointer(assembled,2);
3734   *assembled = mat->assembled;
3735   PetscFunctionReturn(0);
3736 }
3737 
3738 #undef __FUNCT__
3739 #define __FUNCT__ "MatView_Private"
3740 /*
3741     Processes command line options to determine if/how a matrix
3742   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
3743 */
3744 PetscErrorCode MatView_Private(Mat mat)
3745 {
3746   PetscErrorCode    ierr;
3747   PetscTruth        flg;
3748   static PetscTruth incall = PETSC_FALSE;
3749 
3750   PetscFunctionBegin;
3751   if (incall) PetscFunctionReturn(0);
3752   incall = PETSC_TRUE;
3753   ierr = PetscOptionsBegin(mat->comm,mat->prefix,"Matrix Options","Mat");CHKERRQ(ierr);
3754     ierr = PetscOptionsName("-mat_view_info","Information on matrix size","MatView",&flg);CHKERRQ(ierr);
3755     if (flg) {
3756       ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
3757       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3758       ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3759     }
3760     ierr = PetscOptionsName("-mat_view_info_detailed","Nonzeros in the matrix","MatView",&flg);CHKERRQ(ierr);
3761     if (flg) {
3762       ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
3763       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3764       ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3765     }
3766     ierr = PetscOptionsName("-mat_view","Print matrix to stdout","MatView",&flg);CHKERRQ(ierr);
3767     if (flg) {
3768       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3769     }
3770     ierr = PetscOptionsName("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",&flg);CHKERRQ(ierr);
3771     if (flg) {
3772       ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr);
3773       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3774       ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3775     }
3776 #if defined(PETSC_USE_SOCKET_VIEWER)
3777     ierr = PetscOptionsName("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",&flg);CHKERRQ(ierr);
3778     if (flg) {
3779       ierr = MatView(mat,PETSC_VIEWER_SOCKET_(mat->comm));CHKERRQ(ierr);
3780       ierr = PetscViewerFlush(PETSC_VIEWER_SOCKET_(mat->comm));CHKERRQ(ierr);
3781     }
3782 #endif
3783     ierr = PetscOptionsName("-mat_view_binary","Save matrix to file in binary format","MatView",&flg);CHKERRQ(ierr);
3784     if (flg) {
3785       ierr = MatView(mat,PETSC_VIEWER_BINARY_(mat->comm));CHKERRQ(ierr);
3786       ierr = PetscViewerFlush(PETSC_VIEWER_BINARY_(mat->comm));CHKERRQ(ierr);
3787     }
3788   ierr = PetscOptionsEnd();CHKERRQ(ierr);
3789   /* cannot have inside PetscOptionsBegin() because uses PetscOptionsBegin() */
3790   ierr = PetscOptionsHasName(mat->prefix,"-mat_view_draw",&flg);CHKERRQ(ierr);
3791   if (flg) {
3792     ierr = PetscOptionsHasName(mat->prefix,"-mat_view_contour",&flg);CHKERRQ(ierr);
3793     if (flg) {
3794       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(mat->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
3795     }
3796     ierr = MatView(mat,PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3797     ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3798     if (flg) {
3799       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3800     }
3801   }
3802   incall = PETSC_FALSE;
3803   PetscFunctionReturn(0);
3804 }
3805 
3806 #undef __FUNCT__
3807 #define __FUNCT__ "MatAssemblyEnd"
3808 /*@
3809    MatAssemblyEnd - Completes assembling the matrix.  This routine should
3810    be called after MatAssemblyBegin().
3811 
3812    Collective on Mat
3813 
3814    Input Parameters:
3815 +  mat - the matrix
3816 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
3817 
3818    Options Database Keys:
3819 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
3820 .  -mat_view_info_detailed - Prints more detailed info
3821 .  -mat_view - Prints matrix in ASCII format
3822 .  -mat_view_matlab - Prints matrix in Matlab format
3823 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
3824 .  -display <name> - Sets display name (default is host)
3825 .  -draw_pause <sec> - Sets number of seconds to pause after display
3826 .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
3827 .  -viewer_socket_machine <machine>
3828 .  -viewer_socket_port <port>
3829 .  -mat_view_binary - save matrix to file in binary format
3830 -  -viewer_binary_filename <name>
3831 
3832    Notes:
3833    MatSetValues() generally caches the values.  The matrix is ready to
3834    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
3835    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
3836    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
3837    using the matrix.
3838 
3839    Level: beginner
3840 
3841 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
3842 @*/
3843 PetscErrorCode PETSCMAT_DLLEXPORT MatAssemblyEnd(Mat mat,MatAssemblyType type)
3844 {
3845   PetscErrorCode  ierr;
3846   static PetscInt inassm = 0;
3847   PetscTruth      flg;
3848 
3849   PetscFunctionBegin;
3850   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3851   PetscValidType(mat,1);
3852 
3853   inassm++;
3854   MatAssemblyEnd_InUse++;
3855   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
3856     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
3857     if (mat->ops->assemblyend) {
3858       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
3859     }
3860     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
3861   } else {
3862     if (mat->ops->assemblyend) {
3863       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
3864     }
3865   }
3866 
3867   /* Flush assembly is not a true assembly */
3868   if (type != MAT_FLUSH_ASSEMBLY) {
3869     mat->assembled  = PETSC_TRUE; mat->num_ass++;
3870   }
3871   mat->insertmode = NOT_SET_VALUES;
3872   MatAssemblyEnd_InUse--;
3873   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3874   if (!mat->symmetric_eternal) {
3875     mat->symmetric_set              = PETSC_FALSE;
3876     mat->hermitian_set              = PETSC_FALSE;
3877     mat->structurally_symmetric_set = PETSC_FALSE;
3878   }
3879   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
3880     ierr = MatView_Private(mat);CHKERRQ(ierr);
3881     ierr = PetscOptionsHasName(mat->prefix,"-mat_is_symmetric",&flg);CHKERRQ(ierr);
3882     if (flg) {
3883       PetscReal tol = 0.0;
3884       ierr = PetscOptionsGetReal(mat->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);CHKERRQ(ierr);
3885       ierr = MatIsSymmetric(mat,tol,&flg);CHKERRQ(ierr);
3886       if (flg) {
3887         ierr = PetscPrintf(mat->comm,"Matrix is symmetric (tolerance %g)\n",tol);CHKERRQ(ierr);
3888       } else {
3889         ierr = PetscPrintf(mat->comm,"Matrix is not symmetric (tolerance %g)\n",tol);CHKERRQ(ierr);
3890       }
3891     }
3892   }
3893   inassm--;
3894   ierr = PetscOptionsHasName(mat->prefix,"-help",&flg);CHKERRQ(ierr);
3895   if (flg) {
3896     ierr = MatPrintHelp(mat);CHKERRQ(ierr);
3897   }
3898   PetscFunctionReturn(0);
3899 }
3900 
3901 
3902 #undef __FUNCT__
3903 #define __FUNCT__ "MatCompress"
3904 /*@
3905    MatCompress - Tries to store the matrix in as little space as
3906    possible.  May fail if memory is already fully used, since it
3907    tries to allocate new space.
3908 
3909    Collective on Mat
3910 
3911    Input Parameters:
3912 .  mat - the matrix
3913 
3914    Level: advanced
3915 
3916 @*/
3917 PetscErrorCode PETSCMAT_DLLEXPORT MatCompress(Mat mat)
3918 {
3919   PetscErrorCode ierr;
3920 
3921   PetscFunctionBegin;
3922   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3923   PetscValidType(mat,1);
3924   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3925   if (mat->ops->compress) {ierr = (*mat->ops->compress)(mat);CHKERRQ(ierr);}
3926   PetscFunctionReturn(0);
3927 }
3928 
3929 #undef __FUNCT__
3930 #define __FUNCT__ "MatSetOption"
3931 /*@
3932    MatSetOption - Sets a parameter option for a matrix. Some options
3933    may be specific to certain storage formats.  Some options
3934    determine how values will be inserted (or added). Sorted,
3935    row-oriented input will generally assemble the fastest. The default
3936    is row-oriented, nonsorted input.
3937 
3938    Collective on Mat
3939 
3940    Input Parameters:
3941 +  mat - the matrix
3942 -  option - the option, one of those listed below (and possibly others),
3943              e.g., MAT_ROWS_SORTED, MAT_NEW_NONZERO_LOCATION_ERR
3944 
3945    Options Describing Matrix Structure:
3946 +    MAT_SYMMETRIC - symmetric in terms of both structure and value
3947 .    MAT_HERMITIAN - transpose is the complex conjugation
3948 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
3949 .    MAT_NOT_SYMMETRIC - not symmetric in value
3950 .    MAT_NOT_HERMITIAN - transpose is not the complex conjugation
3951 .    MAT_NOT_STRUCTURALLY_SYMMETRIC - not symmetric nonzero structure
3952 .    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
3953                             you set to be kept with all future use of the matrix
3954                             including after MatAssemblyBegin/End() which could
3955                             potentially change the symmetry structure, i.e. you
3956                             KNOW the matrix will ALWAYS have the property you set.
3957 -    MAT_NOT_SYMMETRY_ETERNAL - if MatAssemblyBegin/End() is called then the
3958                                 flags you set will be dropped (in case potentially
3959                                 the symmetry etc was lost).
3960 
3961    Options For Use with MatSetValues():
3962    Insert a logically dense subblock, which can be
3963 +    MAT_ROW_ORIENTED - row-oriented (default)
3964 .    MAT_COLUMN_ORIENTED - column-oriented
3965 .    MAT_ROWS_SORTED - sorted by row
3966 .    MAT_ROWS_UNSORTED - not sorted by row (default)
3967 .    MAT_COLUMNS_SORTED - sorted by column
3968 -    MAT_COLUMNS_UNSORTED - not sorted by column (default)
3969 
3970    Not these options reflect the data you pass in with MatSetValues(); it has
3971    nothing to do with how the data is stored internally in the matrix
3972    data structure.
3973 
3974    When (re)assembling a matrix, we can restrict the input for
3975    efficiency/debugging purposes.  These options include
3976 +    MAT_NO_NEW_NONZERO_LOCATIONS - additional insertions will not be
3977         allowed if they generate a new nonzero
3978 .    MAT_YES_NEW_NONZERO_LOCATIONS - additional insertions will be allowed
3979 .    MAT_NO_NEW_DIAGONALS - additional insertions will not be allowed if
3980          they generate a nonzero in a new diagonal (for block diagonal format only)
3981 .    MAT_YES_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
3982 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
3983 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
3984 -    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
3985 
3986    Notes:
3987    Some options are relevant only for particular matrix types and
3988    are thus ignored by others.  Other options are not supported by
3989    certain matrix types and will generate an error message if set.
3990 
3991    If using a Fortran 77 module to compute a matrix, one may need to
3992    use the column-oriented option (or convert to the row-oriented
3993    format).
3994 
3995    MAT_NO_NEW_NONZERO_LOCATIONS indicates that any add or insertion
3996    that would generate a new entry in the nonzero structure is instead
3997    ignored.  Thus, if memory has not alredy been allocated for this particular
3998    data, then the insertion is ignored. For dense matrices, in which
3999    the entire array is allocated, no entries are ever ignored.
4000    Set after the first MatAssemblyEnd()
4001 
4002    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
4003    that would generate a new entry in the nonzero structure instead produces
4004    an error. (Currently supported for AIJ and BAIJ formats only.)
4005    This is a useful flag when using SAME_NONZERO_PATTERN in calling
4006    KSPSetOperators() to ensure that the nonzero pattern truely does
4007    remain unchanged. Set after the first MatAssemblyEnd()
4008 
4009    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
4010    that would generate a new entry that has not been preallocated will
4011    instead produce an error. (Currently supported for AIJ and BAIJ formats
4012    only.) This is a useful flag when debugging matrix memory preallocation.
4013 
4014    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
4015    other processors should be dropped, rather than stashed.
4016    This is useful if you know that the "owning" processor is also
4017    always generating the correct matrix entries, so that PETSc need
4018    not transfer duplicate entries generated on another processor.
4019 
4020    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
4021    searches during matrix assembly. When this flag is set, the hash table
4022    is created during the first Matrix Assembly. This hash table is
4023    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
4024    to improve the searching of indices. MAT_NO_NEW_NONZERO_LOCATIONS flag
4025    should be used with MAT_USE_HASH_TABLE flag. This option is currently
4026    supported by MATMPIBAIJ format only.
4027 
4028    MAT_KEEP_ZEROED_ROWS indicates when MatZeroRows() is called the zeroed entries
4029    are kept in the nonzero structure
4030 
4031    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
4032    a zero location in the matrix
4033 
4034    MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
4035    ROWBS matrix types
4036 
4037    MAT_DO_NOT_USE_INODES - indicates not using inode version of the code - works
4038    with AIJ and ROWBS matrix types (database option "-mat_no_inode")
4039 
4040    Level: intermediate
4041 
4042    Concepts: matrices^setting options
4043 
4044 @*/
4045 PetscErrorCode PETSCMAT_DLLEXPORT MatSetOption(Mat mat,MatOption op)
4046 {
4047   PetscErrorCode ierr;
4048 
4049   PetscFunctionBegin;
4050   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4051   PetscValidType(mat,1);
4052   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4053   switch (op) {
4054   case MAT_SYMMETRIC:
4055     mat->symmetric                  = PETSC_TRUE;
4056     mat->structurally_symmetric     = PETSC_TRUE;
4057     mat->symmetric_set              = PETSC_TRUE;
4058     mat->structurally_symmetric_set = PETSC_TRUE;
4059     break;
4060   case MAT_HERMITIAN:
4061     mat->hermitian                  = PETSC_TRUE;
4062     mat->structurally_symmetric     = PETSC_TRUE;
4063     mat->hermitian_set              = PETSC_TRUE;
4064     mat->structurally_symmetric_set = PETSC_TRUE;
4065     break;
4066   case MAT_STRUCTURALLY_SYMMETRIC:
4067     mat->structurally_symmetric     = PETSC_TRUE;
4068     mat->structurally_symmetric_set = PETSC_TRUE;
4069     break;
4070   case MAT_NOT_SYMMETRIC:
4071     mat->symmetric                  = PETSC_FALSE;
4072     mat->symmetric_set              = PETSC_TRUE;
4073     break;
4074   case MAT_NOT_HERMITIAN:
4075     mat->hermitian                  = PETSC_FALSE;
4076     mat->hermitian_set              = PETSC_TRUE;
4077     break;
4078   case MAT_NOT_STRUCTURALLY_SYMMETRIC:
4079     mat->structurally_symmetric     = PETSC_FALSE;
4080     mat->structurally_symmetric_set = PETSC_TRUE;
4081     break;
4082   case MAT_SYMMETRY_ETERNAL:
4083     mat->symmetric_eternal          = PETSC_TRUE;
4084     break;
4085   case MAT_NOT_SYMMETRY_ETERNAL:
4086     mat->symmetric_eternal          = PETSC_FALSE;
4087     break;
4088   default:
4089     break;
4090   }
4091   if (mat->ops->setoption) {
4092     ierr = (*mat->ops->setoption)(mat,op);CHKERRQ(ierr);
4093   }
4094   PetscFunctionReturn(0);
4095 }
4096 
4097 #undef __FUNCT__
4098 #define __FUNCT__ "MatZeroEntries"
4099 /*@
4100    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
4101    this routine retains the old nonzero structure.
4102 
4103    Collective on Mat
4104 
4105    Input Parameters:
4106 .  mat - the matrix
4107 
4108    Level: intermediate
4109 
4110    Concepts: matrices^zeroing
4111 
4112 .seealso: MatZeroRows()
4113 @*/
4114 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroEntries(Mat mat)
4115 {
4116   PetscErrorCode ierr;
4117 
4118   PetscFunctionBegin;
4119   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4120   PetscValidType(mat,1);
4121   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4122   if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
4123   if (!mat->ops->zeroentries) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4124   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4125 
4126   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
4127   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
4128   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
4129   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4130   PetscFunctionReturn(0);
4131 }
4132 
4133 #undef __FUNCT__
4134 #define __FUNCT__ "MatZeroRows"
4135 /*@C
4136    MatZeroRows - Zeros all entries (except possibly the main diagonal)
4137    of a set of rows of a matrix.
4138 
4139    Collective on Mat
4140 
4141    Input Parameters:
4142 +  mat - the matrix
4143 .  numRows - the number of rows to remove
4144 .  rows - the global row indices
4145 -  diag - value put in all diagonals of eliminated rows
4146 
4147    Notes:
4148    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4149    but does not release memory.  For the dense and block diagonal
4150    formats this does not alter the nonzero structure.
4151 
4152    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
4153    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4154    merely zeroed.
4155 
4156    The user can set a value in the diagonal entry (or for the AIJ and
4157    row formats can optionally remove the main diagonal entry from the
4158    nonzero structure as well, by passing 0.0 as the final argument).
4159 
4160    For the parallel case, all processes that share the matrix (i.e.,
4161    those in the communicator used for matrix creation) MUST call this
4162    routine, regardless of whether any rows being zeroed are owned by
4163    them.
4164 
4165    Each processor should list the rows that IT wants zeroed
4166 
4167    Level: intermediate
4168 
4169    Concepts: matrices^zeroing rows
4170 
4171 .seealso: MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4172 @*/
4173 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4174 {
4175   PetscErrorCode ierr;
4176 
4177   PetscFunctionBegin;
4178   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4179   PetscValidType(mat,1);
4180   if (numRows) PetscValidIntPointer(rows,3);
4181   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4182   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4183   if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4184   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4185 
4186   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag);CHKERRQ(ierr);
4187   ierr = MatView_Private(mat);CHKERRQ(ierr);
4188   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4189   PetscFunctionReturn(0);
4190 }
4191 
4192 #undef __FUNCT__
4193 #define __FUNCT__ "MatZeroRowsIS"
4194 /*@C
4195    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
4196    of a set of rows of a matrix.
4197 
4198    Collective on Mat
4199 
4200    Input Parameters:
4201 +  mat - the matrix
4202 .  is - index set of rows to remove
4203 -  diag - value put in all diagonals of eliminated rows
4204 
4205    Notes:
4206    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4207    but does not release memory.  For the dense and block diagonal
4208    formats this does not alter the nonzero structure.
4209 
4210    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
4211    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4212    merely zeroed.
4213 
4214    The user can set a value in the diagonal entry (or for the AIJ and
4215    row formats can optionally remove the main diagonal entry from the
4216    nonzero structure as well, by passing 0.0 as the final argument).
4217 
4218    For the parallel case, all processes that share the matrix (i.e.,
4219    those in the communicator used for matrix creation) MUST call this
4220    routine, regardless of whether any rows being zeroed are owned by
4221    them.
4222 
4223    Each processor should list the rows that IT wants zeroed
4224 
4225    Level: intermediate
4226 
4227    Concepts: matrices^zeroing rows
4228 
4229 .seealso: MatZeroRows(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4230 @*/
4231 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsIS(Mat mat,IS is,PetscScalar diag)
4232 {
4233   PetscInt       numRows;
4234   PetscInt       *rows;
4235   PetscErrorCode ierr;
4236 
4237   PetscFunctionBegin;
4238   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4239   PetscValidType(mat,1);
4240   PetscValidHeaderSpecific(is,IS_COOKIE,2);
4241   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
4242   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
4243   ierr = MatZeroRows(mat,numRows,rows,diag);CHKERRQ(ierr);
4244   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
4245   PetscFunctionReturn(0);
4246 }
4247 
4248 #undef __FUNCT__
4249 #define __FUNCT__ "MatZeroRowsLocal"
4250 /*@C
4251    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
4252    of a set of rows of a matrix; using local numbering of rows.
4253 
4254    Collective on Mat
4255 
4256    Input Parameters:
4257 +  mat - the matrix
4258 .  numRows - the number of rows to remove
4259 .  rows - the global row indices
4260 -  diag - value put in all diagonals of eliminated rows
4261 
4262    Notes:
4263    Before calling MatZeroRowsLocal(), the user must first set the
4264    local-to-global mapping by calling MatSetLocalToGlobalMapping().
4265 
4266    For the AIJ matrix formats this removes the old nonzero structure,
4267    but does not release memory.  For the dense and block diagonal
4268    formats this does not alter the nonzero structure.
4269 
4270    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
4271    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4272    merely zeroed.
4273 
4274    The user can set a value in the diagonal entry (or for the AIJ and
4275    row formats can optionally remove the main diagonal entry from the
4276    nonzero structure as well, by passing 0.0 as the final argument).
4277 
4278    Level: intermediate
4279 
4280    Concepts: matrices^zeroing
4281 
4282 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
4283 @*/
4284 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4285 {
4286   PetscErrorCode ierr;
4287 
4288   PetscFunctionBegin;
4289   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4290   PetscValidType(mat,1);
4291   if (numRows) PetscValidIntPointer(rows,3);
4292   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4293   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4294   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4295 
4296   if (mat->ops->zerorowslocal) {
4297     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag);CHKERRQ(ierr);
4298   } else {
4299     IS is, newis;
4300     PetscInt *newRows;
4301 
4302     if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
4303     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,&is);CHKERRQ(ierr);
4304     ierr = ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);CHKERRQ(ierr);
4305     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
4306     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag);CHKERRQ(ierr);
4307     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
4308     ierr = ISDestroy(newis);CHKERRQ(ierr);
4309     ierr = ISDestroy(is);CHKERRQ(ierr);
4310   }
4311   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4312   PetscFunctionReturn(0);
4313 }
4314 
4315 #undef __FUNCT__
4316 #define __FUNCT__ "MatZeroRowsLocal"
4317 /*@C
4318    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
4319    of a set of rows of a matrix; using local numbering of rows.
4320 
4321    Collective on Mat
4322 
4323    Input Parameters:
4324 +  mat - the matrix
4325 .  is - index set of rows to remove
4326 -  diag - value put in all diagonals of eliminated rows
4327 
4328    Notes:
4329    Before calling MatZeroRowsLocal(), the user must first set the
4330    local-to-global mapping by calling MatSetLocalToGlobalMapping().
4331 
4332    For the AIJ matrix formats this removes the old nonzero structure,
4333    but does not release memory.  For the dense and block diagonal
4334    formats this does not alter the nonzero structure.
4335 
4336    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
4337    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4338    merely zeroed.
4339 
4340    The user can set a value in the diagonal entry (or for the AIJ and
4341    row formats can optionally remove the main diagonal entry from the
4342    nonzero structure as well, by passing 0.0 as the final argument).
4343 
4344    Level: intermediate
4345 
4346    Concepts: matrices^zeroing
4347 
4348 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
4349 @*/
4350 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag)
4351 {
4352   PetscErrorCode ierr;
4353   PetscInt       numRows;
4354   PetscInt       *rows;
4355 
4356   PetscFunctionBegin;
4357   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4358   PetscValidType(mat,1);
4359   PetscValidHeaderSpecific(is,IS_COOKIE,2);
4360   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4361   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4362   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4363 
4364   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
4365   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
4366   ierr = MatZeroRowsLocal(mat,numRows,rows,diag);CHKERRQ(ierr);
4367   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
4368   PetscFunctionReturn(0);
4369 }
4370 
4371 #undef __FUNCT__
4372 #define __FUNCT__ "MatGetSize"
4373 /*@
4374    MatGetSize - Returns the numbers of rows and columns in a matrix.
4375 
4376    Not Collective
4377 
4378    Input Parameter:
4379 .  mat - the matrix
4380 
4381    Output Parameters:
4382 +  m - the number of global rows
4383 -  n - the number of global columns
4384 
4385    Note: both output parameters can be PETSC_NULL on input.
4386 
4387    Level: beginner
4388 
4389    Concepts: matrices^size
4390 
4391 .seealso: MatGetLocalSize()
4392 @*/
4393 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
4394 {
4395   PetscFunctionBegin;
4396   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4397   if (m) *m = mat->M;
4398   if (n) *n = mat->N;
4399   PetscFunctionReturn(0);
4400 }
4401 
4402 #undef __FUNCT__
4403 #define __FUNCT__ "MatGetLocalSize"
4404 /*@
4405    MatGetLocalSize - Returns the number of rows and columns in a matrix
4406    stored locally.  This information may be implementation dependent, so
4407    use with care.
4408 
4409    Not Collective
4410 
4411    Input Parameters:
4412 .  mat - the matrix
4413 
4414    Output Parameters:
4415 +  m - the number of local rows
4416 -  n - the number of local columns
4417 
4418    Note: both output parameters can be PETSC_NULL on input.
4419 
4420    Level: beginner
4421 
4422    Concepts: matrices^local size
4423 
4424 .seealso: MatGetSize()
4425 @*/
4426 PetscErrorCode PETSCMAT_DLLEXPORT MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
4427 {
4428   PetscFunctionBegin;
4429   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4430   if (m) PetscValidIntPointer(m,2);
4431   if (n) PetscValidIntPointer(n,3);
4432   if (m) *m = mat->m;
4433   if (n) *n = mat->n;
4434   PetscFunctionReturn(0);
4435 }
4436 
4437 #undef __FUNCT__
4438 #define __FUNCT__ "MatGetOwnershipRange"
4439 /*@
4440    MatGetOwnershipRange - Returns the range of matrix rows owned by
4441    this processor, assuming that the matrix is laid out with the first
4442    n1 rows on the first processor, the next n2 rows on the second, etc.
4443    For certain parallel layouts this range may not be well defined.
4444 
4445    Not Collective
4446 
4447    Input Parameters:
4448 .  mat - the matrix
4449 
4450    Output Parameters:
4451 +  m - the global index of the first local row
4452 -  n - one more than the global index of the last local row
4453 
4454    Note: both output parameters can be PETSC_NULL on input.
4455 
4456    Level: beginner
4457 
4458    Concepts: matrices^row ownership
4459 @*/
4460 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
4461 {
4462   PetscErrorCode ierr;
4463 
4464   PetscFunctionBegin;
4465   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4466   PetscValidType(mat,1);
4467   if (m) PetscValidIntPointer(m,2);
4468   if (n) PetscValidIntPointer(n,3);
4469   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4470   ierr = PetscMapGetLocalRange(mat->rmap,m,n);CHKERRQ(ierr);
4471   PetscFunctionReturn(0);
4472 }
4473 
4474 #undef __FUNCT__
4475 #define __FUNCT__ "MatILUFactorSymbolic"
4476 /*@
4477    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
4478    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
4479    to complete the factorization.
4480 
4481    Collective on Mat
4482 
4483    Input Parameters:
4484 +  mat - the matrix
4485 .  row - row permutation
4486 .  column - column permutation
4487 -  info - structure containing
4488 $      levels - number of levels of fill.
4489 $      expected fill - as ratio of original fill.
4490 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
4491                 missing diagonal entries)
4492 
4493    Output Parameters:
4494 .  fact - new matrix that has been symbolically factored
4495 
4496    Notes:
4497    See the users manual for additional information about
4498    choosing the fill factor for better efficiency.
4499 
4500    Most users should employ the simplified KSP interface for linear solvers
4501    instead of working directly with matrix algebra routines such as this.
4502    See, e.g., KSPCreate().
4503 
4504    Level: developer
4505 
4506   Concepts: matrices^symbolic LU factorization
4507   Concepts: matrices^factorization
4508   Concepts: LU^symbolic factorization
4509 
4510 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
4511           MatGetOrdering(), MatFactorInfo
4512 
4513 @*/
4514 PetscErrorCode PETSCMAT_DLLEXPORT MatILUFactorSymbolic(Mat mat,IS row,IS col,MatFactorInfo *info,Mat *fact)
4515 {
4516   PetscErrorCode ierr;
4517 
4518   PetscFunctionBegin;
4519   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4520   PetscValidType(mat,1);
4521   PetscValidHeaderSpecific(row,IS_COOKIE,2);
4522   PetscValidHeaderSpecific(col,IS_COOKIE,3);
4523   PetscValidPointer(info,4);
4524   PetscValidPointer(fact,5);
4525   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
4526   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",info->fill);
4527   if (!mat->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",mat->type_name);
4528   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4529   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4530   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4531 
4532   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
4533   ierr = (*mat->ops->ilufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
4534   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
4535   PetscFunctionReturn(0);
4536 }
4537 
4538 #undef __FUNCT__
4539 #define __FUNCT__ "MatICCFactorSymbolic"
4540 /*@
4541    MatICCFactorSymbolic - Performs symbolic incomplete
4542    Cholesky factorization for a symmetric matrix.  Use
4543    MatCholeskyFactorNumeric() to complete the factorization.
4544 
4545    Collective on Mat
4546 
4547    Input Parameters:
4548 +  mat - the matrix
4549 .  perm - row and column permutation
4550 -  info - structure containing
4551 $      levels - number of levels of fill.
4552 $      expected fill - as ratio of original fill.
4553 
4554    Output Parameter:
4555 .  fact - the factored matrix
4556 
4557    Notes:
4558    Currently only no-fill factorization is supported.
4559 
4560    Most users should employ the simplified KSP interface for linear solvers
4561    instead of working directly with matrix algebra routines such as this.
4562    See, e.g., KSPCreate().
4563 
4564    Level: developer
4565 
4566   Concepts: matrices^symbolic incomplete Cholesky factorization
4567   Concepts: matrices^factorization
4568   Concepts: Cholsky^symbolic factorization
4569 
4570 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
4571 @*/
4572 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactorSymbolic(Mat mat,IS perm,MatFactorInfo *info,Mat *fact)
4573 {
4574   PetscErrorCode ierr;
4575 
4576   PetscFunctionBegin;
4577   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4578   PetscValidType(mat,1);
4579   PetscValidHeaderSpecific(perm,IS_COOKIE,2);
4580   PetscValidPointer(info,3);
4581   PetscValidPointer(fact,4);
4582   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4583   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
4584   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",info->fill);
4585   if (!mat->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",mat->type_name);
4586   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4587   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4588 
4589   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
4590   ierr = (*mat->ops->iccfactorsymbolic)(mat,perm,info,fact);CHKERRQ(ierr);
4591   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
4592   PetscFunctionReturn(0);
4593 }
4594 
4595 #undef __FUNCT__
4596 #define __FUNCT__ "MatGetArray"
4597 /*@C
4598    MatGetArray - Returns a pointer to the element values in the matrix.
4599    The result of this routine is dependent on the underlying matrix data
4600    structure, and may not even work for certain matrix types.  You MUST
4601    call MatRestoreArray() when you no longer need to access the array.
4602 
4603    Not Collective
4604 
4605    Input Parameter:
4606 .  mat - the matrix
4607 
4608    Output Parameter:
4609 .  v - the location of the values
4610 
4611 
4612    Fortran Note:
4613    This routine is used differently from Fortran, e.g.,
4614 .vb
4615         Mat         mat
4616         PetscScalar mat_array(1)
4617         PetscOffset i_mat
4618         PetscErrorCode ierr
4619         call MatGetArray(mat,mat_array,i_mat,ierr)
4620 
4621   C  Access first local entry in matrix; note that array is
4622   C  treated as one dimensional
4623         value = mat_array(i_mat + 1)
4624 
4625         [... other code ...]
4626         call MatRestoreArray(mat,mat_array,i_mat,ierr)
4627 .ve
4628 
4629    See the Fortran chapter of the users manual and
4630    petsc/src/mat/examples/tests for details.
4631 
4632    Level: advanced
4633 
4634    Concepts: matrices^access array
4635 
4636 .seealso: MatRestoreArray(), MatGetArrayF90()
4637 @*/
4638 PetscErrorCode PETSCMAT_DLLEXPORT MatGetArray(Mat mat,PetscScalar *v[])
4639 {
4640   PetscErrorCode ierr;
4641 
4642   PetscFunctionBegin;
4643   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4644   PetscValidType(mat,1);
4645   PetscValidPointer(v,2);
4646   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4647   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4648   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
4649   PetscFunctionReturn(0);
4650 }
4651 
4652 #undef __FUNCT__
4653 #define __FUNCT__ "MatRestoreArray"
4654 /*@C
4655    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
4656 
4657    Not Collective
4658 
4659    Input Parameter:
4660 +  mat - the matrix
4661 -  v - the location of the values
4662 
4663    Fortran Note:
4664    This routine is used differently from Fortran, e.g.,
4665 .vb
4666         Mat         mat
4667         PetscScalar mat_array(1)
4668         PetscOffset i_mat
4669         PetscErrorCode ierr
4670         call MatGetArray(mat,mat_array,i_mat,ierr)
4671 
4672   C  Access first local entry in matrix; note that array is
4673   C  treated as one dimensional
4674         value = mat_array(i_mat + 1)
4675 
4676         [... other code ...]
4677         call MatRestoreArray(mat,mat_array,i_mat,ierr)
4678 .ve
4679 
4680    See the Fortran chapter of the users manual and
4681    petsc/src/mat/examples/tests for details
4682 
4683    Level: advanced
4684 
4685 .seealso: MatGetArray(), MatRestoreArrayF90()
4686 @*/
4687 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreArray(Mat mat,PetscScalar *v[])
4688 {
4689   PetscErrorCode ierr;
4690 
4691   PetscFunctionBegin;
4692   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4693   PetscValidType(mat,1);
4694   PetscValidPointer(v,2);
4695 #if defined(PETSC_USE_DEBUG)
4696   CHKMEMQ;
4697 #endif
4698   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4699   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
4700   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4701   PetscFunctionReturn(0);
4702 }
4703 
4704 #undef __FUNCT__
4705 #define __FUNCT__ "MatGetSubMatrices"
4706 /*@C
4707    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
4708    points to an array of valid matrices, they may be reused to store the new
4709    submatrices.
4710 
4711    Collective on Mat
4712 
4713    Input Parameters:
4714 +  mat - the matrix
4715 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
4716 .  irow, icol - index sets of rows and columns to extract
4717 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4718 
4719    Output Parameter:
4720 .  submat - the array of submatrices
4721 
4722    Notes:
4723    MatGetSubMatrices() can extract only sequential submatrices
4724    (from both sequential and parallel matrices). Use MatGetSubMatrix()
4725    to extract a parallel submatrix.
4726 
4727    When extracting submatrices from a parallel matrix, each processor can
4728    form a different submatrix by setting the rows and columns of its
4729    individual index sets according to the local submatrix desired.
4730 
4731    When finished using the submatrices, the user should destroy
4732    them with MatDestroyMatrices().
4733 
4734    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
4735    original matrix has not changed from that last call to MatGetSubMatrices().
4736 
4737    This routine creates the matrices in submat; you should NOT create them before
4738    calling it. It also allocates the array of matrix pointers submat.
4739 
4740    For BAIJ matrices the index sets must respect the block structure, that is if they
4741    request one row/column in a block, they must request all rows/columns that are in
4742    that block. For example, if the block size is 2 you cannot request just row 0 and
4743    column 0.
4744 
4745    Fortran Note:
4746    The Fortran interface is slightly different from that given below; it
4747    requires one to pass in  as submat a Mat (integer) array of size at least m.
4748 
4749    Level: advanced
4750 
4751    Concepts: matrices^accessing submatrices
4752    Concepts: submatrices
4753 
4754 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal()
4755 @*/
4756 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
4757 {
4758   PetscErrorCode ierr;
4759   PetscInt        i;
4760   PetscTruth      eq;
4761 
4762   PetscFunctionBegin;
4763   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4764   PetscValidType(mat,1);
4765   if (n) {
4766     PetscValidPointer(irow,3);
4767     PetscValidHeaderSpecific(*irow,IS_COOKIE,3);
4768     PetscValidPointer(icol,4);
4769     PetscValidHeaderSpecific(*icol,IS_COOKIE,4);
4770   }
4771   PetscValidPointer(submat,6);
4772   if (n && scall == MAT_REUSE_MATRIX) {
4773     PetscValidPointer(*submat,6);
4774     PetscValidHeaderSpecific(**submat,MAT_COOKIE,6);
4775   }
4776   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4777   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4778   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4779   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4780 
4781   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
4782   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
4783   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
4784   for (i=0; i<n; i++) {
4785     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
4786       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
4787       if (eq) {
4788 	if (mat->symmetric){
4789 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC);CHKERRQ(ierr);
4790 	} else if (mat->hermitian) {
4791 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN);CHKERRQ(ierr);
4792 	} else if (mat->structurally_symmetric) {
4793 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC);CHKERRQ(ierr);
4794 	}
4795       }
4796     }
4797   }
4798   PetscFunctionReturn(0);
4799 }
4800 
4801 #undef __FUNCT__
4802 #define __FUNCT__ "MatDestroyMatrices"
4803 /*@C
4804    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
4805 
4806    Collective on Mat
4807 
4808    Input Parameters:
4809 +  n - the number of local matrices
4810 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
4811                        sequence of MatGetSubMatrices())
4812 
4813    Level: advanced
4814 
4815     Notes: Frees not only the matrices, but also the array that contains the matrices
4816 
4817 .seealso: MatGetSubMatrices()
4818 @*/
4819 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroyMatrices(PetscInt n,Mat *mat[])
4820 {
4821   PetscErrorCode ierr;
4822   PetscInt       i;
4823 
4824   PetscFunctionBegin;
4825   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
4826   PetscValidPointer(mat,2);
4827   for (i=0; i<n; i++) {
4828     ierr = MatDestroy((*mat)[i]);CHKERRQ(ierr);
4829   }
4830   /* memory is allocated even if n = 0 */
4831   ierr = PetscFree(*mat);CHKERRQ(ierr);
4832   PetscFunctionReturn(0);
4833 }
4834 
4835 #undef __FUNCT__
4836 #define __FUNCT__ "MatIncreaseOverlap"
4837 /*@
4838    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
4839    replaces the index sets by larger ones that represent submatrices with
4840    additional overlap.
4841 
4842    Collective on Mat
4843 
4844    Input Parameters:
4845 +  mat - the matrix
4846 .  n   - the number of index sets
4847 .  is  - the array of index sets (these index sets will changed during the call)
4848 -  ov  - the additional overlap requested
4849 
4850    Level: developer
4851 
4852    Concepts: overlap
4853    Concepts: ASM^computing overlap
4854 
4855 .seealso: MatGetSubMatrices()
4856 @*/
4857 PetscErrorCode PETSCMAT_DLLEXPORT MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
4858 {
4859   PetscErrorCode ierr;
4860 
4861   PetscFunctionBegin;
4862   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4863   PetscValidType(mat,1);
4864   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
4865   if (n) {
4866     PetscValidPointer(is,3);
4867     PetscValidHeaderSpecific(*is,IS_COOKIE,3);
4868   }
4869   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4870   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4871   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4872 
4873   if (!ov) PetscFunctionReturn(0);
4874   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4875   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
4876   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
4877   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
4878   PetscFunctionReturn(0);
4879 }
4880 
4881 #undef __FUNCT__
4882 #define __FUNCT__ "MatPrintHelp"
4883 /*@
4884    MatPrintHelp - Prints all the options for the matrix.
4885 
4886    Collective on Mat
4887 
4888    Input Parameter:
4889 .  mat - the matrix
4890 
4891    Options Database Keys:
4892 +  -help - Prints matrix options
4893 -  -h - Prints matrix options
4894 
4895    Level: developer
4896 
4897 .seealso: MatCreate(), MatCreateXXX()
4898 @*/
4899 PetscErrorCode PETSCMAT_DLLEXPORT MatPrintHelp(Mat mat)
4900 {
4901   static PetscTruth called = PETSC_FALSE;
4902   PetscErrorCode    ierr;
4903 
4904   PetscFunctionBegin;
4905   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4906   PetscValidType(mat,1);
4907   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4908 
4909   if (!called) {
4910     if (mat->ops->printhelp) {
4911       ierr = (*mat->ops->printhelp)(mat);CHKERRQ(ierr);
4912     }
4913     called = PETSC_TRUE;
4914   }
4915   PetscFunctionReturn(0);
4916 }
4917 
4918 #undef __FUNCT__
4919 #define __FUNCT__ "MatGetBlockSize"
4920 /*@
4921    MatGetBlockSize - Returns the matrix block size; useful especially for the
4922    block row and block diagonal formats.
4923 
4924    Not Collective
4925 
4926    Input Parameter:
4927 .  mat - the matrix
4928 
4929    Output Parameter:
4930 .  bs - block size
4931 
4932    Notes:
4933    Block diagonal formats are MATSEQBDIAG, MATMPIBDIAG.
4934    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
4935 
4936    Level: intermediate
4937 
4938    Concepts: matrices^block size
4939 
4940 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatCreateSeqBDiag(), MatCreateMPIBDiag()
4941 @*/
4942 PetscErrorCode PETSCMAT_DLLEXPORT MatGetBlockSize(Mat mat,PetscInt *bs)
4943 {
4944   PetscErrorCode ierr;
4945 
4946   PetscFunctionBegin;
4947   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4948   PetscValidType(mat,1);
4949   PetscValidIntPointer(bs,2);
4950   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4951   *bs = mat->bs;
4952   PetscFunctionReturn(0);
4953 }
4954 
4955 #undef __FUNCT__
4956 #define __FUNCT__ "MatSetBlockSize"
4957 /*@
4958    MatSetBlockSize - Sets the matrix block size; for many matrix types you
4959      cannot use this and MUST set the blocksize when you preallocate the matrix
4960 
4961    Not Collective
4962 
4963    Input Parameters:
4964 +  mat - the matrix
4965 -  bs - block size
4966 
4967    Notes:
4968      Only works for shell and AIJ matrices
4969 
4970    Level: intermediate
4971 
4972    Concepts: matrices^block size
4973 
4974 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatCreateSeqBDiag(), MatCreateMPIBDiag(), MatGetBlockSize()
4975 @*/
4976 PetscErrorCode PETSCMAT_DLLEXPORT MatSetBlockSize(Mat mat,PetscInt bs)
4977 {
4978   PetscErrorCode ierr;
4979 
4980   PetscFunctionBegin;
4981   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4982   PetscValidType(mat,1);
4983   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4984   if (mat->ops->setblocksize) {
4985     mat->bs = bs;
4986     ierr = (*mat->ops->setblocksize)(mat,bs);CHKERRQ(ierr);
4987   } else {
4988     SETERRQ1(PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",mat->type_name);
4989   }
4990   PetscFunctionReturn(0);
4991 }
4992 
4993 #undef __FUNCT__
4994 #define __FUNCT__ "MatGetRowIJ"
4995 /*@C
4996     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
4997 
4998    Collective on Mat
4999 
5000     Input Parameters:
5001 +   mat - the matrix
5002 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
5003 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5004                 symmetrized
5005 
5006     Output Parameters:
5007 +   n - number of rows in the (possibly compressed) matrix
5008 .   ia - the row pointers
5009 .   ja - the column indices
5010 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
5011 
5012     Level: developer
5013 
5014 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
5015 @*/
5016 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5017 {
5018   PetscErrorCode ierr;
5019 
5020   PetscFunctionBegin;
5021   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5022   PetscValidType(mat,1);
5023   PetscValidIntPointer(n,4);
5024   if (ia) PetscValidIntPointer(ia,5);
5025   if (ja) PetscValidIntPointer(ja,6);
5026   PetscValidIntPointer(done,7);
5027   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5028   if (!mat->ops->getrowij) *done = PETSC_FALSE;
5029   else {
5030     *done = PETSC_TRUE;
5031     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
5032   }
5033   PetscFunctionReturn(0);
5034 }
5035 
5036 #undef __FUNCT__
5037 #define __FUNCT__ "MatGetColumnIJ"
5038 /*@C
5039     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
5040 
5041     Collective on Mat
5042 
5043     Input Parameters:
5044 +   mat - the matrix
5045 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5046 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5047                 symmetrized
5048 
5049     Output Parameters:
5050 +   n - number of columns in the (possibly compressed) matrix
5051 .   ia - the column pointers
5052 .   ja - the row indices
5053 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
5054 
5055     Level: developer
5056 
5057 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5058 @*/
5059 PetscErrorCode PETSCMAT_DLLEXPORT MatGetColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5060 {
5061   PetscErrorCode ierr;
5062 
5063   PetscFunctionBegin;
5064   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5065   PetscValidType(mat,1);
5066   PetscValidIntPointer(n,4);
5067   if (ia) PetscValidIntPointer(ia,5);
5068   if (ja) PetscValidIntPointer(ja,6);
5069   PetscValidIntPointer(done,7);
5070   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5071   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
5072   else {
5073     *done = PETSC_TRUE;
5074     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
5075   }
5076   PetscFunctionReturn(0);
5077 }
5078 
5079 #undef __FUNCT__
5080 #define __FUNCT__ "MatRestoreRowIJ"
5081 /*@C
5082     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
5083     MatGetRowIJ().
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 - size of (possibly compressed) matrix
5095 .   ia - the row pointers
5096 .   ja - the column indices
5097 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5098 
5099     Level: developer
5100 
5101 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5102 @*/
5103 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreRowIJ(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   if (ia) PetscValidIntPointer(ia,5);
5111   if (ja) PetscValidIntPointer(ja,6);
5112   PetscValidIntPointer(done,7);
5113   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5114 
5115   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
5116   else {
5117     *done = PETSC_TRUE;
5118     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
5119   }
5120   PetscFunctionReturn(0);
5121 }
5122 
5123 #undef __FUNCT__
5124 #define __FUNCT__ "MatRestoreColumnIJ"
5125 /*@C
5126     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
5127     MatGetColumnIJ().
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 column pointers
5140 .   ja - the row indices
5141 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5142 
5143     Level: developer
5144 
5145 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
5146 @*/
5147 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreColumnIJ(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->restorecolumnij) *done = PETSC_FALSE;
5160   else {
5161     *done = PETSC_TRUE;
5162     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
5163   }
5164   PetscFunctionReturn(0);
5165 }
5166 
5167 #undef __FUNCT__
5168 #define __FUNCT__ "MatColoringPatch"
5169 /*@C
5170     MatColoringPatch -Used inside matrix coloring routines that
5171     use MatGetRowIJ() and/or MatGetColumnIJ().
5172 
5173     Collective on Mat
5174 
5175     Input Parameters:
5176 +   mat - the matrix
5177 .   n   - number of colors
5178 -   colorarray - array indicating color for each column
5179 
5180     Output Parameters:
5181 .   iscoloring - coloring generated using colorarray information
5182 
5183     Level: developer
5184 
5185 .seealso: MatGetRowIJ(), MatGetColumnIJ()
5186 
5187 @*/
5188 PetscErrorCode PETSCMAT_DLLEXPORT MatColoringPatch(Mat mat,PetscInt n,PetscInt ncolors,ISColoringValue colorarray[],ISColoring *iscoloring)
5189 {
5190   PetscErrorCode ierr;
5191 
5192   PetscFunctionBegin;
5193   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5194   PetscValidType(mat,1);
5195   PetscValidIntPointer(colorarray,4);
5196   PetscValidPointer(iscoloring,5);
5197   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5198 
5199   if (!mat->ops->coloringpatch){
5200     ierr = ISColoringCreate(mat->comm,n,colorarray,iscoloring);CHKERRQ(ierr);
5201   } else {
5202     ierr = (*mat->ops->coloringpatch)(mat,n,ncolors,colorarray,iscoloring);CHKERRQ(ierr);
5203   }
5204   PetscFunctionReturn(0);
5205 }
5206 
5207 
5208 #undef __FUNCT__
5209 #define __FUNCT__ "MatSetUnfactored"
5210 /*@
5211    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
5212 
5213    Collective on Mat
5214 
5215    Input Parameter:
5216 .  mat - the factored matrix to be reset
5217 
5218    Notes:
5219    This routine should be used only with factored matrices formed by in-place
5220    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
5221    format).  This option can save memory, for example, when solving nonlinear
5222    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
5223    ILU(0) preconditioner.
5224 
5225    Note that one can specify in-place ILU(0) factorization by calling
5226 .vb
5227      PCType(pc,PCILU);
5228      PCILUSeUseInPlace(pc);
5229 .ve
5230    or by using the options -pc_type ilu -pc_ilu_in_place
5231 
5232    In-place factorization ILU(0) can also be used as a local
5233    solver for the blocks within the block Jacobi or additive Schwarz
5234    methods (runtime option: -sub_pc_ilu_in_place).  See the discussion
5235    of these preconditioners in the users manual for details on setting
5236    local solver options.
5237 
5238    Most users should employ the simplified KSP interface for linear solvers
5239    instead of working directly with matrix algebra routines such as this.
5240    See, e.g., KSPCreate().
5241 
5242    Level: developer
5243 
5244 .seealso: PCILUSetUseInPlace(), PCLUSetUseInPlace()
5245 
5246    Concepts: matrices^unfactored
5247 
5248 @*/
5249 PetscErrorCode PETSCMAT_DLLEXPORT MatSetUnfactored(Mat mat)
5250 {
5251   PetscErrorCode ierr;
5252 
5253   PetscFunctionBegin;
5254   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5255   PetscValidType(mat,1);
5256   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5257   mat->factor = 0;
5258   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
5259   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
5260   PetscFunctionReturn(0);
5261 }
5262 
5263 /*MC
5264     MatGetArrayF90 - Accesses a matrix array from Fortran90.
5265 
5266     Synopsis:
5267     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
5268 
5269     Not collective
5270 
5271     Input Parameter:
5272 .   x - matrix
5273 
5274     Output Parameters:
5275 +   xx_v - the Fortran90 pointer to the array
5276 -   ierr - error code
5277 
5278     Example of Usage:
5279 .vb
5280       PetscScalar, pointer xx_v(:)
5281       ....
5282       call MatGetArrayF90(x,xx_v,ierr)
5283       a = xx_v(3)
5284       call MatRestoreArrayF90(x,xx_v,ierr)
5285 .ve
5286 
5287     Notes:
5288     Not yet supported for all F90 compilers
5289 
5290     Level: advanced
5291 
5292 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
5293 
5294     Concepts: matrices^accessing array
5295 
5296 M*/
5297 
5298 /*MC
5299     MatRestoreArrayF90 - Restores a matrix array that has been
5300     accessed with MatGetArrayF90().
5301 
5302     Synopsis:
5303     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
5304 
5305     Not collective
5306 
5307     Input Parameters:
5308 +   x - matrix
5309 -   xx_v - the Fortran90 pointer to the array
5310 
5311     Output Parameter:
5312 .   ierr - error code
5313 
5314     Example of Usage:
5315 .vb
5316        PetscScalar, pointer xx_v(:)
5317        ....
5318        call MatGetArrayF90(x,xx_v,ierr)
5319        a = xx_v(3)
5320        call MatRestoreArrayF90(x,xx_v,ierr)
5321 .ve
5322 
5323     Notes:
5324     Not yet supported for all F90 compilers
5325 
5326     Level: advanced
5327 
5328 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
5329 
5330 M*/
5331 
5332 
5333 #undef __FUNCT__
5334 #define __FUNCT__ "MatGetSubMatrix"
5335 /*@
5336     MatGetSubMatrix - Gets a single submatrix on the same number of processors
5337                       as the original matrix.
5338 
5339     Collective on Mat
5340 
5341     Input Parameters:
5342 +   mat - the original matrix
5343 .   isrow - rows this processor should obtain
5344 .   iscol - columns for all processors you wish to keep
5345 .   csize - number of columns "local" to this processor (does nothing for sequential
5346             matrices). This should match the result from VecGetLocalSize(x,...) if you
5347             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
5348 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
5349 
5350     Output Parameter:
5351 .   newmat - the new submatrix, of the same type as the old
5352 
5353     Level: advanced
5354 
5355     Notes: the iscol argument MUST be the same on each processor. You might be
5356     able to create the iscol argument with ISAllGather().
5357 
5358       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
5359    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
5360    to this routine with a mat of the same nonzero structure and with a cll of MAT_REUSE_MATRIX
5361    will reuse the matrix generated the first time.
5362 
5363     Concepts: matrices^submatrices
5364 
5365 .seealso: MatGetSubMatrices(), ISAllGather()
5366 @*/
5367 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrix(Mat mat,IS isrow,IS iscol,PetscInt csize,MatReuse cll,Mat *newmat)
5368 {
5369   PetscErrorCode ierr;
5370   PetscMPIInt    size;
5371   Mat            *local;
5372 
5373   PetscFunctionBegin;
5374   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5375   PetscValidHeaderSpecific(isrow,IS_COOKIE,2);
5376   PetscValidHeaderSpecific(iscol,IS_COOKIE,3);
5377   PetscValidPointer(newmat,6);
5378   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_COOKIE,6);
5379   PetscValidType(mat,1);
5380   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5381   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5382   ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr);
5383 
5384   /* if original matrix is on just one processor then use submatrix generated */
5385   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
5386     ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
5387     PetscFunctionReturn(0);
5388   } else if (!mat->ops->getsubmatrix && size == 1) {
5389     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
5390     *newmat = *local;
5391     ierr    = PetscFree(local);CHKERRQ(ierr);
5392     PetscFunctionReturn(0);
5393   }
5394 
5395   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5396   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscol,csize,cll,newmat);CHKERRQ(ierr);
5397   ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);
5398   PetscFunctionReturn(0);
5399 }
5400 
5401 #undef __FUNCT__
5402 #define __FUNCT__ "MatGetSubMatrixRaw"
5403 /*@
5404     MatGetSubMatrixRaw - Gets a single submatrix on the same number of processors
5405                          as the original matrix.
5406 
5407     Collective on Mat
5408 
5409     Input Parameters:
5410 +   mat - the original matrix
5411 .   nrows - the number of rows this processor should obtain
5412 .   rows - rows this processor should obtain
5413 .   ncols - the number of columns for all processors you wish to keep
5414 .   cols - columns for all processors you wish to keep
5415 .   csize - number of columns "local" to this processor (does nothing for sequential
5416             matrices). This should match the result from VecGetLocalSize(x,...) if you
5417             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
5418 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
5419 
5420     Output Parameter:
5421 .   newmat - the new submatrix, of the same type as the old
5422 
5423     Level: advanced
5424 
5425     Notes: the iscol argument MUST be the same on each processor. You might be
5426     able to create the iscol argument with ISAllGather().
5427 
5428       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
5429    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
5430    to this routine with a mat of the same nonzero structure and with a cll of MAT_REUSE_MATRIX
5431    will reuse the matrix generated the first time.
5432 
5433     Concepts: matrices^submatrices
5434 
5435 .seealso: MatGetSubMatrices(), ISAllGather()
5436 @*/
5437 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrixRaw(Mat mat,PetscInt nrows,const PetscInt rows[],PetscInt ncols,const PetscInt cols[],PetscInt csize,MatReuse cll,Mat *newmat)
5438 {
5439   IS             isrow, iscol;
5440   PetscErrorCode ierr;
5441 
5442   PetscFunctionBegin;
5443   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5444   PetscValidIntPointer(rows,2);
5445   PetscValidIntPointer(cols,3);
5446   PetscValidPointer(newmat,6);
5447   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_COOKIE,6);
5448   PetscValidType(mat,1);
5449   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5450   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5451   ierr = ISCreateGeneralWithArray(PETSC_COMM_SELF, nrows, (PetscInt *) rows, &isrow);CHKERRQ(ierr);
5452   ierr = ISCreateGeneralWithArray(PETSC_COMM_SELF, ncols, (PetscInt *) cols, &iscol);CHKERRQ(ierr);
5453   ierr = MatGetSubMatrix(mat, isrow, iscol, csize, cll, newmat);CHKERRQ(ierr);
5454   ierr = ISDestroy(isrow);CHKERRQ(ierr);
5455   ierr = ISDestroy(iscol);CHKERRQ(ierr);
5456   PetscFunctionReturn(0);
5457 }
5458 
5459 #undef __FUNCT__
5460 #define __FUNCT__ "MatGetPetscMaps"
5461 /*@C
5462    MatGetPetscMaps - Returns the maps associated with the matrix.
5463 
5464    Not Collective
5465 
5466    Input Parameter:
5467 .  mat - the matrix
5468 
5469    Output Parameters:
5470 +  rmap - the row (right) map
5471 -  cmap - the column (left) map
5472 
5473    Level: developer
5474 
5475    Concepts: maps^getting from matrix
5476 
5477 @*/
5478 PetscErrorCode PETSCMAT_DLLEXPORT MatGetPetscMaps(Mat mat,PetscMap *rmap,PetscMap *cmap)
5479 {
5480   PetscErrorCode ierr;
5481 
5482   PetscFunctionBegin;
5483   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5484   PetscValidType(mat,1);
5485   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5486   ierr = (*mat->ops->getmaps)(mat,rmap,cmap);CHKERRQ(ierr);
5487   PetscFunctionReturn(0);
5488 }
5489 
5490 /*
5491       Version that works for all PETSc matrices
5492 */
5493 #undef __FUNCT__
5494 #define __FUNCT__ "MatGetPetscMaps_Petsc"
5495 PetscErrorCode MatGetPetscMaps_Petsc(Mat mat,PetscMap *rmap,PetscMap *cmap)
5496 {
5497   PetscFunctionBegin;
5498   if (rmap) *rmap = mat->rmap;
5499   if (cmap) *cmap = mat->cmap;
5500   PetscFunctionReturn(0);
5501 }
5502 
5503 #undef __FUNCT__
5504 #define __FUNCT__ "MatStashSetInitialSize"
5505 /*@
5506    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
5507    used during the assembly process to store values that belong to
5508    other processors.
5509 
5510    Not Collective
5511 
5512    Input Parameters:
5513 +  mat   - the matrix
5514 .  size  - the initial size of the stash.
5515 -  bsize - the initial size of the block-stash(if used).
5516 
5517    Options Database Keys:
5518 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
5519 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
5520 
5521    Level: intermediate
5522 
5523    Notes:
5524      The block-stash is used for values set with MatSetValuesBlocked() while
5525      the stash is used for values set with MatSetValues()
5526 
5527      Run with the option -log_info and look for output of the form
5528      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
5529      to determine the appropriate value, MM, to use for size and
5530      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
5531      to determine the value, BMM to use for bsize
5532 
5533    Concepts: stash^setting matrix size
5534    Concepts: matrices^stash
5535 
5536 @*/
5537 PetscErrorCode PETSCMAT_DLLEXPORT MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
5538 {
5539   PetscErrorCode ierr;
5540 
5541   PetscFunctionBegin;
5542   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5543   PetscValidType(mat,1);
5544   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
5545   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
5546   PetscFunctionReturn(0);
5547 }
5548 
5549 #undef __FUNCT__
5550 #define __FUNCT__ "MatInterpolateAdd"
5551 /*@
5552    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
5553      the matrix
5554 
5555    Collective on Mat
5556 
5557    Input Parameters:
5558 +  mat   - the matrix
5559 .  x,y - the vectors
5560 -  w - where the result is stored
5561 
5562    Level: intermediate
5563 
5564    Notes:
5565     w may be the same vector as y.
5566 
5567     This allows one to use either the restriction or interpolation (its transpose)
5568     matrix to do the interpolation
5569 
5570     Concepts: interpolation
5571 
5572 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
5573 
5574 @*/
5575 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
5576 {
5577   PetscErrorCode ierr;
5578   PetscInt       M,N;
5579 
5580   PetscFunctionBegin;
5581   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5582   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
5583   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
5584   PetscValidHeaderSpecific(w,VEC_COOKIE,4);
5585   PetscValidType(A,1);
5586   ierr = MatPreallocated(A);CHKERRQ(ierr);
5587   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
5588   if (N > M) {
5589     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
5590   } else {
5591     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
5592   }
5593   PetscFunctionReturn(0);
5594 }
5595 
5596 #undef __FUNCT__
5597 #define __FUNCT__ "MatInterpolate"
5598 /*@
5599    MatInterpolate - y = A*x or A'*x depending on the shape of
5600      the matrix
5601 
5602    Collective on Mat
5603 
5604    Input Parameters:
5605 +  mat   - the matrix
5606 -  x,y - the vectors
5607 
5608    Level: intermediate
5609 
5610    Notes:
5611     This allows one to use either the restriction or interpolation (its transpose)
5612     matrix to do the interpolation
5613 
5614    Concepts: matrices^interpolation
5615 
5616 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
5617 
5618 @*/
5619 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolate(Mat A,Vec x,Vec y)
5620 {
5621   PetscErrorCode ierr;
5622   PetscInt       M,N;
5623 
5624   PetscFunctionBegin;
5625   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5626   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
5627   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
5628   PetscValidType(A,1);
5629   ierr = MatPreallocated(A);CHKERRQ(ierr);
5630   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
5631   if (N > M) {
5632     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
5633   } else {
5634     ierr = MatMult(A,x,y);CHKERRQ(ierr);
5635   }
5636   PetscFunctionReturn(0);
5637 }
5638 
5639 #undef __FUNCT__
5640 #define __FUNCT__ "MatRestrict"
5641 /*@
5642    MatRestrict - y = A*x or A'*x
5643 
5644    Collective on Mat
5645 
5646    Input Parameters:
5647 +  mat   - the matrix
5648 -  x,y - the vectors
5649 
5650    Level: intermediate
5651 
5652    Notes:
5653     This allows one to use either the restriction or interpolation (its transpose)
5654     matrix to do the restriction
5655 
5656    Concepts: matrices^restriction
5657 
5658 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
5659 
5660 @*/
5661 PetscErrorCode PETSCMAT_DLLEXPORT MatRestrict(Mat A,Vec x,Vec y)
5662 {
5663   PetscErrorCode ierr;
5664   PetscInt       M,N;
5665 
5666   PetscFunctionBegin;
5667   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5668   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
5669   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
5670   PetscValidType(A,1);
5671   ierr = MatPreallocated(A);CHKERRQ(ierr);
5672 
5673   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
5674   if (N > M) {
5675     ierr = MatMult(A,x,y);CHKERRQ(ierr);
5676   } else {
5677     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
5678   }
5679   PetscFunctionReturn(0);
5680 }
5681 
5682 #undef __FUNCT__
5683 #define __FUNCT__ "MatNullSpaceAttach"
5684 /*@C
5685    MatNullSpaceAttach - attaches a null space to a matrix.
5686         This null space will be removed from the resulting vector whenever
5687         MatMult() is called
5688 
5689    Collective on Mat
5690 
5691    Input Parameters:
5692 +  mat - the matrix
5693 -  nullsp - the null space object
5694 
5695    Level: developer
5696 
5697    Notes:
5698       Overwrites any previous null space that may have been attached
5699 
5700    Concepts: null space^attaching to matrix
5701 
5702 .seealso: MatCreate(), MatNullSpaceCreate()
5703 @*/
5704 PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
5705 {
5706   PetscErrorCode ierr;
5707 
5708   PetscFunctionBegin;
5709   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5710   PetscValidType(mat,1);
5711   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_COOKIE,2);
5712   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5713 
5714   if (mat->nullsp) {
5715     ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr);
5716   }
5717   mat->nullsp = nullsp;
5718   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
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->M != mat->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->M && !mat->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 *brealloc)
6243 {
6244   PetscErrorCode ierr;
6245   PetscFunctionBegin;
6246   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
6247   ierr = MatStashGetInfo_Private(&mat->bstash,nstash,reallocs);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->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->m,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->bs);CHKERRQ(ierr);}
6297   if (left) {ierr = VecSetBlockSize(*left,mat->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->M!=A->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->M,A->N);
6372   if (fill <=0.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"fill=%g must be > 0.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->N!=C->M) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->N,C->M);
6426   if (P->M!=A->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->M,A->N);
6427   if (A->M!=A->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->M,A->N);
6428   if (P->N!=C->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->N,C->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   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
6472   PetscValidType(P,2);
6473   MatPreallocated(P);
6474   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6475   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6476   PetscValidPointer(C,3);
6477 
6478   if (P->M!=A->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->M,A->N);
6479   if (A->M!=A->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->M,A->N);
6480   ierr = MatPreallocated(A);CHKERRQ(ierr);
6481   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
6482   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
6483   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
6484 
6485   ierr = MatSetBlockSize(*C,A->bs);CHKERRQ(ierr);
6486 
6487   PetscFunctionReturn(0);
6488 }
6489 
6490 #undef __FUNCT__
6491 #define __FUNCT__ "MatMatMult"
6492 /*@
6493    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
6494 
6495    Collective on Mat
6496 
6497    Input Parameters:
6498 +  A - the left matrix
6499 .  B - the right matrix
6500 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6501 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B))
6502 
6503    Output Parameters:
6504 .  C - the product matrix
6505 
6506    Notes:
6507    C will be created and must be destroyed by the user with MatDestroy().
6508 
6509    This routine is currently only implemented for pairs of AIJ matrices and classes
6510    which inherit from AIJ.  C will be of type MATAIJ.
6511 
6512    Level: intermediate
6513 
6514 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
6515 @*/
6516 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
6517 {
6518   PetscErrorCode ierr;
6519   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
6520   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
6521 
6522   PetscFunctionBegin;
6523   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6524   PetscValidType(A,1);
6525   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6526   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6527   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
6528   PetscValidType(B,2);
6529   MatPreallocated(B);
6530   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6531   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6532   PetscValidPointer(C,3);
6533   if (B->M!=A->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->M,A->N);
6534   if (fill <=0.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"fill=%g must be > 0.0",fill);
6535   ierr = MatPreallocated(A);CHKERRQ(ierr);
6536 
6537   /* For now, we do not dispatch based on the type of A and B */
6538   /* When implementations like _SeqAIJ_MAIJ exist, attack the multiple dispatch problem. */
6539   fA = A->ops->matmult;
6540   if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for A of type %s",A->type_name);
6541   fB = B->ops->matmult;
6542   if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",B->type_name);
6543   if (fB!=fA) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",A->type_name,B->type_name);
6544 
6545   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
6546   ierr = (*A->ops->matmult)(A,B,scall,fill,C);CHKERRQ(ierr);
6547   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
6548 
6549   PetscFunctionReturn(0);
6550 }
6551 
6552 #undef __FUNCT__
6553 #define __FUNCT__ "MatMatMultSymbolic"
6554 /*@
6555    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
6556    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
6557 
6558    Collective on Mat
6559 
6560    Input Parameters:
6561 +  A - the left matrix
6562 .  B - the right matrix
6563 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B))
6564 
6565    Output Parameters:
6566 .  C - the matrix containing the ij structure of product matrix
6567 
6568    Notes:
6569    C will be created as a MATSEQAIJ matrix and must be destroyed by the user with MatDestroy().
6570 
6571    This routine is currently only implemented for SeqAIJ matrices and classes which inherit from SeqAIJ.
6572 
6573    Level: intermediate
6574 
6575 .seealso: MatMatMult(), MatMatMultNumeric()
6576 @*/
6577 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
6578 {
6579   PetscErrorCode ierr;
6580   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
6581   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
6582 
6583   PetscFunctionBegin;
6584   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6585   PetscValidType(A,1);
6586   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6587   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6588 
6589   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
6590   PetscValidType(B,2);
6591   MatPreallocated(B);
6592   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6593   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6594   PetscValidPointer(C,3);
6595 
6596   if (B->M!=A->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->M,A->N);
6597   if (fill <=0.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"fill=%g must be > 0.0",fill);
6598   ierr = MatPreallocated(A);CHKERRQ(ierr);
6599 
6600   /* For now, we do not dispatch based on the type of A and P */
6601   /* When implementations like _SeqAIJ_MAIJ exist, attack the multiple dispatch problem. */
6602   Asymbolic = A->ops->matmultsymbolic;
6603   if (!Asymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for A of type %s",A->type_name);
6604   Bsymbolic = B->ops->matmultsymbolic;
6605   if (!Bsymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",B->type_name);
6606   if (Bsymbolic!=Asymbolic) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",A->type_name,B->type_name);
6607 
6608   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
6609   ierr = (*Asymbolic)(A,B,fill,C);CHKERRQ(ierr);
6610   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
6611 
6612   PetscFunctionReturn(0);
6613 }
6614 
6615 #undef __FUNCT__
6616 #define __FUNCT__ "MatMatMultNumeric"
6617 /*@
6618    MatMatMultNumeric - Performs the numeric matrix-matrix product.
6619    Call this routine after first calling MatMatMultSymbolic().
6620 
6621    Collective on Mat
6622 
6623    Input Parameters:
6624 +  A - the left matrix
6625 -  B - the right matrix
6626 
6627    Output Parameters:
6628 .  C - the product matrix, whose ij structure was defined from MatMatMultSymbolic().
6629 
6630    Notes:
6631    C must have been created with MatMatMultSymbolic.
6632 
6633    This routine is currently only implemented for SeqAIJ type matrices.
6634 
6635    Level: intermediate
6636 
6637 .seealso: MatMatMult(), MatMatMultSymbolic()
6638 @*/
6639 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultNumeric(Mat A,Mat B,Mat C)
6640 {
6641   PetscErrorCode ierr;
6642   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
6643   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
6644 
6645   PetscFunctionBegin;
6646 
6647   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6648   PetscValidType(A,1);
6649   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6650   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6651 
6652   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
6653   PetscValidType(B,2);
6654   MatPreallocated(B);
6655   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6656   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6657 
6658   PetscValidHeaderSpecific(C,MAT_COOKIE,3);
6659   PetscValidType(C,3);
6660   MatPreallocated(C);
6661   if (!C->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6662   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6663 
6664   if (B->N!=C->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->N,C->N);
6665   if (B->M!=A->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->M,A->N);
6666   if (A->M!=C->M) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->M,C->M);
6667   ierr = MatPreallocated(A);CHKERRQ(ierr);
6668 
6669   /* For now, we do not dispatch based on the type of A and B */
6670   /* When implementations like _SeqAIJ_MAIJ exist, attack the multiple dispatch problem. */
6671   Anumeric = A->ops->matmultnumeric;
6672   if (!Anumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for A of type %s",A->type_name);
6673   Bnumeric = B->ops->matmultnumeric;
6674   if (!Bnumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",B->type_name);
6675   if (Bnumeric!=Anumeric) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",A->type_name,B->type_name);
6676 
6677   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
6678   ierr = (*Anumeric)(A,B,C);CHKERRQ(ierr);
6679   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
6680 
6681   PetscFunctionReturn(0);
6682 }
6683 
6684 #undef __FUNCT__
6685 #define __FUNCT__ "MatMatMultTranspose"
6686 /*@
6687    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
6688 
6689    Collective on Mat
6690 
6691    Input Parameters:
6692 +  A - the left matrix
6693 .  B - the right matrix
6694 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6695 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B))
6696 
6697    Output Parameters:
6698 .  C - the product matrix
6699 
6700    Notes:
6701    C will be created and must be destroyed by the user with MatDestroy().
6702 
6703    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
6704    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
6705 
6706    Level: intermediate
6707 
6708 .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
6709 @*/
6710 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
6711 {
6712   PetscErrorCode ierr;
6713   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
6714   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
6715 
6716   PetscFunctionBegin;
6717   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6718   PetscValidType(A,1);
6719   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6720   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6721   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
6722   PetscValidType(B,2);
6723   MatPreallocated(B);
6724   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6725   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6726   PetscValidPointer(C,3);
6727   if (B->M!=A->M) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->M,A->M);
6728   if (fill <=0.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"fill=%g must be > 0.0",fill);
6729   ierr = MatPreallocated(A);CHKERRQ(ierr);
6730 
6731   fA = A->ops->matmulttranspose;
6732   if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",A->type_name);
6733   fB = B->ops->matmulttranspose;
6734   if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",B->type_name);
6735   if (fB!=fA) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultTranspose requires A, %s, to be compatible with B, %s",A->type_name,B->type_name);
6736 
6737   ierr = PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
6738   ierr = (*A->ops->matmulttranspose)(A,B,scall,fill,C);CHKERRQ(ierr);
6739   ierr = PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
6740 
6741   PetscFunctionReturn(0);
6742 }
6743