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