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