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