xref: /petsc/src/mat/interface/matrix.c (revision c2f951e6e70416e4a6125f4dc70c5df2d24072f1)
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   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2365   if (!(*fact)->ops->choleskyfactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2366   if (mat->rmap.N != (*fact)->rmap.N || mat->cmap.N != (*fact)->cmap.N) {
2367     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);
2368   }
2369   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2370 
2371   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
2372   ierr = (*(*fact)->ops->choleskyfactornumeric)(mat,info,fact);CHKERRQ(ierr);
2373   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
2374   ierr = PetscObjectStateIncrease((PetscObject)*fact);CHKERRQ(ierr);
2375   PetscFunctionReturn(0);
2376 }
2377 
2378 /* ----------------------------------------------------------------*/
2379 #undef __FUNCT__
2380 #define __FUNCT__ "MatSolve"
2381 /*@
2382    MatSolve - Solves A x = b, given a factored matrix.
2383 
2384    Collective on Mat and Vec
2385 
2386    Input Parameters:
2387 +  mat - the factored matrix
2388 -  b - the right-hand-side vector
2389 
2390    Output Parameter:
2391 .  x - the result vector
2392 
2393    Notes:
2394    The vectors b and x cannot be the same.  I.e., one cannot
2395    call MatSolve(A,x,x).
2396 
2397    Notes:
2398    Most users should employ the simplified KSP interface for linear solvers
2399    instead of working directly with matrix algebra routines such as this.
2400    See, e.g., KSPCreate().
2401 
2402    Level: developer
2403 
2404    Concepts: matrices^triangular solves
2405 
2406 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
2407 @*/
2408 PetscErrorCode PETSCMAT_DLLEXPORT MatSolve(Mat mat,Vec b,Vec x)
2409 {
2410   PetscErrorCode ierr;
2411 
2412   PetscFunctionBegin;
2413   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2414   PetscValidType(mat,1);
2415   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2416   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2417   PetscCheckSameComm(mat,1,b,2);
2418   PetscCheckSameComm(mat,1,x,3);
2419   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2420   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2421   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);
2422   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);
2423   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);
2424   if (!mat->rmap.N && !mat->cmap.N) PetscFunctionReturn(0);
2425   if (!mat->ops->solve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2426   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2427 
2428   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
2429   ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
2430   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
2431   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2432   PetscFunctionReturn(0);
2433 }
2434 
2435 #undef __FUNCT__
2436 #define __FUNCT__ "MatMatSolve"
2437 /*@
2438    MatMatSolve - Solves A X = B, given a factored matrix.
2439 
2440    Collective on Mat
2441 
2442    Input Parameters:
2443 +  mat - the factored matrix
2444 -  b - the right-hand-side vector
2445 
2446    Output Parameter:
2447 .  x - the result vector
2448 
2449    Notes:
2450    The vectors b and x cannot be the same.  I.e., one cannot
2451    call MatMatSolve(A,x,x).
2452 
2453    Notes:
2454    Most users should employ the simplified KSP interface for linear solvers
2455    instead of working directly with matrix algebra routines such as this.
2456    See, e.g., KSPCreate().
2457 
2458    Level: developer
2459 
2460    Concepts: matrices^triangular solves
2461 
2462 .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd()
2463 @*/
2464 PetscErrorCode PETSCMAT_DLLEXPORT MatMatSolve(Mat A,Mat B,Mat X)
2465 {
2466   PetscErrorCode ierr;
2467 
2468   PetscFunctionBegin;
2469   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
2470   PetscValidType(A,1);
2471   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
2472   PetscValidHeaderSpecific(X,MAT_COOKIE,3);
2473   PetscCheckSameComm(A,1,B,2);
2474   PetscCheckSameComm(A,1,X,3);
2475   if (X == B) SETERRQ(PETSC_ERR_ARG_IDN,"X and B must be different matrices");
2476   if (!A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2477   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);
2478   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);
2479   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);
2480   if (!A->rmap.N && !A->cmap.N) PetscFunctionReturn(0);
2481   if (!A->ops->matsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",A->type_name);
2482   ierr = MatPreallocated(A);CHKERRQ(ierr);
2483 
2484   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
2485   ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
2486   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
2487   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
2488   PetscFunctionReturn(0);
2489 }
2490 
2491 
2492 #undef __FUNCT__
2493 #define __FUNCT__ "MatForwardSolve"
2494 /* @
2495    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU.
2496 
2497    Collective on Mat and Vec
2498 
2499    Input Parameters:
2500 +  mat - the factored matrix
2501 -  b - the right-hand-side vector
2502 
2503    Output Parameter:
2504 .  x - the result vector
2505 
2506    Notes:
2507    MatSolve() should be used for most applications, as it performs
2508    a forward solve followed by a backward solve.
2509 
2510    The vectors b and x cannot be the same.  I.e., one cannot
2511    call MatForwardSolve(A,x,x).
2512 
2513    Most users should employ the simplified KSP interface for linear solvers
2514    instead of working directly with matrix algebra routines such as this.
2515    See, e.g., KSPCreate().
2516 
2517    Level: developer
2518 
2519    Concepts: matrices^forward solves
2520 
2521 .seealso: MatSolve(), MatBackwardSolve()
2522 @ */
2523 PetscErrorCode PETSCMAT_DLLEXPORT MatForwardSolve(Mat mat,Vec b,Vec x)
2524 {
2525   PetscErrorCode ierr;
2526 
2527   PetscFunctionBegin;
2528   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2529   PetscValidType(mat,1);
2530   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2531   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2532   PetscCheckSameComm(mat,1,b,2);
2533   PetscCheckSameComm(mat,1,x,3);
2534   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2535   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2536   if (!mat->ops->forwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2537   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);
2538   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);
2539   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);
2540   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2541   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
2542   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
2543   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
2544   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2545   PetscFunctionReturn(0);
2546 }
2547 
2548 #undef __FUNCT__
2549 #define __FUNCT__ "MatBackwardSolve"
2550 /* @
2551    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
2552 
2553    Collective on Mat and Vec
2554 
2555    Input Parameters:
2556 +  mat - the factored matrix
2557 -  b - the right-hand-side vector
2558 
2559    Output Parameter:
2560 .  x - the result vector
2561 
2562    Notes:
2563    MatSolve() should be used for most applications, as it performs
2564    a forward solve followed by a backward solve.
2565 
2566    The vectors b and x cannot be the same.  I.e., one cannot
2567    call MatBackwardSolve(A,x,x).
2568 
2569    Most users should employ the simplified KSP interface for linear solvers
2570    instead of working directly with matrix algebra routines such as this.
2571    See, e.g., KSPCreate().
2572 
2573    Level: developer
2574 
2575    Concepts: matrices^backward solves
2576 
2577 .seealso: MatSolve(), MatForwardSolve()
2578 @ */
2579 PetscErrorCode PETSCMAT_DLLEXPORT MatBackwardSolve(Mat mat,Vec b,Vec x)
2580 {
2581   PetscErrorCode ierr;
2582 
2583   PetscFunctionBegin;
2584   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2585   PetscValidType(mat,1);
2586   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2587   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2588   PetscCheckSameComm(mat,1,b,2);
2589   PetscCheckSameComm(mat,1,x,3);
2590   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2591   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2592   if (!mat->ops->backwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2593   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);
2594   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);
2595   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);
2596   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2597 
2598   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
2599   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
2600   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
2601   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2602   PetscFunctionReturn(0);
2603 }
2604 
2605 #undef __FUNCT__
2606 #define __FUNCT__ "MatSolveAdd"
2607 /*@
2608    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
2609 
2610    Collective on Mat and Vec
2611 
2612    Input Parameters:
2613 +  mat - the factored matrix
2614 .  b - the right-hand-side vector
2615 -  y - the vector to be added to
2616 
2617    Output Parameter:
2618 .  x - the result vector
2619 
2620    Notes:
2621    The vectors b and x cannot be the same.  I.e., one cannot
2622    call MatSolveAdd(A,x,y,x).
2623 
2624    Most users should employ the simplified KSP interface for linear solvers
2625    instead of working directly with matrix algebra routines such as this.
2626    See, e.g., KSPCreate().
2627 
2628    Level: developer
2629 
2630    Concepts: matrices^triangular solves
2631 
2632 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
2633 @*/
2634 PetscErrorCode PETSCMAT_DLLEXPORT MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
2635 {
2636   PetscScalar    one = 1.0;
2637   Vec            tmp;
2638   PetscErrorCode ierr;
2639 
2640   PetscFunctionBegin;
2641   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2642   PetscValidType(mat,1);
2643   PetscValidHeaderSpecific(y,VEC_COOKIE,2);
2644   PetscValidHeaderSpecific(b,VEC_COOKIE,3);
2645   PetscValidHeaderSpecific(x,VEC_COOKIE,4);
2646   PetscCheckSameComm(mat,1,b,2);
2647   PetscCheckSameComm(mat,1,y,2);
2648   PetscCheckSameComm(mat,1,x,3);
2649   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2650   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2651   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);
2652   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);
2653   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);
2654   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);
2655   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);
2656   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2657 
2658   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
2659   if (mat->ops->solveadd)  {
2660     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
2661   } else {
2662     /* do the solve then the add manually */
2663     if (x != y) {
2664       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
2665       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
2666     } else {
2667       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
2668       ierr = PetscLogObjectParent(mat,tmp);CHKERRQ(ierr);
2669       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
2670       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
2671       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
2672       ierr = VecDestroy(tmp);CHKERRQ(ierr);
2673     }
2674   }
2675   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
2676   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2677   PetscFunctionReturn(0);
2678 }
2679 
2680 #undef __FUNCT__
2681 #define __FUNCT__ "MatSolveTranspose"
2682 /*@
2683    MatSolveTranspose - Solves A' x = b, given a factored matrix.
2684 
2685    Collective on Mat and Vec
2686 
2687    Input Parameters:
2688 +  mat - the factored matrix
2689 -  b - the right-hand-side vector
2690 
2691    Output Parameter:
2692 .  x - the result vector
2693 
2694    Notes:
2695    The vectors b and x cannot be the same.  I.e., one cannot
2696    call MatSolveTranspose(A,x,x).
2697 
2698    Most users should employ the simplified KSP interface for linear solvers
2699    instead of working directly with matrix algebra routines such as this.
2700    See, e.g., KSPCreate().
2701 
2702    Level: developer
2703 
2704    Concepts: matrices^triangular solves
2705 
2706 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
2707 @*/
2708 PetscErrorCode PETSCMAT_DLLEXPORT MatSolveTranspose(Mat mat,Vec b,Vec x)
2709 {
2710   PetscErrorCode ierr;
2711 
2712   PetscFunctionBegin;
2713   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2714   PetscValidType(mat,1);
2715   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2716   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2717   PetscCheckSameComm(mat,1,b,2);
2718   PetscCheckSameComm(mat,1,x,3);
2719   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2720   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2721   if (!mat->ops->solvetranspose) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s",mat->type_name);
2722   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);
2723   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);
2724   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2725   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
2726   ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
2727   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
2728   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2729   PetscFunctionReturn(0);
2730 }
2731 
2732 #undef __FUNCT__
2733 #define __FUNCT__ "MatSolveTransposeAdd"
2734 /*@
2735    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
2736                       factored matrix.
2737 
2738    Collective on Mat and Vec
2739 
2740    Input Parameters:
2741 +  mat - the factored matrix
2742 .  b - the right-hand-side vector
2743 -  y - the vector to be added to
2744 
2745    Output Parameter:
2746 .  x - the result vector
2747 
2748    Notes:
2749    The vectors b and x cannot be the same.  I.e., one cannot
2750    call MatSolveTransposeAdd(A,x,y,x).
2751 
2752    Most users should employ the simplified KSP interface for linear solvers
2753    instead of working directly with matrix algebra routines such as this.
2754    See, e.g., KSPCreate().
2755 
2756    Level: developer
2757 
2758    Concepts: matrices^triangular solves
2759 
2760 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
2761 @*/
2762 PetscErrorCode PETSCMAT_DLLEXPORT MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
2763 {
2764   PetscScalar    one = 1.0;
2765   PetscErrorCode ierr;
2766   Vec            tmp;
2767 
2768   PetscFunctionBegin;
2769   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2770   PetscValidType(mat,1);
2771   PetscValidHeaderSpecific(y,VEC_COOKIE,2);
2772   PetscValidHeaderSpecific(b,VEC_COOKIE,3);
2773   PetscValidHeaderSpecific(x,VEC_COOKIE,4);
2774   PetscCheckSameComm(mat,1,b,2);
2775   PetscCheckSameComm(mat,1,y,3);
2776   PetscCheckSameComm(mat,1,x,4);
2777   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2778   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2779   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);
2780   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);
2781   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);
2782   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);
2783   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2784 
2785   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
2786   if (mat->ops->solvetransposeadd) {
2787     ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
2788   } else {
2789     /* do the solve then the add manually */
2790     if (x != y) {
2791       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
2792       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
2793     } else {
2794       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
2795       ierr = PetscLogObjectParent(mat,tmp);CHKERRQ(ierr);
2796       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
2797       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
2798       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
2799       ierr = VecDestroy(tmp);CHKERRQ(ierr);
2800     }
2801   }
2802   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
2803   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2804   PetscFunctionReturn(0);
2805 }
2806 /* ----------------------------------------------------------------*/
2807 
2808 #undef __FUNCT__
2809 #define __FUNCT__ "MatRelax"
2810 /*@
2811    MatRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.
2812 
2813    Collective on Mat and Vec
2814 
2815    Input Parameters:
2816 +  mat - the matrix
2817 .  b - the right hand side
2818 .  omega - the relaxation factor
2819 .  flag - flag indicating the type of SOR (see below)
2820 .  shift -  diagonal shift
2821 -  its - the number of iterations
2822 -  lits - the number of local iterations
2823 
2824    Output Parameters:
2825 .  x - the solution (can contain an initial guess)
2826 
2827    SOR Flags:
2828 .     SOR_FORWARD_SWEEP - forward SOR
2829 .     SOR_BACKWARD_SWEEP - backward SOR
2830 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
2831 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
2832 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
2833 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
2834 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
2835          upper/lower triangular part of matrix to
2836          vector (with omega)
2837 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
2838 
2839    Notes:
2840    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
2841    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
2842    on each processor.
2843 
2844    Application programmers will not generally use MatRelax() directly,
2845    but instead will employ the KSP/PC interface.
2846 
2847    Notes for Advanced Users:
2848    The flags are implemented as bitwise inclusive or operations.
2849    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
2850    to specify a zero initial guess for SSOR.
2851 
2852    Most users should employ the simplified KSP interface for linear solvers
2853    instead of working directly with matrix algebra routines such as this.
2854    See, e.g., KSPCreate().
2855 
2856    See also, MatPBRelax(). This routine will automatically call the point block
2857    version if the point version is not available.
2858 
2859    Level: developer
2860 
2861    Concepts: matrices^relaxation
2862    Concepts: matrices^SOR
2863    Concepts: matrices^Gauss-Seidel
2864 
2865 @*/
2866 PetscErrorCode PETSCMAT_DLLEXPORT MatRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
2867 {
2868   PetscErrorCode ierr;
2869 
2870   PetscFunctionBegin;
2871   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2872   PetscValidType(mat,1);
2873   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2874   PetscValidHeaderSpecific(x,VEC_COOKIE,8);
2875   PetscCheckSameComm(mat,1,b,2);
2876   PetscCheckSameComm(mat,1,x,8);
2877   if (!mat->ops->relax && !mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2878   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2879   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2880   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);
2881   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);
2882   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);
2883   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2884   ierr = PetscLogEventBegin(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2885   if (mat->ops->relax) {
2886     ierr =(*mat->ops->relax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
2887   } else {
2888     ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
2889   }
2890   ierr = PetscLogEventEnd(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2891   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2892   PetscFunctionReturn(0);
2893 }
2894 
2895 #undef __FUNCT__
2896 #define __FUNCT__ "MatPBRelax"
2897 /*@
2898    MatPBRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.
2899 
2900    Collective on Mat and Vec
2901 
2902    See MatRelax() for usage
2903 
2904    For multi-component PDEs where the Jacobian is stored in a point block format
2905    (with the PETSc BAIJ matrix formats) the relaxation is done one point block at
2906    a time. That is, the small (for example, 4 by 4) blocks along the diagonal are solved
2907    simultaneously (that is a 4 by 4 linear solve is done) to update all the values at a point.
2908 
2909    Level: developer
2910 
2911 @*/
2912 PetscErrorCode PETSCMAT_DLLEXPORT MatPBRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
2913 {
2914   PetscErrorCode ierr;
2915 
2916   PetscFunctionBegin;
2917   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2918   PetscValidType(mat,1);
2919   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2920   PetscValidHeaderSpecific(x,VEC_COOKIE,8);
2921   PetscCheckSameComm(mat,1,b,2);
2922   PetscCheckSameComm(mat,1,x,8);
2923   if (!mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2924   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2925   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2926   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);
2927   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);
2928   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);
2929   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2930 
2931   ierr = PetscLogEventBegin(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2932   ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
2933   ierr = PetscLogEventEnd(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2934   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2935   PetscFunctionReturn(0);
2936 }
2937 
2938 #undef __FUNCT__
2939 #define __FUNCT__ "MatCopy_Basic"
2940 /*
2941       Default matrix copy routine.
2942 */
2943 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
2944 {
2945   PetscErrorCode    ierr;
2946   PetscInt          i,rstart,rend,nz;
2947   const PetscInt    *cwork;
2948   const PetscScalar *vwork;
2949 
2950   PetscFunctionBegin;
2951   if (B->assembled) {
2952     ierr = MatZeroEntries(B);CHKERRQ(ierr);
2953   }
2954   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
2955   for (i=rstart; i<rend; i++) {
2956     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
2957     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
2958     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
2959   }
2960   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2961   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2962   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
2963   PetscFunctionReturn(0);
2964 }
2965 
2966 #undef __FUNCT__
2967 #define __FUNCT__ "MatCopy"
2968 /*@
2969    MatCopy - Copys a matrix to another matrix.
2970 
2971    Collective on Mat
2972 
2973    Input Parameters:
2974 +  A - the matrix
2975 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
2976 
2977    Output Parameter:
2978 .  B - where the copy is put
2979 
2980    Notes:
2981    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
2982    same nonzero pattern or the routine will crash.
2983 
2984    MatCopy() copies the matrix entries of a matrix to another existing
2985    matrix (after first zeroing the second matrix).  A related routine is
2986    MatConvert(), which first creates a new matrix and then copies the data.
2987 
2988    Level: intermediate
2989 
2990    Concepts: matrices^copying
2991 
2992 .seealso: MatConvert(), MatDuplicate()
2993 
2994 @*/
2995 PetscErrorCode PETSCMAT_DLLEXPORT MatCopy(Mat A,Mat B,MatStructure str)
2996 {
2997   PetscErrorCode ierr;
2998 
2999   PetscFunctionBegin;
3000   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
3001   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
3002   PetscValidType(A,1);
3003   PetscValidType(B,2);
3004   MatPreallocated(B);
3005   PetscCheckSameComm(A,1,B,2);
3006   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3007   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3008   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);
3009   ierr = MatPreallocated(A);CHKERRQ(ierr);
3010 
3011   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3012   if (A->ops->copy) {
3013     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
3014   } else { /* generic conversion */
3015     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
3016   }
3017   if (A->mapping) {
3018     if (B->mapping) {ierr = ISLocalToGlobalMappingDestroy(B->mapping);CHKERRQ(ierr);B->mapping = 0;}
3019     ierr = MatSetLocalToGlobalMapping(B,A->mapping);CHKERRQ(ierr);
3020   }
3021   if (A->bmapping) {
3022     if (B->bmapping) {ierr = ISLocalToGlobalMappingDestroy(B->bmapping);CHKERRQ(ierr);B->bmapping = 0;}
3023     ierr = MatSetLocalToGlobalMappingBlock(B,A->mapping);CHKERRQ(ierr);
3024   }
3025   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3026   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3027   PetscFunctionReturn(0);
3028 }
3029 
3030 #include "petscsys.h"
3031 PetscTruth MatConvertRegisterAllCalled = PETSC_FALSE;
3032 PetscFList MatConvertList              = 0;
3033 
3034 #undef __FUNCT__
3035 #define __FUNCT__ "MatConvertRegister"
3036 /*@C
3037     MatConvertRegister - Allows one to register a routine that converts a sparse matrix
3038         from one format to another.
3039 
3040   Not Collective
3041 
3042   Input Parameters:
3043 +   type - the type of matrix (defined in include/petscmat.h), for example, MATSEQAIJ.
3044 -   Converter - the function that reads the matrix from the binary file.
3045 
3046   Level: developer
3047 
3048 .seealso: MatConvertRegisterAll(), MatConvert()
3049 
3050 @*/
3051 PetscErrorCode PETSCMAT_DLLEXPORT MatConvertRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(Mat,MatType,MatReuse,Mat*))
3052 {
3053   PetscErrorCode ierr;
3054   char           fullname[PETSC_MAX_PATH_LEN];
3055 
3056   PetscFunctionBegin;
3057   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3058   ierr = PetscFListAdd(&MatConvertList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3059   PetscFunctionReturn(0);
3060 }
3061 
3062 #undef __FUNCT__
3063 #define __FUNCT__ "MatConvert"
3064 /*@C
3065    MatConvert - Converts a matrix to another matrix, either of the same
3066    or different type.
3067 
3068    Collective on Mat
3069 
3070    Input Parameters:
3071 +  mat - the matrix
3072 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3073    same type as the original matrix.
3074 -  reuse - denotes if the destination matrix is to be created or reused.  Currently
3075    MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3076    MAT_INITIAL_MATRIX.
3077    Output Parameter:
3078 .  M - pointer to place new matrix
3079 
3080    Notes:
3081    MatConvert() first creates a new matrix and then copies the data from
3082    the first matrix.  A related routine is MatCopy(), which copies the matrix
3083    entries of one matrix to another already existing matrix context.
3084 
3085    Level: intermediate
3086 
3087    Concepts: matrices^converting between storage formats
3088 
3089 .seealso: MatCopy(), MatDuplicate()
3090 @*/
3091 PetscErrorCode PETSCMAT_DLLEXPORT MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3092 {
3093   PetscErrorCode         ierr;
3094   PetscTruth             sametype,issame,flg;
3095   char                   convname[256],mtype[256];
3096   Mat                    B;
3097 
3098   PetscFunctionBegin;
3099   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3100   PetscValidType(mat,1);
3101   PetscValidPointer(M,3);
3102   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3103   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3104   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3105 
3106   ierr = PetscOptionsGetString(PETSC_NULL,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
3107   if (flg) {
3108     newtype = mtype;
3109   }
3110   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3111 
3112   ierr = PetscTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
3113   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
3114   if ((reuse==MAT_REUSE_MATRIX) && (mat != *M)) {
3115     SETERRQ(PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for inplace convertion currently");
3116   }
3117   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3118     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
3119   } else {
3120     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=PETSC_NULL;
3121     /*
3122        Order of precedence:
3123        1) See if a specialized converter is known to the current matrix.
3124        2) See if a specialized converter is known to the desired matrix class.
3125        3) See if a good general converter is registered for the desired class
3126           (as of 6/27/03 only MATMPIADJ falls into this category).
3127        4) See if a good general converter is known for the current matrix.
3128        5) Use a really basic converter.
3129     */
3130     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3131     ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
3132     ierr = PetscStrcat(convname,mat->type_name);CHKERRQ(ierr);
3133     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3134     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
3135     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3136     ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3137 
3138     if (!conv) {
3139       /* 2)  See if a specialized converter is known to the desired matrix class. */
3140       ierr = MatCreate(mat->comm,&B);CHKERRQ(ierr);
3141       ierr = MatSetSizes(B,mat->rmap.n,mat->cmap.n,mat->rmap.N,mat->cmap.N);CHKERRQ(ierr);
3142       ierr = MatSetType(B,newtype);CHKERRQ(ierr);
3143       ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3144       ierr = MatDestroy(B);CHKERRQ(ierr);
3145       if (!conv) {
3146         /* 3) See if a good general converter is registered for the desired class */
3147         if (!MatConvertRegisterAllCalled) {
3148           ierr = MatConvertRegisterAll(PETSC_NULL);CHKERRQ(ierr);
3149         }
3150         ierr = PetscFListFind(mat->comm,MatConvertList,newtype,(void(**)(void))&conv);CHKERRQ(ierr);
3151         if (!conv) {
3152           /* 4) See if a good general converter is known for the current matrix */
3153           if (mat->ops->convert) {
3154             conv = mat->ops->convert;
3155           } else {
3156             /* 5) Use a really basic converter. */
3157             conv = MatConvert_Basic;
3158           }
3159         }
3160       }
3161     }
3162     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
3163   }
3164   B = *M;
3165   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3166   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3167   PetscFunctionReturn(0);
3168 }
3169 
3170 
3171 #undef __FUNCT__
3172 #define __FUNCT__ "MatDuplicate"
3173 /*@
3174    MatDuplicate - Duplicates a matrix including the non-zero structure.
3175 
3176    Collective on Mat
3177 
3178    Input Parameters:
3179 +  mat - the matrix
3180 -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
3181         values as well or not
3182 
3183    Output Parameter:
3184 .  M - pointer to place new matrix
3185 
3186    Level: intermediate
3187 
3188    Concepts: matrices^duplicating
3189 
3190 .seealso: MatCopy(), MatConvert()
3191 @*/
3192 PetscErrorCode PETSCMAT_DLLEXPORT MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
3193 {
3194   PetscErrorCode ierr;
3195   Mat            B;
3196 
3197   PetscFunctionBegin;
3198   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3199   PetscValidType(mat,1);
3200   PetscValidPointer(M,3);
3201   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3202   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3203   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3204 
3205   *M  = 0;
3206   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3207   if (!mat->ops->duplicate) {
3208     SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type");
3209   }
3210   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
3211   B = *M;
3212   if (mat->mapping) {
3213     ierr = MatSetLocalToGlobalMapping(B,mat->mapping);CHKERRQ(ierr);
3214   }
3215   if (mat->bmapping) {
3216     ierr = MatSetLocalToGlobalMappingBlock(B,mat->bmapping);CHKERRQ(ierr);
3217   }
3218   ierr = PetscMapCopy(mat->comm,&mat->rmap,&B->rmap);CHKERRQ(ierr);
3219   ierr = PetscMapCopy(mat->comm,&mat->cmap,&B->cmap);CHKERRQ(ierr);
3220 
3221   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3222   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3223   PetscFunctionReturn(0);
3224 }
3225 
3226 #undef __FUNCT__
3227 #define __FUNCT__ "MatGetDiagonal"
3228 /*@
3229    MatGetDiagonal - Gets the diagonal of a matrix.
3230 
3231    Collective on Mat and Vec
3232 
3233    Input Parameters:
3234 +  mat - the matrix
3235 -  v - the vector for storing the diagonal
3236 
3237    Output Parameter:
3238 .  v - the diagonal of the matrix
3239 
3240    Notes:
3241    For the SeqAIJ matrix format, this routine may also be called
3242    on a LU factored matrix; in that case it routines the reciprocal of
3243    the diagonal entries in U. It returns the entries permuted by the
3244    row and column permutation used during the symbolic factorization.
3245 
3246    Level: intermediate
3247 
3248    Concepts: matrices^accessing diagonals
3249 
3250 .seealso: MatGetRow(), MatGetSubmatrices(), MatGetSubmatrix(), MatGetRowMax()
3251 @*/
3252 PetscErrorCode PETSCMAT_DLLEXPORT MatGetDiagonal(Mat mat,Vec v)
3253 {
3254   PetscErrorCode ierr;
3255 
3256   PetscFunctionBegin;
3257   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3258   PetscValidType(mat,1);
3259   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3260   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3261   if (!mat->ops->getdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3262   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3263 
3264   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
3265   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3266   PetscFunctionReturn(0);
3267 }
3268 
3269 #undef __FUNCT__
3270 #define __FUNCT__ "MatGetRowMax"
3271 /*@
3272    MatGetRowMax - Gets the maximum value (in absolute value) of each
3273         row of the matrix
3274 
3275    Collective on Mat and Vec
3276 
3277    Input Parameters:
3278 .  mat - the matrix
3279 
3280    Output Parameter:
3281 .  v - the vector for storing the maximums
3282 
3283    Level: intermediate
3284 
3285    Concepts: matrices^getting row maximums
3286 
3287 .seealso: MatGetDiagonal(), MatGetSubmatrices(), MatGetSubmatrix()
3288 @*/
3289 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMax(Mat mat,Vec v)
3290 {
3291   PetscErrorCode ierr;
3292 
3293   PetscFunctionBegin;
3294   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3295   PetscValidType(mat,1);
3296   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3297   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3298   if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3299   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3300 
3301   ierr = (*mat->ops->getrowmax)(mat,v);CHKERRQ(ierr);
3302   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3303   PetscFunctionReturn(0);
3304 }
3305 
3306 #undef __FUNCT__
3307 #define __FUNCT__ "MatTranspose"
3308 /*@C
3309    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
3310 
3311    Collective on Mat
3312 
3313    Input Parameter:
3314 .  mat - the matrix to transpose
3315 
3316    Output Parameters:
3317 .  B - the transpose (or pass in PETSC_NULL for an in-place transpose)
3318 
3319    Level: intermediate
3320 
3321    Concepts: matrices^transposing
3322 
3323 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose()
3324 @*/
3325 PetscErrorCode PETSCMAT_DLLEXPORT MatTranspose(Mat mat,Mat *B)
3326 {
3327   PetscErrorCode ierr;
3328 
3329   PetscFunctionBegin;
3330   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3331   PetscValidType(mat,1);
3332   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3333   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3334   if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3335   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3336 
3337   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
3338   ierr = (*mat->ops->transpose)(mat,B);CHKERRQ(ierr);
3339   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
3340   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
3341   PetscFunctionReturn(0);
3342 }
3343 
3344 #undef __FUNCT__
3345 #define __FUNCT__ "MatIsTranspose"
3346 /*@C
3347    MatIsTranspose - Test whether a matrix is another one's transpose,
3348         or its own, in which case it tests symmetry.
3349 
3350    Collective on Mat
3351 
3352    Input Parameter:
3353 +  A - the matrix to test
3354 -  B - the matrix to test against, this can equal the first parameter
3355 
3356    Output Parameters:
3357 .  flg - the result
3358 
3359    Notes:
3360    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
3361    has a running time of the order of the number of nonzeros; the parallel
3362    test involves parallel copies of the block-offdiagonal parts of the matrix.
3363 
3364    Level: intermediate
3365 
3366    Concepts: matrices^transposing, matrix^symmetry
3367 
3368 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
3369 @*/
3370 PetscErrorCode PETSCMAT_DLLEXPORT MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
3371 {
3372   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);
3373 
3374   PetscFunctionBegin;
3375   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
3376   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
3377   PetscValidPointer(flg,3);
3378   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
3379   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
3380   if (f && g) {
3381     if (f==g) {
3382       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
3383     } else {
3384       SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
3385     }
3386   }
3387   PetscFunctionReturn(0);
3388 }
3389 
3390 #undef __FUNCT__
3391 #define __FUNCT__ "MatPermute"
3392 /*@C
3393    MatPermute - Creates a new matrix with rows and columns permuted from the
3394    original.
3395 
3396    Collective on Mat
3397 
3398    Input Parameters:
3399 +  mat - the matrix to permute
3400 .  row - row permutation, each processor supplies only the permutation for its rows
3401 -  col - column permutation, each processor needs the entire column permutation, that is
3402          this is the same size as the total number of columns in the matrix
3403 
3404    Output Parameters:
3405 .  B - the permuted matrix
3406 
3407    Level: advanced
3408 
3409    Concepts: matrices^permuting
3410 
3411 .seealso: MatGetOrdering()
3412 @*/
3413 PetscErrorCode PETSCMAT_DLLEXPORT MatPermute(Mat mat,IS row,IS col,Mat *B)
3414 {
3415   PetscErrorCode ierr;
3416 
3417   PetscFunctionBegin;
3418   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3419   PetscValidType(mat,1);
3420   PetscValidHeaderSpecific(row,IS_COOKIE,2);
3421   PetscValidHeaderSpecific(col,IS_COOKIE,3);
3422   PetscValidPointer(B,4);
3423   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3424   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3425   if (!mat->ops->permute) SETERRQ1(PETSC_ERR_SUP,"MatPermute not available for Mat type %s",mat->type_name);
3426   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3427 
3428   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
3429   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
3430   PetscFunctionReturn(0);
3431 }
3432 
3433 #undef __FUNCT__
3434 #define __FUNCT__ "MatPermuteSparsify"
3435 /*@C
3436   MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the
3437   original and sparsified to the prescribed tolerance.
3438 
3439   Collective on Mat
3440 
3441   Input Parameters:
3442 + A    - The matrix to permute
3443 . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
3444 . frac - The half-bandwidth as a fraction of the total size, or 0.0
3445 . tol  - The drop tolerance
3446 . rowp - The row permutation
3447 - colp - The column permutation
3448 
3449   Output Parameter:
3450 . B    - The permuted, sparsified matrix
3451 
3452   Level: advanced
3453 
3454   Note:
3455   The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
3456   restrict the half-bandwidth of the resulting matrix to 5% of the
3457   total matrix size.
3458 
3459 .keywords: matrix, permute, sparsify
3460 
3461 .seealso: MatGetOrdering(), MatPermute()
3462 @*/
3463 PetscErrorCode PETSCMAT_DLLEXPORT MatPermuteSparsify(Mat A, PetscInt band, PetscReal frac, PetscReal tol, IS rowp, IS colp, Mat *B)
3464 {
3465   IS                irowp, icolp;
3466   PetscInt          *rows, *cols;
3467   PetscInt          M, N, locRowStart, locRowEnd;
3468   PetscInt          nz, newNz;
3469   const PetscInt    *cwork;
3470   PetscInt          *cnew;
3471   const PetscScalar *vwork;
3472   PetscScalar       *vnew;
3473   PetscInt          bw, issize;
3474   PetscInt          row, locRow, newRow, col, newCol;
3475   PetscErrorCode    ierr;
3476 
3477   PetscFunctionBegin;
3478   PetscValidHeaderSpecific(A,    MAT_COOKIE,1);
3479   PetscValidHeaderSpecific(rowp, IS_COOKIE,5);
3480   PetscValidHeaderSpecific(colp, IS_COOKIE,6);
3481   PetscValidPointer(B,7);
3482   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
3483   if (A->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
3484   if (!A->ops->permutesparsify) {
3485     ierr = MatGetSize(A, &M, &N);CHKERRQ(ierr);
3486     ierr = MatGetOwnershipRange(A, &locRowStart, &locRowEnd);CHKERRQ(ierr);
3487     ierr = ISGetSize(rowp, &issize);CHKERRQ(ierr);
3488     if (issize != M) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for row permutation, should be %D", issize, M);
3489     ierr = ISGetSize(colp, &issize);CHKERRQ(ierr);
3490     if (issize != N) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for column permutation, should be %D", issize, N);
3491     ierr = ISInvertPermutation(rowp, 0, &irowp);CHKERRQ(ierr);
3492     ierr = ISGetIndices(irowp, &rows);CHKERRQ(ierr);
3493     ierr = ISInvertPermutation(colp, 0, &icolp);CHKERRQ(ierr);
3494     ierr = ISGetIndices(icolp, &cols);CHKERRQ(ierr);
3495     ierr = PetscMalloc(N * sizeof(PetscInt),         &cnew);CHKERRQ(ierr);
3496     ierr = PetscMalloc(N * sizeof(PetscScalar), &vnew);CHKERRQ(ierr);
3497 
3498     /* Setup bandwidth to include */
3499     if (band == PETSC_DECIDE) {
3500       if (frac <= 0.0)
3501         bw = (PetscInt) (M * 0.05);
3502       else
3503         bw = (PetscInt) (M * frac);
3504     } else {
3505       if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
3506       bw = band;
3507     }
3508 
3509     /* Put values into new matrix */
3510     ierr = MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B);CHKERRQ(ierr);
3511     for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) {
3512       ierr = MatGetRow(A, row, &nz, &cwork, &vwork);CHKERRQ(ierr);
3513       newRow   = rows[locRow]+locRowStart;
3514       for(col = 0, newNz = 0; col < nz; col++) {
3515         newCol = cols[cwork[col]];
3516         if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (PetscAbsScalar(vwork[col]) >= tol)) {
3517           cnew[newNz] = newCol;
3518           vnew[newNz] = vwork[col];
3519           newNz++;
3520         }
3521       }
3522       ierr = MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES);CHKERRQ(ierr);
3523       ierr = MatRestoreRow(A, row, &nz, &cwork, &vwork);CHKERRQ(ierr);
3524     }
3525     ierr = PetscFree(cnew);CHKERRQ(ierr);
3526     ierr = PetscFree(vnew);CHKERRQ(ierr);
3527     ierr = MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3528     ierr = MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3529     ierr = ISRestoreIndices(irowp, &rows);CHKERRQ(ierr);
3530     ierr = ISRestoreIndices(icolp, &cols);CHKERRQ(ierr);
3531     ierr = ISDestroy(irowp);CHKERRQ(ierr);
3532     ierr = ISDestroy(icolp);CHKERRQ(ierr);
3533   } else {
3534     ierr = (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B);CHKERRQ(ierr);
3535   }
3536   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
3537   PetscFunctionReturn(0);
3538 }
3539 
3540 #undef __FUNCT__
3541 #define __FUNCT__ "MatEqual"
3542 /*@
3543    MatEqual - Compares two matrices.
3544 
3545    Collective on Mat
3546 
3547    Input Parameters:
3548 +  A - the first matrix
3549 -  B - the second matrix
3550 
3551    Output Parameter:
3552 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
3553 
3554    Level: intermediate
3555 
3556    Concepts: matrices^equality between
3557 @*/
3558 PetscErrorCode PETSCMAT_DLLEXPORT MatEqual(Mat A,Mat B,PetscTruth *flg)
3559 {
3560   PetscErrorCode ierr;
3561 
3562   PetscFunctionBegin;
3563   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
3564   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
3565   PetscValidType(A,1);
3566   PetscValidType(B,2);
3567   MatPreallocated(B);
3568   PetscValidIntPointer(flg,3);
3569   PetscCheckSameComm(A,1,B,2);
3570   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3571   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3572   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);
3573   if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",A->type_name);
3574   if (!B->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",B->type_name);
3575   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);
3576   ierr = MatPreallocated(A);CHKERRQ(ierr);
3577 
3578   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
3579   PetscFunctionReturn(0);
3580 }
3581 
3582 #undef __FUNCT__
3583 #define __FUNCT__ "MatDiagonalScale"
3584 /*@
3585    MatDiagonalScale - Scales a matrix on the left and right by diagonal
3586    matrices that are stored as vectors.  Either of the two scaling
3587    matrices can be PETSC_NULL.
3588 
3589    Collective on Mat
3590 
3591    Input Parameters:
3592 +  mat - the matrix to be scaled
3593 .  l - the left scaling vector (or PETSC_NULL)
3594 -  r - the right scaling vector (or PETSC_NULL)
3595 
3596    Notes:
3597    MatDiagonalScale() computes A = LAR, where
3598    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
3599 
3600    Level: intermediate
3601 
3602    Concepts: matrices^diagonal scaling
3603    Concepts: diagonal scaling of matrices
3604 
3605 .seealso: MatScale()
3606 @*/
3607 PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalScale(Mat mat,Vec l,Vec r)
3608 {
3609   PetscErrorCode ierr;
3610 
3611   PetscFunctionBegin;
3612   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3613   PetscValidType(mat,1);
3614   if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3615   if (l) {PetscValidHeaderSpecific(l,VEC_COOKIE,2);PetscCheckSameComm(mat,1,l,2);}
3616   if (r) {PetscValidHeaderSpecific(r,VEC_COOKIE,3);PetscCheckSameComm(mat,1,r,3);}
3617   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3618   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3619   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3620 
3621   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3622   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
3623   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3624   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3625   PetscFunctionReturn(0);
3626 }
3627 
3628 #undef __FUNCT__
3629 #define __FUNCT__ "MatScale"
3630 /*@
3631     MatScale - Scales all elements of a matrix by a given number.
3632 
3633     Collective on Mat
3634 
3635     Input Parameters:
3636 +   mat - the matrix to be scaled
3637 -   a  - the scaling value
3638 
3639     Output Parameter:
3640 .   mat - the scaled matrix
3641 
3642     Level: intermediate
3643 
3644     Concepts: matrices^scaling all entries
3645 
3646 .seealso: MatDiagonalScale()
3647 @*/
3648 PetscErrorCode PETSCMAT_DLLEXPORT MatScale(Mat mat,PetscScalar a)
3649 {
3650   PetscErrorCode ierr;
3651 
3652   PetscFunctionBegin;
3653   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3654   PetscValidType(mat,1);
3655   if (!mat->ops->scale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3656   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3657   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3658   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3659 
3660   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3661   ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
3662   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3663   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3664   PetscFunctionReturn(0);
3665 }
3666 
3667 #undef __FUNCT__
3668 #define __FUNCT__ "MatNorm"
3669 /*@
3670    MatNorm - Calculates various norms of a matrix.
3671 
3672    Collective on Mat
3673 
3674    Input Parameters:
3675 +  mat - the matrix
3676 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
3677 
3678    Output Parameters:
3679 .  nrm - the resulting norm
3680 
3681    Level: intermediate
3682 
3683    Concepts: matrices^norm
3684    Concepts: norm^of matrix
3685 @*/
3686 PetscErrorCode PETSCMAT_DLLEXPORT MatNorm(Mat mat,NormType type,PetscReal *nrm)
3687 {
3688   PetscErrorCode ierr;
3689 
3690   PetscFunctionBegin;
3691   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3692   PetscValidType(mat,1);
3693   PetscValidScalarPointer(nrm,3);
3694 
3695   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3696   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3697   if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3698   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3699 
3700   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
3701   PetscFunctionReturn(0);
3702 }
3703 
3704 /*
3705      This variable is used to prevent counting of MatAssemblyBegin() that
3706    are called from within a MatAssemblyEnd().
3707 */
3708 static PetscInt MatAssemblyEnd_InUse = 0;
3709 #undef __FUNCT__
3710 #define __FUNCT__ "MatAssemblyBegin"
3711 /*@
3712    MatAssemblyBegin - Begins assembling the matrix.  This routine should
3713    be called after completing all calls to MatSetValues().
3714 
3715    Collective on Mat
3716 
3717    Input Parameters:
3718 +  mat - the matrix
3719 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
3720 
3721    Notes:
3722    MatSetValues() generally caches the values.  The matrix is ready to
3723    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
3724    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
3725    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
3726    using the matrix.
3727 
3728    Level: beginner
3729 
3730    Concepts: matrices^assembling
3731 
3732 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
3733 @*/
3734 PetscErrorCode PETSCMAT_DLLEXPORT MatAssemblyBegin(Mat mat,MatAssemblyType type)
3735 {
3736   PetscErrorCode ierr;
3737 
3738   PetscFunctionBegin;
3739   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3740   PetscValidType(mat,1);
3741   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3742   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
3743   if (mat->assembled) {
3744     mat->was_assembled = PETSC_TRUE;
3745     mat->assembled     = PETSC_FALSE;
3746   }
3747   if (!MatAssemblyEnd_InUse) {
3748     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
3749     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
3750     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
3751   } else {
3752     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
3753   }
3754   PetscFunctionReturn(0);
3755 }
3756 
3757 #undef __FUNCT__
3758 #define __FUNCT__ "MatAssembed"
3759 /*@
3760    MatAssembled - Indicates if a matrix has been assembled and is ready for
3761      use; for example, in matrix-vector product.
3762 
3763    Collective on Mat
3764 
3765    Input Parameter:
3766 .  mat - the matrix
3767 
3768    Output Parameter:
3769 .  assembled - PETSC_TRUE or PETSC_FALSE
3770 
3771    Level: advanced
3772 
3773    Concepts: matrices^assembled?
3774 
3775 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
3776 @*/
3777 PetscErrorCode PETSCMAT_DLLEXPORT MatAssembled(Mat mat,PetscTruth *assembled)
3778 {
3779   PetscFunctionBegin;
3780   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3781   PetscValidType(mat,1);
3782   PetscValidPointer(assembled,2);
3783   *assembled = mat->assembled;
3784   PetscFunctionReturn(0);
3785 }
3786 
3787 #undef __FUNCT__
3788 #define __FUNCT__ "MatView_Private"
3789 /*
3790     Processes command line options to determine if/how a matrix
3791   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
3792 */
3793 PetscErrorCode MatView_Private(Mat mat)
3794 {
3795   PetscErrorCode    ierr;
3796   PetscTruth        flg;
3797   static PetscTruth incall = PETSC_FALSE;
3798 
3799   PetscFunctionBegin;
3800   if (incall) PetscFunctionReturn(0);
3801   incall = PETSC_TRUE;
3802   ierr = PetscOptionsBegin(mat->comm,mat->prefix,"Matrix Options","Mat");CHKERRQ(ierr);
3803     ierr = PetscOptionsName("-mat_view_info","Information on matrix size","MatView",&flg);CHKERRQ(ierr);
3804     if (flg) {
3805       ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
3806       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3807       ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3808     }
3809     ierr = PetscOptionsName("-mat_view_info_detailed","Nonzeros in the matrix","MatView",&flg);CHKERRQ(ierr);
3810     if (flg) {
3811       ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
3812       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3813       ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3814     }
3815     ierr = PetscOptionsName("-mat_view","Print matrix to stdout","MatView",&flg);CHKERRQ(ierr);
3816     if (flg) {
3817       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3818     }
3819     ierr = PetscOptionsName("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",&flg);CHKERRQ(ierr);
3820     if (flg) {
3821       ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr);
3822       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3823       ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3824     }
3825 #if defined(PETSC_USE_SOCKET_VIEWER)
3826     ierr = PetscOptionsName("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",&flg);CHKERRQ(ierr);
3827     if (flg) {
3828       ierr = MatView(mat,PETSC_VIEWER_SOCKET_(mat->comm));CHKERRQ(ierr);
3829       ierr = PetscViewerFlush(PETSC_VIEWER_SOCKET_(mat->comm));CHKERRQ(ierr);
3830     }
3831 #endif
3832     ierr = PetscOptionsName("-mat_view_binary","Save matrix to file in binary format","MatView",&flg);CHKERRQ(ierr);
3833     if (flg) {
3834       ierr = MatView(mat,PETSC_VIEWER_BINARY_(mat->comm));CHKERRQ(ierr);
3835       ierr = PetscViewerFlush(PETSC_VIEWER_BINARY_(mat->comm));CHKERRQ(ierr);
3836     }
3837   ierr = PetscOptionsEnd();CHKERRQ(ierr);
3838   /* cannot have inside PetscOptionsBegin() because uses PetscOptionsBegin() */
3839   ierr = PetscOptionsHasName(mat->prefix,"-mat_view_draw",&flg);CHKERRQ(ierr);
3840   if (flg) {
3841     ierr = PetscOptionsHasName(mat->prefix,"-mat_view_contour",&flg);CHKERRQ(ierr);
3842     if (flg) {
3843       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(mat->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
3844     }
3845     ierr = MatView(mat,PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3846     ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3847     if (flg) {
3848       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3849     }
3850   }
3851   incall = PETSC_FALSE;
3852   PetscFunctionReturn(0);
3853 }
3854 
3855 #undef __FUNCT__
3856 #define __FUNCT__ "MatAssemblyEnd"
3857 /*@
3858    MatAssemblyEnd - Completes assembling the matrix.  This routine should
3859    be called after MatAssemblyBegin().
3860 
3861    Collective on Mat
3862 
3863    Input Parameters:
3864 +  mat - the matrix
3865 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
3866 
3867    Options Database Keys:
3868 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
3869 .  -mat_view_info_detailed - Prints more detailed info
3870 .  -mat_view - Prints matrix in ASCII format
3871 .  -mat_view_matlab - Prints matrix in Matlab format
3872 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
3873 .  -display <name> - Sets display name (default is host)
3874 .  -draw_pause <sec> - Sets number of seconds to pause after display
3875 .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
3876 .  -viewer_socket_machine <machine>
3877 .  -viewer_socket_port <port>
3878 .  -mat_view_binary - save matrix to file in binary format
3879 -  -viewer_binary_filename <name>
3880 
3881    Notes:
3882    MatSetValues() generally caches the values.  The matrix is ready to
3883    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
3884    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
3885    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
3886    using the matrix.
3887 
3888    Level: beginner
3889 
3890 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
3891 @*/
3892 PetscErrorCode PETSCMAT_DLLEXPORT MatAssemblyEnd(Mat mat,MatAssemblyType type)
3893 {
3894   PetscErrorCode  ierr;
3895   static PetscInt inassm = 0;
3896   PetscTruth      flg;
3897 
3898   PetscFunctionBegin;
3899   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3900   PetscValidType(mat,1);
3901 
3902   inassm++;
3903   MatAssemblyEnd_InUse++;
3904   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
3905     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
3906     if (mat->ops->assemblyend) {
3907       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
3908     }
3909     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
3910   } else {
3911     if (mat->ops->assemblyend) {
3912       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
3913     }
3914   }
3915 
3916   /* Flush assembly is not a true assembly */
3917   if (type != MAT_FLUSH_ASSEMBLY) {
3918     mat->assembled  = PETSC_TRUE; mat->num_ass++;
3919   }
3920   mat->insertmode = NOT_SET_VALUES;
3921   MatAssemblyEnd_InUse--;
3922   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3923   if (!mat->symmetric_eternal) {
3924     mat->symmetric_set              = PETSC_FALSE;
3925     mat->hermitian_set              = PETSC_FALSE;
3926     mat->structurally_symmetric_set = PETSC_FALSE;
3927   }
3928   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
3929     ierr = MatView_Private(mat);CHKERRQ(ierr);
3930     ierr = PetscOptionsHasName(mat->prefix,"-mat_is_symmetric",&flg);CHKERRQ(ierr);
3931     if (flg) {
3932       PetscReal tol = 0.0;
3933       ierr = PetscOptionsGetReal(mat->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);CHKERRQ(ierr);
3934       ierr = MatIsSymmetric(mat,tol,&flg);CHKERRQ(ierr);
3935       if (flg) {
3936         ierr = PetscPrintf(mat->comm,"Matrix is symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
3937       } else {
3938         ierr = PetscPrintf(mat->comm,"Matrix is not symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
3939       }
3940     }
3941   }
3942   inassm--;
3943   ierr = PetscOptionsHasName(mat->prefix,"-help",&flg);CHKERRQ(ierr);
3944   if (flg) {
3945     ierr = MatPrintHelp(mat);CHKERRQ(ierr);
3946   }
3947   PetscFunctionReturn(0);
3948 }
3949 
3950 
3951 #undef __FUNCT__
3952 #define __FUNCT__ "MatCompress"
3953 /*@
3954    MatCompress - Tries to store the matrix in as little space as
3955    possible.  May fail if memory is already fully used, since it
3956    tries to allocate new space.
3957 
3958    Collective on Mat
3959 
3960    Input Parameters:
3961 .  mat - the matrix
3962 
3963    Level: advanced
3964 
3965 @*/
3966 PetscErrorCode PETSCMAT_DLLEXPORT MatCompress(Mat mat)
3967 {
3968   PetscErrorCode ierr;
3969 
3970   PetscFunctionBegin;
3971   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3972   PetscValidType(mat,1);
3973   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3974   if (mat->ops->compress) {ierr = (*mat->ops->compress)(mat);CHKERRQ(ierr);}
3975   PetscFunctionReturn(0);
3976 }
3977 
3978 #undef __FUNCT__
3979 #define __FUNCT__ "MatSetOption"
3980 /*@
3981    MatSetOption - Sets a parameter option for a matrix. Some options
3982    may be specific to certain storage formats.  Some options
3983    determine how values will be inserted (or added). Sorted,
3984    row-oriented input will generally assemble the fastest. The default
3985    is row-oriented, nonsorted input.
3986 
3987    Collective on Mat
3988 
3989    Input Parameters:
3990 +  mat - the matrix
3991 -  option - the option, one of those listed below (and possibly others),
3992              e.g., MAT_ROWS_SORTED, MAT_NEW_NONZERO_LOCATION_ERR
3993 
3994    Options Describing Matrix Structure:
3995 +    MAT_SYMMETRIC - symmetric in terms of both structure and value
3996 .    MAT_HERMITIAN - transpose is the complex conjugation
3997 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
3998 .    MAT_NOT_SYMMETRIC - not symmetric in value
3999 .    MAT_NOT_HERMITIAN - transpose is not the complex conjugation
4000 .    MAT_NOT_STRUCTURALLY_SYMMETRIC - not symmetric nonzero structure
4001 .    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
4002                             you set to be kept with all future use of the matrix
4003                             including after MatAssemblyBegin/End() which could
4004                             potentially change the symmetry structure, i.e. you
4005                             KNOW the matrix will ALWAYS have the property you set.
4006 -    MAT_NOT_SYMMETRY_ETERNAL - if MatAssemblyBegin/End() is called then the
4007                                 flags you set will be dropped (in case potentially
4008                                 the symmetry etc was lost).
4009 
4010    Options For Use with MatSetValues():
4011    Insert a logically dense subblock, which can be
4012 +    MAT_ROW_ORIENTED - row-oriented (default)
4013 .    MAT_COLUMN_ORIENTED - column-oriented
4014 .    MAT_ROWS_SORTED - sorted by row
4015 .    MAT_ROWS_UNSORTED - not sorted by row (default)
4016 .    MAT_COLUMNS_SORTED - sorted by column
4017 -    MAT_COLUMNS_UNSORTED - not sorted by column (default)
4018 
4019    Not these options reflect the data you pass in with MatSetValues(); it has
4020    nothing to do with how the data is stored internally in the matrix
4021    data structure.
4022 
4023    When (re)assembling a matrix, we can restrict the input for
4024    efficiency/debugging purposes.  These options include
4025 +    MAT_NO_NEW_NONZERO_LOCATIONS - additional insertions will not be
4026         allowed if they generate a new nonzero
4027 .    MAT_YES_NEW_NONZERO_LOCATIONS - additional insertions will be allowed
4028 .    MAT_NO_NEW_DIAGONALS - additional insertions will not be allowed if
4029          they generate a nonzero in a new diagonal (for block diagonal format only)
4030 .    MAT_YES_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
4031 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
4032 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
4033 -    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
4034 
4035    Notes:
4036    Some options are relevant only for particular matrix types and
4037    are thus ignored by others.  Other options are not supported by
4038    certain matrix types and will generate an error message if set.
4039 
4040    If using a Fortran 77 module to compute a matrix, one may need to
4041    use the column-oriented option (or convert to the row-oriented
4042    format).
4043 
4044    MAT_NO_NEW_NONZERO_LOCATIONS indicates that any add or insertion
4045    that would generate a new entry in the nonzero structure is instead
4046    ignored.  Thus, if memory has not alredy been allocated for this particular
4047    data, then the insertion is ignored. For dense matrices, in which
4048    the entire array is allocated, no entries are ever ignored.
4049    Set after the first MatAssemblyEnd()
4050 
4051    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
4052    that would generate a new entry in the nonzero structure instead produces
4053    an error. (Currently supported for AIJ and BAIJ formats only.)
4054    This is a useful flag when using SAME_NONZERO_PATTERN in calling
4055    KSPSetOperators() to ensure that the nonzero pattern truely does
4056    remain unchanged. Set after the first MatAssemblyEnd()
4057 
4058    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
4059    that would generate a new entry that has not been preallocated will
4060    instead produce an error. (Currently supported for AIJ and BAIJ formats
4061    only.) This is a useful flag when debugging matrix memory preallocation.
4062 
4063    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
4064    other processors should be dropped, rather than stashed.
4065    This is useful if you know that the "owning" processor is also
4066    always generating the correct matrix entries, so that PETSc need
4067    not transfer duplicate entries generated on another processor.
4068 
4069    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
4070    searches during matrix assembly. When this flag is set, the hash table
4071    is created during the first Matrix Assembly. This hash table is
4072    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
4073    to improve the searching of indices. MAT_NO_NEW_NONZERO_LOCATIONS flag
4074    should be used with MAT_USE_HASH_TABLE flag. This option is currently
4075    supported by MATMPIBAIJ format only.
4076 
4077    MAT_KEEP_ZEROED_ROWS indicates when MatZeroRows() is called the zeroed entries
4078    are kept in the nonzero structure
4079 
4080    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
4081    a zero location in the matrix
4082 
4083    MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
4084    ROWBS matrix types
4085 
4086    MAT_DO_NOT_USE_INODES - indicates not using inode version of the code - works
4087    with AIJ and ROWBS matrix types (database option "-mat_no_inode")
4088 
4089    Level: intermediate
4090 
4091    Concepts: matrices^setting options
4092 
4093 @*/
4094 PetscErrorCode PETSCMAT_DLLEXPORT MatSetOption(Mat mat,MatOption op)
4095 {
4096   PetscErrorCode ierr;
4097 
4098   PetscFunctionBegin;
4099   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4100   PetscValidType(mat,1);
4101   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4102   switch (op) {
4103   case MAT_SYMMETRIC:
4104     mat->symmetric                  = PETSC_TRUE;
4105     mat->structurally_symmetric     = PETSC_TRUE;
4106     mat->symmetric_set              = PETSC_TRUE;
4107     mat->structurally_symmetric_set = PETSC_TRUE;
4108     break;
4109   case MAT_HERMITIAN:
4110     mat->hermitian                  = PETSC_TRUE;
4111     mat->structurally_symmetric     = PETSC_TRUE;
4112     mat->hermitian_set              = PETSC_TRUE;
4113     mat->structurally_symmetric_set = PETSC_TRUE;
4114     break;
4115   case MAT_STRUCTURALLY_SYMMETRIC:
4116     mat->structurally_symmetric     = PETSC_TRUE;
4117     mat->structurally_symmetric_set = PETSC_TRUE;
4118     break;
4119   case MAT_NOT_SYMMETRIC:
4120     mat->symmetric                  = PETSC_FALSE;
4121     mat->symmetric_set              = PETSC_TRUE;
4122     break;
4123   case MAT_NOT_HERMITIAN:
4124     mat->hermitian                  = PETSC_FALSE;
4125     mat->hermitian_set              = PETSC_TRUE;
4126     break;
4127   case MAT_NOT_STRUCTURALLY_SYMMETRIC:
4128     mat->structurally_symmetric     = PETSC_FALSE;
4129     mat->structurally_symmetric_set = PETSC_TRUE;
4130     break;
4131   case MAT_SYMMETRY_ETERNAL:
4132     mat->symmetric_eternal          = PETSC_TRUE;
4133     break;
4134   case MAT_NOT_SYMMETRY_ETERNAL:
4135     mat->symmetric_eternal          = PETSC_FALSE;
4136     break;
4137   default:
4138     break;
4139   }
4140   if (mat->ops->setoption) {
4141     ierr = (*mat->ops->setoption)(mat,op);CHKERRQ(ierr);
4142   }
4143   PetscFunctionReturn(0);
4144 }
4145 
4146 #undef __FUNCT__
4147 #define __FUNCT__ "MatZeroEntries"
4148 /*@
4149    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
4150    this routine retains the old nonzero structure.
4151 
4152    Collective on Mat
4153 
4154    Input Parameters:
4155 .  mat - the matrix
4156 
4157    Level: intermediate
4158 
4159    Concepts: matrices^zeroing
4160 
4161 .seealso: MatZeroRows()
4162 @*/
4163 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroEntries(Mat mat)
4164 {
4165   PetscErrorCode ierr;
4166 
4167   PetscFunctionBegin;
4168   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4169   PetscValidType(mat,1);
4170   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4171   if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
4172   if (!mat->ops->zeroentries) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4173   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4174 
4175   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
4176   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
4177   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
4178   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4179   PetscFunctionReturn(0);
4180 }
4181 
4182 #undef __FUNCT__
4183 #define __FUNCT__ "MatZeroRows"
4184 /*@C
4185    MatZeroRows - Zeros all entries (except possibly the main diagonal)
4186    of a set of rows of a matrix.
4187 
4188    Collective on Mat
4189 
4190    Input Parameters:
4191 +  mat - the matrix
4192 .  numRows - the number of rows to remove
4193 .  rows - the global row indices
4194 -  diag - value put in all diagonals of eliminated rows
4195 
4196    Notes:
4197    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4198    but does not release memory.  For the dense and block diagonal
4199    formats this does not alter the nonzero structure.
4200 
4201    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
4202    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4203    merely zeroed.
4204 
4205    The user can set a value in the diagonal entry (or for the AIJ and
4206    row formats can optionally remove the main diagonal entry from the
4207    nonzero structure as well, by passing 0.0 as the final argument).
4208 
4209    For the parallel case, all processes that share the matrix (i.e.,
4210    those in the communicator used for matrix creation) MUST call this
4211    routine, regardless of whether any rows being zeroed are owned by
4212    them.
4213 
4214    Each processor should list the rows that IT wants zeroed
4215 
4216    Level: intermediate
4217 
4218    Concepts: matrices^zeroing rows
4219 
4220 .seealso: MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4221 @*/
4222 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4223 {
4224   PetscErrorCode ierr;
4225 
4226   PetscFunctionBegin;
4227   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4228   PetscValidType(mat,1);
4229   if (numRows) PetscValidIntPointer(rows,3);
4230   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4231   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4232   if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4233   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4234 
4235   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag);CHKERRQ(ierr);
4236   ierr = MatView_Private(mat);CHKERRQ(ierr);
4237   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4238   PetscFunctionReturn(0);
4239 }
4240 
4241 #undef __FUNCT__
4242 #define __FUNCT__ "MatZeroRowsIS"
4243 /*@C
4244    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
4245    of a set of rows of a matrix.
4246 
4247    Collective on Mat
4248 
4249    Input Parameters:
4250 +  mat - the matrix
4251 .  is - index set of rows to remove
4252 -  diag - value put in all diagonals of eliminated rows
4253 
4254    Notes:
4255    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4256    but does not release memory.  For the dense and block diagonal
4257    formats this does not alter the nonzero structure.
4258 
4259    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
4260    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4261    merely zeroed.
4262 
4263    The user can set a value in the diagonal entry (or for the AIJ and
4264    row formats can optionally remove the main diagonal entry from the
4265    nonzero structure as well, by passing 0.0 as the final argument).
4266 
4267    For the parallel case, all processes that share the matrix (i.e.,
4268    those in the communicator used for matrix creation) MUST call this
4269    routine, regardless of whether any rows being zeroed are owned by
4270    them.
4271 
4272    Each processor should list the rows that IT wants zeroed
4273 
4274    Level: intermediate
4275 
4276    Concepts: matrices^zeroing rows
4277 
4278 .seealso: MatZeroRows(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4279 @*/
4280 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsIS(Mat mat,IS is,PetscScalar diag)
4281 {
4282   PetscInt       numRows;
4283   PetscInt       *rows;
4284   PetscErrorCode ierr;
4285 
4286   PetscFunctionBegin;
4287   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4288   PetscValidType(mat,1);
4289   PetscValidHeaderSpecific(is,IS_COOKIE,2);
4290   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
4291   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
4292   ierr = MatZeroRows(mat,numRows,rows,diag);CHKERRQ(ierr);
4293   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
4294   PetscFunctionReturn(0);
4295 }
4296 
4297 #undef __FUNCT__
4298 #define __FUNCT__ "MatZeroRowsLocal"
4299 /*@C
4300    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
4301    of a set of rows of a matrix; using local numbering of rows.
4302 
4303    Collective on Mat
4304 
4305    Input Parameters:
4306 +  mat - the matrix
4307 .  numRows - the number of rows to remove
4308 .  rows - the global row indices
4309 -  diag - value put in all diagonals of eliminated rows
4310 
4311    Notes:
4312    Before calling MatZeroRowsLocal(), the user must first set the
4313    local-to-global mapping by calling MatSetLocalToGlobalMapping().
4314 
4315    For the AIJ matrix formats this removes the old nonzero structure,
4316    but does not release memory.  For the dense and block diagonal
4317    formats this does not alter the nonzero structure.
4318 
4319    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
4320    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4321    merely zeroed.
4322 
4323    The user can set a value in the diagonal entry (or for the AIJ and
4324    row formats can optionally remove the main diagonal entry from the
4325    nonzero structure as well, by passing 0.0 as the final argument).
4326 
4327    Level: intermediate
4328 
4329    Concepts: matrices^zeroing
4330 
4331 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
4332 @*/
4333 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4334 {
4335   PetscErrorCode ierr;
4336 
4337   PetscFunctionBegin;
4338   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4339   PetscValidType(mat,1);
4340   if (numRows) PetscValidIntPointer(rows,3);
4341   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4342   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4343   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4344 
4345   if (mat->ops->zerorowslocal) {
4346     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag);CHKERRQ(ierr);
4347   } else {
4348     IS is, newis;
4349     PetscInt *newRows;
4350 
4351     if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
4352     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,&is);CHKERRQ(ierr);
4353     ierr = ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);CHKERRQ(ierr);
4354     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
4355     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag);CHKERRQ(ierr);
4356     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
4357     ierr = ISDestroy(newis);CHKERRQ(ierr);
4358     ierr = ISDestroy(is);CHKERRQ(ierr);
4359   }
4360   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4361   PetscFunctionReturn(0);
4362 }
4363 
4364 #undef __FUNCT__
4365 #define __FUNCT__ "MatZeroRowsLocal"
4366 /*@C
4367    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
4368    of a set of rows of a matrix; using local numbering of rows.
4369 
4370    Collective on Mat
4371 
4372    Input Parameters:
4373 +  mat - the matrix
4374 .  is - index set of rows to remove
4375 -  diag - value put in all diagonals of eliminated rows
4376 
4377    Notes:
4378    Before calling MatZeroRowsLocal(), the user must first set the
4379    local-to-global mapping by calling MatSetLocalToGlobalMapping().
4380 
4381    For the AIJ matrix formats this removes the old nonzero structure,
4382    but does not release memory.  For the dense and block diagonal
4383    formats this does not alter the nonzero structure.
4384 
4385    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
4386    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4387    merely zeroed.
4388 
4389    The user can set a value in the diagonal entry (or for the AIJ and
4390    row formats can optionally remove the main diagonal entry from the
4391    nonzero structure as well, by passing 0.0 as the final argument).
4392 
4393    Level: intermediate
4394 
4395    Concepts: matrices^zeroing
4396 
4397 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
4398 @*/
4399 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag)
4400 {
4401   PetscErrorCode ierr;
4402   PetscInt       numRows;
4403   PetscInt       *rows;
4404 
4405   PetscFunctionBegin;
4406   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4407   PetscValidType(mat,1);
4408   PetscValidHeaderSpecific(is,IS_COOKIE,2);
4409   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4410   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4411   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4412 
4413   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
4414   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
4415   ierr = MatZeroRowsLocal(mat,numRows,rows,diag);CHKERRQ(ierr);
4416   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
4417   PetscFunctionReturn(0);
4418 }
4419 
4420 #undef __FUNCT__
4421 #define __FUNCT__ "MatGetSize"
4422 /*@
4423    MatGetSize - Returns the numbers of rows and columns in a matrix.
4424 
4425    Not Collective
4426 
4427    Input Parameter:
4428 .  mat - the matrix
4429 
4430    Output Parameters:
4431 +  m - the number of global rows
4432 -  n - the number of global columns
4433 
4434    Note: both output parameters can be PETSC_NULL on input.
4435 
4436    Level: beginner
4437 
4438    Concepts: matrices^size
4439 
4440 .seealso: MatGetLocalSize()
4441 @*/
4442 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
4443 {
4444   PetscFunctionBegin;
4445   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4446   if (m) *m = mat->rmap.N;
4447   if (n) *n = mat->cmap.N;
4448   PetscFunctionReturn(0);
4449 }
4450 
4451 #undef __FUNCT__
4452 #define __FUNCT__ "MatGetLocalSize"
4453 /*@
4454    MatGetLocalSize - Returns the number of rows and columns in a matrix
4455    stored locally.  This information may be implementation dependent, so
4456    use with care.
4457 
4458    Not Collective
4459 
4460    Input Parameters:
4461 .  mat - the matrix
4462 
4463    Output Parameters:
4464 +  m - the number of local rows
4465 -  n - the number of local columns
4466 
4467    Note: both output parameters can be PETSC_NULL on input.
4468 
4469    Level: beginner
4470 
4471    Concepts: matrices^local size
4472 
4473 .seealso: MatGetSize()
4474 @*/
4475 PetscErrorCode PETSCMAT_DLLEXPORT MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
4476 {
4477   PetscFunctionBegin;
4478   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4479   if (m) PetscValidIntPointer(m,2);
4480   if (n) PetscValidIntPointer(n,3);
4481   if (m) *m = mat->rmap.n;
4482   if (n) *n = mat->cmap.n;
4483   PetscFunctionReturn(0);
4484 }
4485 
4486 #undef __FUNCT__
4487 #define __FUNCT__ "MatGetOwnershipRange"
4488 /*@
4489    MatGetOwnershipRange - Returns the range of matrix rows owned by
4490    this processor, assuming that the matrix is laid out with the first
4491    n1 rows on the first processor, the next n2 rows on the second, etc.
4492    For certain parallel layouts this range may not be well defined.
4493 
4494    Not Collective
4495 
4496    Input Parameters:
4497 .  mat - the matrix
4498 
4499    Output Parameters:
4500 +  m - the global index of the first local row
4501 -  n - one more than the global index of the last local row
4502 
4503    Note: both output parameters can be PETSC_NULL on input.
4504 
4505    Level: beginner
4506 
4507    Concepts: matrices^row ownership
4508 @*/
4509 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
4510 {
4511   PetscErrorCode ierr;
4512 
4513   PetscFunctionBegin;
4514   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4515   PetscValidType(mat,1);
4516   if (m) PetscValidIntPointer(m,2);
4517   if (n) PetscValidIntPointer(n,3);
4518   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4519   if (m) *m = mat->rmap.rstart;
4520   if (n) *n = mat->rmap.rend;
4521   PetscFunctionReturn(0);
4522 }
4523 
4524 #undef __FUNCT__
4525 #define __FUNCT__ "MatILUFactorSymbolic"
4526 /*@
4527    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
4528    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
4529    to complete the factorization.
4530 
4531    Collective on Mat
4532 
4533    Input Parameters:
4534 +  mat - the matrix
4535 .  row - row permutation
4536 .  column - column permutation
4537 -  info - structure containing
4538 $      levels - number of levels of fill.
4539 $      expected fill - as ratio of original fill.
4540 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
4541                 missing diagonal entries)
4542 
4543    Output Parameters:
4544 .  fact - new matrix that has been symbolically factored
4545 
4546    Notes:
4547    See the users manual for additional information about
4548    choosing the fill factor for better efficiency.
4549 
4550    Most users should employ the simplified KSP interface for linear solvers
4551    instead of working directly with matrix algebra routines such as this.
4552    See, e.g., KSPCreate().
4553 
4554    Level: developer
4555 
4556   Concepts: matrices^symbolic LU factorization
4557   Concepts: matrices^factorization
4558   Concepts: LU^symbolic factorization
4559 
4560 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
4561           MatGetOrdering(), MatFactorInfo
4562 
4563 @*/
4564 PetscErrorCode PETSCMAT_DLLEXPORT MatILUFactorSymbolic(Mat mat,IS row,IS col,MatFactorInfo *info,Mat *fact)
4565 {
4566   PetscErrorCode ierr;
4567 
4568   PetscFunctionBegin;
4569   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4570   PetscValidType(mat,1);
4571   PetscValidHeaderSpecific(row,IS_COOKIE,2);
4572   PetscValidHeaderSpecific(col,IS_COOKIE,3);
4573   PetscValidPointer(info,4);
4574   PetscValidPointer(fact,5);
4575   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
4576   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
4577   if (!mat->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",mat->type_name);
4578   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4579   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4580   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4581 
4582   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
4583   ierr = (*mat->ops->ilufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
4584   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
4585   PetscFunctionReturn(0);
4586 }
4587 
4588 #undef __FUNCT__
4589 #define __FUNCT__ "MatICCFactorSymbolic"
4590 /*@
4591    MatICCFactorSymbolic - Performs symbolic incomplete
4592    Cholesky factorization for a symmetric matrix.  Use
4593    MatCholeskyFactorNumeric() to complete the factorization.
4594 
4595    Collective on Mat
4596 
4597    Input Parameters:
4598 +  mat - the matrix
4599 .  perm - row and column permutation
4600 -  info - structure containing
4601 $      levels - number of levels of fill.
4602 $      expected fill - as ratio of original fill.
4603 
4604    Output Parameter:
4605 .  fact - the factored matrix
4606 
4607    Notes:
4608    Most users should employ the KSP interface for linear solvers
4609    instead of working directly with matrix algebra routines such as this.
4610    See, e.g., KSPCreate().
4611 
4612    Level: developer
4613 
4614   Concepts: matrices^symbolic incomplete Cholesky factorization
4615   Concepts: matrices^factorization
4616   Concepts: Cholsky^symbolic factorization
4617 
4618 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
4619 @*/
4620 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactorSymbolic(Mat mat,IS perm,MatFactorInfo *info,Mat *fact)
4621 {
4622   PetscErrorCode ierr;
4623 
4624   PetscFunctionBegin;
4625   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4626   PetscValidType(mat,1);
4627   PetscValidHeaderSpecific(perm,IS_COOKIE,2);
4628   PetscValidPointer(info,3);
4629   PetscValidPointer(fact,4);
4630   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4631   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
4632   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
4633   if (!mat->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",mat->type_name);
4634   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4635   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4636 
4637   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
4638   ierr = (*mat->ops->iccfactorsymbolic)(mat,perm,info,fact);CHKERRQ(ierr);
4639   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
4640   PetscFunctionReturn(0);
4641 }
4642 
4643 #undef __FUNCT__
4644 #define __FUNCT__ "MatGetArray"
4645 /*@C
4646    MatGetArray - Returns a pointer to the element values in the matrix.
4647    The result of this routine is dependent on the underlying matrix data
4648    structure, and may not even work for certain matrix types.  You MUST
4649    call MatRestoreArray() when you no longer need to access the array.
4650 
4651    Not Collective
4652 
4653    Input Parameter:
4654 .  mat - the matrix
4655 
4656    Output Parameter:
4657 .  v - the location of the values
4658 
4659 
4660    Fortran Note:
4661    This routine is used differently from Fortran, e.g.,
4662 .vb
4663         Mat         mat
4664         PetscScalar mat_array(1)
4665         PetscOffset i_mat
4666         PetscErrorCode ierr
4667         call MatGetArray(mat,mat_array,i_mat,ierr)
4668 
4669   C  Access first local entry in matrix; note that array is
4670   C  treated as one dimensional
4671         value = mat_array(i_mat + 1)
4672 
4673         [... other code ...]
4674         call MatRestoreArray(mat,mat_array,i_mat,ierr)
4675 .ve
4676 
4677    See the Fortran chapter of the users manual and
4678    petsc/src/mat/examples/tests for details.
4679 
4680    Level: advanced
4681 
4682    Concepts: matrices^access array
4683 
4684 .seealso: MatRestoreArray(), MatGetArrayF90()
4685 @*/
4686 PetscErrorCode PETSCMAT_DLLEXPORT MatGetArray(Mat mat,PetscScalar *v[])
4687 {
4688   PetscErrorCode ierr;
4689 
4690   PetscFunctionBegin;
4691   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4692   PetscValidType(mat,1);
4693   PetscValidPointer(v,2);
4694   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4695   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4696   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
4697   CHKMEMQ;
4698   PetscFunctionReturn(0);
4699 }
4700 
4701 #undef __FUNCT__
4702 #define __FUNCT__ "MatRestoreArray"
4703 /*@C
4704    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
4705 
4706    Not Collective
4707 
4708    Input Parameter:
4709 +  mat - the matrix
4710 -  v - the location of the values
4711 
4712    Fortran Note:
4713    This routine is used differently from Fortran, e.g.,
4714 .vb
4715         Mat         mat
4716         PetscScalar mat_array(1)
4717         PetscOffset i_mat
4718         PetscErrorCode ierr
4719         call MatGetArray(mat,mat_array,i_mat,ierr)
4720 
4721   C  Access first local entry in matrix; note that array is
4722   C  treated as one dimensional
4723         value = mat_array(i_mat + 1)
4724 
4725         [... other code ...]
4726         call MatRestoreArray(mat,mat_array,i_mat,ierr)
4727 .ve
4728 
4729    See the Fortran chapter of the users manual and
4730    petsc/src/mat/examples/tests for details
4731 
4732    Level: advanced
4733 
4734 .seealso: MatGetArray(), MatRestoreArrayF90()
4735 @*/
4736 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreArray(Mat mat,PetscScalar *v[])
4737 {
4738   PetscErrorCode ierr;
4739 
4740   PetscFunctionBegin;
4741   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4742   PetscValidType(mat,1);
4743   PetscValidPointer(v,2);
4744 #if defined(PETSC_USE_DEBUG)
4745   CHKMEMQ;
4746 #endif
4747   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4748   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
4749   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4750   PetscFunctionReturn(0);
4751 }
4752 
4753 #undef __FUNCT__
4754 #define __FUNCT__ "MatGetSubMatrices"
4755 /*@C
4756    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
4757    points to an array of valid matrices, they may be reused to store the new
4758    submatrices.
4759 
4760    Collective on Mat
4761 
4762    Input Parameters:
4763 +  mat - the matrix
4764 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
4765 .  irow, icol - index sets of rows and columns to extract
4766 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4767 
4768    Output Parameter:
4769 .  submat - the array of submatrices
4770 
4771    Notes:
4772    MatGetSubMatrices() can extract only sequential submatrices
4773    (from both sequential and parallel matrices). Use MatGetSubMatrix()
4774    to extract a parallel submatrix.
4775 
4776    When extracting submatrices from a parallel matrix, each processor can
4777    form a different submatrix by setting the rows and columns of its
4778    individual index sets according to the local submatrix desired.
4779 
4780    When finished using the submatrices, the user should destroy
4781    them with MatDestroyMatrices().
4782 
4783    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
4784    original matrix has not changed from that last call to MatGetSubMatrices().
4785 
4786    This routine creates the matrices in submat; you should NOT create them before
4787    calling it. It also allocates the array of matrix pointers submat.
4788 
4789    For BAIJ matrices the index sets must respect the block structure, that is if they
4790    request one row/column in a block, they must request all rows/columns that are in
4791    that block. For example, if the block size is 2 you cannot request just row 0 and
4792    column 0.
4793 
4794    Fortran Note:
4795    The Fortran interface is slightly different from that given below; it
4796    requires one to pass in  as submat a Mat (integer) array of size at least m.
4797 
4798    Level: advanced
4799 
4800    Concepts: matrices^accessing submatrices
4801    Concepts: submatrices
4802 
4803 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal()
4804 @*/
4805 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
4806 {
4807   PetscErrorCode ierr;
4808   PetscInt        i;
4809   PetscTruth      eq;
4810 
4811   PetscFunctionBegin;
4812   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4813   PetscValidType(mat,1);
4814   if (n) {
4815     PetscValidPointer(irow,3);
4816     PetscValidHeaderSpecific(*irow,IS_COOKIE,3);
4817     PetscValidPointer(icol,4);
4818     PetscValidHeaderSpecific(*icol,IS_COOKIE,4);
4819   }
4820   PetscValidPointer(submat,6);
4821   if (n && scall == MAT_REUSE_MATRIX) {
4822     PetscValidPointer(*submat,6);
4823     PetscValidHeaderSpecific(**submat,MAT_COOKIE,6);
4824   }
4825   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4826   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4827   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4828   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4829 
4830   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
4831   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
4832   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
4833   for (i=0; i<n; i++) {
4834     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
4835       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
4836       if (eq) {
4837 	if (mat->symmetric){
4838 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC);CHKERRQ(ierr);
4839 	} else if (mat->hermitian) {
4840 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN);CHKERRQ(ierr);
4841 	} else if (mat->structurally_symmetric) {
4842 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC);CHKERRQ(ierr);
4843 	}
4844       }
4845     }
4846   }
4847   PetscFunctionReturn(0);
4848 }
4849 
4850 #undef __FUNCT__
4851 #define __FUNCT__ "MatDestroyMatrices"
4852 /*@C
4853    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
4854 
4855    Collective on Mat
4856 
4857    Input Parameters:
4858 +  n - the number of local matrices
4859 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
4860                        sequence of MatGetSubMatrices())
4861 
4862    Level: advanced
4863 
4864     Notes: Frees not only the matrices, but also the array that contains the matrices
4865 
4866 .seealso: MatGetSubMatrices()
4867 @*/
4868 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroyMatrices(PetscInt n,Mat *mat[])
4869 {
4870   PetscErrorCode ierr;
4871   PetscInt       i;
4872 
4873   PetscFunctionBegin;
4874   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
4875   PetscValidPointer(mat,2);
4876   for (i=0; i<n; i++) {
4877     ierr = MatDestroy((*mat)[i]);CHKERRQ(ierr);
4878   }
4879   /* memory is allocated even if n = 0 */
4880   ierr = PetscFree(*mat);CHKERRQ(ierr);
4881   PetscFunctionReturn(0);
4882 }
4883 
4884 #undef __FUNCT__
4885 #define __FUNCT__ "MatIncreaseOverlap"
4886 /*@
4887    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
4888    replaces the index sets by larger ones that represent submatrices with
4889    additional overlap.
4890 
4891    Collective on Mat
4892 
4893    Input Parameters:
4894 +  mat - the matrix
4895 .  n   - the number of index sets
4896 .  is  - the array of index sets (these index sets will changed during the call)
4897 -  ov  - the additional overlap requested
4898 
4899    Level: developer
4900 
4901    Concepts: overlap
4902    Concepts: ASM^computing overlap
4903 
4904 .seealso: MatGetSubMatrices()
4905 @*/
4906 PetscErrorCode PETSCMAT_DLLEXPORT MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
4907 {
4908   PetscErrorCode ierr;
4909 
4910   PetscFunctionBegin;
4911   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4912   PetscValidType(mat,1);
4913   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
4914   if (n) {
4915     PetscValidPointer(is,3);
4916     PetscValidHeaderSpecific(*is,IS_COOKIE,3);
4917   }
4918   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4919   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4920   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4921 
4922   if (!ov) PetscFunctionReturn(0);
4923   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4924   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
4925   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
4926   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
4927   PetscFunctionReturn(0);
4928 }
4929 
4930 #undef __FUNCT__
4931 #define __FUNCT__ "MatPrintHelp"
4932 /*@
4933    MatPrintHelp - Prints all the options for the matrix.
4934 
4935    Collective on Mat
4936 
4937    Input Parameter:
4938 .  mat - the matrix
4939 
4940    Options Database Keys:
4941 +  -help - Prints matrix options
4942 -  -h - Prints matrix options
4943 
4944    Level: developer
4945 
4946 .seealso: MatCreate(), MatCreateXXX()
4947 @*/
4948 PetscErrorCode PETSCMAT_DLLEXPORT MatPrintHelp(Mat mat)
4949 {
4950   static PetscTruth called = PETSC_FALSE;
4951   PetscErrorCode    ierr;
4952 
4953   PetscFunctionBegin;
4954   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4955   PetscValidType(mat,1);
4956   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4957 
4958   if (!called) {
4959     if (mat->ops->printhelp) {
4960       ierr = (*mat->ops->printhelp)(mat);CHKERRQ(ierr);
4961     }
4962     called = PETSC_TRUE;
4963   }
4964   PetscFunctionReturn(0);
4965 }
4966 
4967 #undef __FUNCT__
4968 #define __FUNCT__ "MatGetBlockSize"
4969 /*@
4970    MatGetBlockSize - Returns the matrix block size; useful especially for the
4971    block row and block diagonal formats.
4972 
4973    Not Collective
4974 
4975    Input Parameter:
4976 .  mat - the matrix
4977 
4978    Output Parameter:
4979 .  bs - block size
4980 
4981    Notes:
4982    Block diagonal formats are MATSEQBDIAG, MATMPIBDIAG.
4983    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
4984 
4985    Level: intermediate
4986 
4987    Concepts: matrices^block size
4988 
4989 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatCreateSeqBDiag(), MatCreateMPIBDiag()
4990 @*/
4991 PetscErrorCode PETSCMAT_DLLEXPORT MatGetBlockSize(Mat mat,PetscInt *bs)
4992 {
4993   PetscErrorCode ierr;
4994 
4995   PetscFunctionBegin;
4996   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4997   PetscValidType(mat,1);
4998   PetscValidIntPointer(bs,2);
4999   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5000   *bs = mat->rmap.bs;
5001   PetscFunctionReturn(0);
5002 }
5003 
5004 #undef __FUNCT__
5005 #define __FUNCT__ "MatSetBlockSize"
5006 /*@
5007    MatSetBlockSize - Sets the matrix block size; for many matrix types you
5008      cannot use this and MUST set the blocksize when you preallocate the matrix
5009 
5010    Not Collective
5011 
5012    Input Parameters:
5013 +  mat - the matrix
5014 -  bs - block size
5015 
5016    Notes:
5017      Only works for shell and AIJ matrices
5018 
5019    Level: intermediate
5020 
5021    Concepts: matrices^block size
5022 
5023 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatCreateSeqBDiag(), MatCreateMPIBDiag(), MatGetBlockSize()
5024 @*/
5025 PetscErrorCode PETSCMAT_DLLEXPORT MatSetBlockSize(Mat mat,PetscInt bs)
5026 {
5027   PetscErrorCode ierr;
5028 
5029   PetscFunctionBegin;
5030   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5031   PetscValidType(mat,1);
5032   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5033   if (mat->ops->setblocksize) {
5034     mat->rmap.bs = bs;
5035     ierr = (*mat->ops->setblocksize)(mat,bs);CHKERRQ(ierr);
5036   } else {
5037     SETERRQ1(PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",mat->type_name);
5038   }
5039   PetscFunctionReturn(0);
5040 }
5041 
5042 #undef __FUNCT__
5043 #define __FUNCT__ "MatGetRowIJ"
5044 /*@C
5045     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
5046 
5047    Collective on Mat
5048 
5049     Input Parameters:
5050 +   mat - the matrix
5051 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
5052 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5053                 symmetrized
5054 
5055     Output Parameters:
5056 +   n - number of rows in the (possibly compressed) matrix
5057 .   ia - the row pointers
5058 .   ja - the column indices
5059 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
5060            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
5061 
5062     Level: developer
5063 
5064     Notes: You CANNOT change any of the ia[] or ja[] values.
5065 
5066            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
5067 
5068 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
5069 @*/
5070 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5071 {
5072   PetscErrorCode ierr;
5073 
5074   PetscFunctionBegin;
5075   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5076   PetscValidType(mat,1);
5077   PetscValidIntPointer(n,4);
5078   if (ia) PetscValidIntPointer(ia,5);
5079   if (ja) PetscValidIntPointer(ja,6);
5080   PetscValidIntPointer(done,7);
5081   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5082   if (!mat->ops->getrowij) *done = PETSC_FALSE;
5083   else {
5084     *done = PETSC_TRUE;
5085     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
5086   }
5087   PetscFunctionReturn(0);
5088 }
5089 
5090 #undef __FUNCT__
5091 #define __FUNCT__ "MatGetColumnIJ"
5092 /*@C
5093     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
5094 
5095     Collective on Mat
5096 
5097     Input Parameters:
5098 +   mat - the matrix
5099 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5100 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5101                 symmetrized
5102 
5103     Output Parameters:
5104 +   n - number of columns in the (possibly compressed) matrix
5105 .   ia - the column pointers
5106 .   ja - the row indices
5107 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
5108 
5109     Level: developer
5110 
5111 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5112 @*/
5113 PetscErrorCode PETSCMAT_DLLEXPORT MatGetColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5114 {
5115   PetscErrorCode ierr;
5116 
5117   PetscFunctionBegin;
5118   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5119   PetscValidType(mat,1);
5120   PetscValidIntPointer(n,4);
5121   if (ia) PetscValidIntPointer(ia,5);
5122   if (ja) PetscValidIntPointer(ja,6);
5123   PetscValidIntPointer(done,7);
5124   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5125   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
5126   else {
5127     *done = PETSC_TRUE;
5128     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
5129   }
5130   PetscFunctionReturn(0);
5131 }
5132 
5133 #undef __FUNCT__
5134 #define __FUNCT__ "MatRestoreRowIJ"
5135 /*@C
5136     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
5137     MatGetRowIJ().
5138 
5139     Collective on Mat
5140 
5141     Input Parameters:
5142 +   mat - the matrix
5143 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5144 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5145                 symmetrized
5146 
5147     Output Parameters:
5148 +   n - size of (possibly compressed) matrix
5149 .   ia - the row pointers
5150 .   ja - the column indices
5151 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5152 
5153     Level: developer
5154 
5155 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5156 @*/
5157 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5158 {
5159   PetscErrorCode ierr;
5160 
5161   PetscFunctionBegin;
5162   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5163   PetscValidType(mat,1);
5164   if (ia) PetscValidIntPointer(ia,5);
5165   if (ja) PetscValidIntPointer(ja,6);
5166   PetscValidIntPointer(done,7);
5167   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5168 
5169   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
5170   else {
5171     *done = PETSC_TRUE;
5172     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
5173   }
5174   PetscFunctionReturn(0);
5175 }
5176 
5177 #undef __FUNCT__
5178 #define __FUNCT__ "MatRestoreColumnIJ"
5179 /*@C
5180     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
5181     MatGetColumnIJ().
5182 
5183     Collective on Mat
5184 
5185     Input Parameters:
5186 +   mat - the matrix
5187 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5188 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5189                 symmetrized
5190 
5191     Output Parameters:
5192 +   n - size of (possibly compressed) matrix
5193 .   ia - the column pointers
5194 .   ja - the row indices
5195 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5196 
5197     Level: developer
5198 
5199 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
5200 @*/
5201 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5202 {
5203   PetscErrorCode ierr;
5204 
5205   PetscFunctionBegin;
5206   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5207   PetscValidType(mat,1);
5208   if (ia) PetscValidIntPointer(ia,5);
5209   if (ja) PetscValidIntPointer(ja,6);
5210   PetscValidIntPointer(done,7);
5211   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5212 
5213   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
5214   else {
5215     *done = PETSC_TRUE;
5216     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
5217   }
5218   PetscFunctionReturn(0);
5219 }
5220 
5221 #undef __FUNCT__
5222 #define __FUNCT__ "MatColoringPatch"
5223 /*@C
5224     MatColoringPatch -Used inside matrix coloring routines that
5225     use MatGetRowIJ() and/or MatGetColumnIJ().
5226 
5227     Collective on Mat
5228 
5229     Input Parameters:
5230 +   mat - the matrix
5231 .   ncolors - max color value
5232 .   n   - number of entries in colorarray
5233 -   colorarray - array indicating color for each column
5234 
5235     Output Parameters:
5236 .   iscoloring - coloring generated using colorarray information
5237 
5238     Level: developer
5239 
5240 .seealso: MatGetRowIJ(), MatGetColumnIJ()
5241 
5242 @*/
5243 PetscErrorCode PETSCMAT_DLLEXPORT MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
5244 {
5245   PetscErrorCode ierr;
5246 
5247   PetscFunctionBegin;
5248   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5249   PetscValidType(mat,1);
5250   PetscValidIntPointer(colorarray,4);
5251   PetscValidPointer(iscoloring,5);
5252   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5253 
5254   if (!mat->ops->coloringpatch){
5255     ierr = ISColoringCreate(mat->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
5256   } else {
5257     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
5258   }
5259   PetscFunctionReturn(0);
5260 }
5261 
5262 
5263 #undef __FUNCT__
5264 #define __FUNCT__ "MatSetUnfactored"
5265 /*@
5266    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
5267 
5268    Collective on Mat
5269 
5270    Input Parameter:
5271 .  mat - the factored matrix to be reset
5272 
5273    Notes:
5274    This routine should be used only with factored matrices formed by in-place
5275    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
5276    format).  This option can save memory, for example, when solving nonlinear
5277    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
5278    ILU(0) preconditioner.
5279 
5280    Note that one can specify in-place ILU(0) factorization by calling
5281 .vb
5282      PCType(pc,PCILU);
5283      PCFactorSeUseInPlace(pc);
5284 .ve
5285    or by using the options -pc_type ilu -pc_factor_in_place
5286 
5287    In-place factorization ILU(0) can also be used as a local
5288    solver for the blocks within the block Jacobi or additive Schwarz
5289    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
5290    of these preconditioners in the users manual for details on setting
5291    local solver options.
5292 
5293    Most users should employ the simplified KSP interface for linear solvers
5294    instead of working directly with matrix algebra routines such as this.
5295    See, e.g., KSPCreate().
5296 
5297    Level: developer
5298 
5299 .seealso: PCFactorSetUseInPlace()
5300 
5301    Concepts: matrices^unfactored
5302 
5303 @*/
5304 PetscErrorCode PETSCMAT_DLLEXPORT MatSetUnfactored(Mat mat)
5305 {
5306   PetscErrorCode ierr;
5307 
5308   PetscFunctionBegin;
5309   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5310   PetscValidType(mat,1);
5311   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5312   mat->factor = 0;
5313   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
5314   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
5315   PetscFunctionReturn(0);
5316 }
5317 
5318 /*MC
5319     MatGetArrayF90 - Accesses a matrix array from Fortran90.
5320 
5321     Synopsis:
5322     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
5323 
5324     Not collective
5325 
5326     Input Parameter:
5327 .   x - matrix
5328 
5329     Output Parameters:
5330 +   xx_v - the Fortran90 pointer to the array
5331 -   ierr - error code
5332 
5333     Example of Usage:
5334 .vb
5335       PetscScalar, pointer xx_v(:)
5336       ....
5337       call MatGetArrayF90(x,xx_v,ierr)
5338       a = xx_v(3)
5339       call MatRestoreArrayF90(x,xx_v,ierr)
5340 .ve
5341 
5342     Notes:
5343     Not yet supported for all F90 compilers
5344 
5345     Level: advanced
5346 
5347 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
5348 
5349     Concepts: matrices^accessing array
5350 
5351 M*/
5352 
5353 /*MC
5354     MatRestoreArrayF90 - Restores a matrix array that has been
5355     accessed with MatGetArrayF90().
5356 
5357     Synopsis:
5358     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
5359 
5360     Not collective
5361 
5362     Input Parameters:
5363 +   x - matrix
5364 -   xx_v - the Fortran90 pointer to the array
5365 
5366     Output Parameter:
5367 .   ierr - error code
5368 
5369     Example of Usage:
5370 .vb
5371        PetscScalar, pointer xx_v(:)
5372        ....
5373        call MatGetArrayF90(x,xx_v,ierr)
5374        a = xx_v(3)
5375        call MatRestoreArrayF90(x,xx_v,ierr)
5376 .ve
5377 
5378     Notes:
5379     Not yet supported for all F90 compilers
5380 
5381     Level: advanced
5382 
5383 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
5384 
5385 M*/
5386 
5387 
5388 #undef __FUNCT__
5389 #define __FUNCT__ "MatGetSubMatrix"
5390 /*@
5391     MatGetSubMatrix - Gets a single submatrix on the same number of processors
5392                       as the original matrix.
5393 
5394     Collective on Mat
5395 
5396     Input Parameters:
5397 +   mat - the original matrix
5398 .   isrow - rows this processor should obtain
5399 .   iscol - columns for all processors you wish to keep
5400 .   csize - number of columns "local" to this processor (does nothing for sequential
5401             matrices). This should match the result from VecGetLocalSize(x,...) if you
5402             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
5403 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
5404 
5405     Output Parameter:
5406 .   newmat - the new submatrix, of the same type as the old
5407 
5408     Level: advanced
5409 
5410     Notes: the iscol argument MUST be the same on each processor. You might be
5411     able to create the iscol argument with ISAllGather().
5412 
5413       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
5414    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
5415    to this routine with a mat of the same nonzero structure and with a cll of MAT_REUSE_MATRIX
5416    will reuse the matrix generated the first time.
5417 
5418     Concepts: matrices^submatrices
5419 
5420 .seealso: MatGetSubMatrices(), ISAllGather()
5421 @*/
5422 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrix(Mat mat,IS isrow,IS iscol,PetscInt csize,MatReuse cll,Mat *newmat)
5423 {
5424   PetscErrorCode ierr;
5425   PetscMPIInt    size;
5426   Mat            *local;
5427 
5428   PetscFunctionBegin;
5429   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5430   PetscValidHeaderSpecific(isrow,IS_COOKIE,2);
5431   PetscValidHeaderSpecific(iscol,IS_COOKIE,3);
5432   PetscValidPointer(newmat,6);
5433   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_COOKIE,6);
5434   PetscValidType(mat,1);
5435   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5436   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5437   ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr);
5438 
5439   /* if original matrix is on just one processor then use submatrix generated */
5440   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
5441     ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
5442     PetscFunctionReturn(0);
5443   } else if (!mat->ops->getsubmatrix && size == 1) {
5444     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
5445     *newmat = *local;
5446     ierr    = PetscFree(local);CHKERRQ(ierr);
5447     PetscFunctionReturn(0);
5448   }
5449 
5450   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5451   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscol,csize,cll,newmat);CHKERRQ(ierr);
5452   ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);
5453   PetscFunctionReturn(0);
5454 }
5455 
5456 #undef __FUNCT__
5457 #define __FUNCT__ "MatGetSubMatrixRaw"
5458 /*@
5459     MatGetSubMatrixRaw - Gets a single submatrix on the same number of processors
5460                          as the original matrix.
5461 
5462     Collective on Mat
5463 
5464     Input Parameters:
5465 +   mat - the original matrix
5466 .   nrows - the number of rows this processor should obtain
5467 .   rows - rows this processor should obtain
5468 .   ncols - the number of columns for all processors you wish to keep
5469 .   cols - columns for all processors you wish to keep
5470 .   csize - number of columns "local" to this processor (does nothing for sequential
5471             matrices). This should match the result from VecGetLocalSize(x,...) if you
5472             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
5473 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
5474 
5475     Output Parameter:
5476 .   newmat - the new submatrix, of the same type as the old
5477 
5478     Level: advanced
5479 
5480     Notes: the iscol argument MUST be the same on each processor. You might be
5481     able to create the iscol argument with ISAllGather().
5482 
5483       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
5484    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
5485    to this routine with a mat of the same nonzero structure and with a cll of MAT_REUSE_MATRIX
5486    will reuse the matrix generated the first time.
5487 
5488     Concepts: matrices^submatrices
5489 
5490 .seealso: MatGetSubMatrices(), ISAllGather()
5491 @*/
5492 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrixRaw(Mat mat,PetscInt nrows,const PetscInt rows[],PetscInt ncols,const PetscInt cols[],PetscInt csize,MatReuse cll,Mat *newmat)
5493 {
5494   IS             isrow, iscol;
5495   PetscErrorCode ierr;
5496 
5497   PetscFunctionBegin;
5498   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5499   PetscValidIntPointer(rows,2);
5500   PetscValidIntPointer(cols,3);
5501   PetscValidPointer(newmat,6);
5502   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_COOKIE,6);
5503   PetscValidType(mat,1);
5504   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5505   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5506   ierr = ISCreateGeneralWithArray(PETSC_COMM_SELF, nrows, (PetscInt *) rows, &isrow);CHKERRQ(ierr);
5507   ierr = ISCreateGeneralWithArray(PETSC_COMM_SELF, ncols, (PetscInt *) cols, &iscol);CHKERRQ(ierr);
5508   ierr = MatGetSubMatrix(mat, isrow, iscol, csize, cll, newmat);CHKERRQ(ierr);
5509   ierr = ISDestroy(isrow);CHKERRQ(ierr);
5510   ierr = ISDestroy(iscol);CHKERRQ(ierr);
5511   PetscFunctionReturn(0);
5512 }
5513 
5514 #undef __FUNCT__
5515 #define __FUNCT__ "MatStashSetInitialSize"
5516 /*@
5517    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
5518    used during the assembly process to store values that belong to
5519    other processors.
5520 
5521    Not Collective
5522 
5523    Input Parameters:
5524 +  mat   - the matrix
5525 .  size  - the initial size of the stash.
5526 -  bsize - the initial size of the block-stash(if used).
5527 
5528    Options Database Keys:
5529 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
5530 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
5531 
5532    Level: intermediate
5533 
5534    Notes:
5535      The block-stash is used for values set with MatSetValuesBlocked() while
5536      the stash is used for values set with MatSetValues()
5537 
5538      Run with the option -info and look for output of the form
5539      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
5540      to determine the appropriate value, MM, to use for size and
5541      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
5542      to determine the value, BMM to use for bsize
5543 
5544    Concepts: stash^setting matrix size
5545    Concepts: matrices^stash
5546 
5547 @*/
5548 PetscErrorCode PETSCMAT_DLLEXPORT MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
5549 {
5550   PetscErrorCode ierr;
5551 
5552   PetscFunctionBegin;
5553   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5554   PetscValidType(mat,1);
5555   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
5556   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
5557   PetscFunctionReturn(0);
5558 }
5559 
5560 #undef __FUNCT__
5561 #define __FUNCT__ "MatInterpolateAdd"
5562 /*@
5563    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
5564      the matrix
5565 
5566    Collective on Mat
5567 
5568    Input Parameters:
5569 +  mat   - the matrix
5570 .  x,y - the vectors
5571 -  w - where the result is stored
5572 
5573    Level: intermediate
5574 
5575    Notes:
5576     w may be the same vector as y.
5577 
5578     This allows one to use either the restriction or interpolation (its transpose)
5579     matrix to do the interpolation
5580 
5581     Concepts: interpolation
5582 
5583 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
5584 
5585 @*/
5586 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
5587 {
5588   PetscErrorCode ierr;
5589   PetscInt       M,N;
5590 
5591   PetscFunctionBegin;
5592   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5593   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
5594   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
5595   PetscValidHeaderSpecific(w,VEC_COOKIE,4);
5596   PetscValidType(A,1);
5597   ierr = MatPreallocated(A);CHKERRQ(ierr);
5598   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
5599   if (N > M) {
5600     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
5601   } else {
5602     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
5603   }
5604   PetscFunctionReturn(0);
5605 }
5606 
5607 #undef __FUNCT__
5608 #define __FUNCT__ "MatInterpolate"
5609 /*@
5610    MatInterpolate - y = A*x or A'*x depending on the shape of
5611      the matrix
5612 
5613    Collective on Mat
5614 
5615    Input Parameters:
5616 +  mat   - the matrix
5617 -  x,y - the vectors
5618 
5619    Level: intermediate
5620 
5621    Notes:
5622     This allows one to use either the restriction or interpolation (its transpose)
5623     matrix to do the interpolation
5624 
5625    Concepts: matrices^interpolation
5626 
5627 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
5628 
5629 @*/
5630 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolate(Mat A,Vec x,Vec y)
5631 {
5632   PetscErrorCode ierr;
5633   PetscInt       M,N;
5634 
5635   PetscFunctionBegin;
5636   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5637   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
5638   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
5639   PetscValidType(A,1);
5640   ierr = MatPreallocated(A);CHKERRQ(ierr);
5641   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
5642   if (N > M) {
5643     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
5644   } else {
5645     ierr = MatMult(A,x,y);CHKERRQ(ierr);
5646   }
5647   PetscFunctionReturn(0);
5648 }
5649 
5650 #undef __FUNCT__
5651 #define __FUNCT__ "MatRestrict"
5652 /*@
5653    MatRestrict - y = A*x or A'*x
5654 
5655    Collective on Mat
5656 
5657    Input Parameters:
5658 +  mat   - the matrix
5659 -  x,y - the vectors
5660 
5661    Level: intermediate
5662 
5663    Notes:
5664     This allows one to use either the restriction or interpolation (its transpose)
5665     matrix to do the restriction
5666 
5667    Concepts: matrices^restriction
5668 
5669 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
5670 
5671 @*/
5672 PetscErrorCode PETSCMAT_DLLEXPORT MatRestrict(Mat A,Vec x,Vec y)
5673 {
5674   PetscErrorCode ierr;
5675   PetscInt       M,N;
5676 
5677   PetscFunctionBegin;
5678   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5679   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
5680   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
5681   PetscValidType(A,1);
5682   ierr = MatPreallocated(A);CHKERRQ(ierr);
5683 
5684   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
5685   if (N > M) {
5686     ierr = MatMult(A,x,y);CHKERRQ(ierr);
5687   } else {
5688     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
5689   }
5690   PetscFunctionReturn(0);
5691 }
5692 
5693 #undef __FUNCT__
5694 #define __FUNCT__ "MatNullSpaceAttach"
5695 /*@C
5696    MatNullSpaceAttach - attaches a null space to a matrix.
5697         This null space will be removed from the resulting vector whenever
5698         MatMult() is called
5699 
5700    Collective on Mat
5701 
5702    Input Parameters:
5703 +  mat - the matrix
5704 -  nullsp - the null space object
5705 
5706    Level: developer
5707 
5708    Notes:
5709       Overwrites any previous null space that may have been attached
5710 
5711    Concepts: null space^attaching to matrix
5712 
5713 .seealso: MatCreate(), MatNullSpaceCreate()
5714 @*/
5715 PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
5716 {
5717   PetscErrorCode ierr;
5718 
5719   PetscFunctionBegin;
5720   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5721   PetscValidType(mat,1);
5722   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_COOKIE,2);
5723   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5724 
5725   if (mat->nullsp) {
5726     ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr);
5727   }
5728   mat->nullsp = nullsp;
5729   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
5730   PetscFunctionReturn(0);
5731 }
5732 
5733 #undef __FUNCT__
5734 #define __FUNCT__ "MatICCFactor"
5735 /*@
5736    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
5737 
5738    Collective on Mat
5739 
5740    Input Parameters:
5741 +  mat - the matrix
5742 .  row - row/column permutation
5743 .  fill - expected fill factor >= 1.0
5744 -  level - level of fill, for ICC(k)
5745 
5746    Notes:
5747    Probably really in-place only when level of fill is zero, otherwise allocates
5748    new space to store factored matrix and deletes previous memory.
5749 
5750    Most users should employ the simplified KSP interface for linear solvers
5751    instead of working directly with matrix algebra routines such as this.
5752    See, e.g., KSPCreate().
5753 
5754    Level: developer
5755 
5756    Concepts: matrices^incomplete Cholesky factorization
5757    Concepts: Cholesky factorization
5758 
5759 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5760 @*/
5761 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactor(Mat mat,IS row,MatFactorInfo* info)
5762 {
5763   PetscErrorCode ierr;
5764 
5765   PetscFunctionBegin;
5766   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5767   PetscValidType(mat,1);
5768   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
5769   PetscValidPointer(info,3);
5770   if (mat->rmap.N != mat->cmap.N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
5771   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5772   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5773   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5774   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5775   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
5776   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5777   PetscFunctionReturn(0);
5778 }
5779 
5780 #undef __FUNCT__
5781 #define __FUNCT__ "MatSetValuesAdic"
5782 /*@
5783    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
5784 
5785    Not Collective
5786 
5787    Input Parameters:
5788 +  mat - the matrix
5789 -  v - the values compute with ADIC
5790 
5791    Level: developer
5792 
5793    Notes:
5794      Must call MatSetColoring() before using this routine. Also this matrix must already
5795      have its nonzero pattern determined.
5796 
5797 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5798           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
5799 @*/
5800 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdic(Mat mat,void *v)
5801 {
5802   PetscErrorCode ierr;
5803 
5804   PetscFunctionBegin;
5805   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5806   PetscValidType(mat,1);
5807   PetscValidPointer(mat,2);
5808 
5809   if (!mat->assembled) {
5810     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
5811   }
5812   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5813   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5814   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
5815   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5816   ierr = MatView_Private(mat);CHKERRQ(ierr);
5817   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5818   PetscFunctionReturn(0);
5819 }
5820 
5821 
5822 #undef __FUNCT__
5823 #define __FUNCT__ "MatSetColoring"
5824 /*@
5825    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
5826 
5827    Not Collective
5828 
5829    Input Parameters:
5830 +  mat - the matrix
5831 -  coloring - the coloring
5832 
5833    Level: developer
5834 
5835 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5836           MatSetValues(), MatSetValuesAdic()
5837 @*/
5838 PetscErrorCode PETSCMAT_DLLEXPORT MatSetColoring(Mat mat,ISColoring coloring)
5839 {
5840   PetscErrorCode ierr;
5841 
5842   PetscFunctionBegin;
5843   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5844   PetscValidType(mat,1);
5845   PetscValidPointer(coloring,2);
5846 
5847   if (!mat->assembled) {
5848     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
5849   }
5850   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5851   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
5852   PetscFunctionReturn(0);
5853 }
5854 
5855 #undef __FUNCT__
5856 #define __FUNCT__ "MatSetValuesAdifor"
5857 /*@
5858    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
5859 
5860    Not Collective
5861 
5862    Input Parameters:
5863 +  mat - the matrix
5864 .  nl - leading dimension of v
5865 -  v - the values compute with ADIFOR
5866 
5867    Level: developer
5868 
5869    Notes:
5870      Must call MatSetColoring() before using this routine. Also this matrix must already
5871      have its nonzero pattern determined.
5872 
5873 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5874           MatSetValues(), MatSetColoring()
5875 @*/
5876 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
5877 {
5878   PetscErrorCode ierr;
5879 
5880   PetscFunctionBegin;
5881   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5882   PetscValidType(mat,1);
5883   PetscValidPointer(v,3);
5884 
5885   if (!mat->assembled) {
5886     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
5887   }
5888   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5889   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5890   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
5891   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5892   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5893   PetscFunctionReturn(0);
5894 }
5895 
5896 #undef __FUNCT__
5897 #define __FUNCT__ "MatDiagonalScaleLocal"
5898 /*@
5899    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
5900          ghosted ones.
5901 
5902    Not Collective
5903 
5904    Input Parameters:
5905 +  mat - the matrix
5906 -  diag = the diagonal values, including ghost ones
5907 
5908    Level: developer
5909 
5910    Notes: Works only for MPIAIJ and MPIBAIJ matrices
5911 
5912 .seealso: MatDiagonalScale()
5913 @*/
5914 PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalScaleLocal(Mat mat,Vec diag)
5915 {
5916   PetscErrorCode ierr;
5917   PetscMPIInt    size;
5918 
5919   PetscFunctionBegin;
5920   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5921   PetscValidHeaderSpecific(diag,VEC_COOKIE,2);
5922   PetscValidType(mat,1);
5923 
5924   if (!mat->assembled) {
5925     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
5926   }
5927   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5928   ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr);
5929   if (size == 1) {
5930     PetscInt n,m;
5931     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
5932     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
5933     if (m == n) {
5934       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
5935     } else {
5936       SETERRQ(PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
5937     }
5938   } else {
5939     PetscErrorCode (*f)(Mat,Vec);
5940     ierr = PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);CHKERRQ(ierr);
5941     if (f) {
5942       ierr = (*f)(mat,diag);CHKERRQ(ierr);
5943     } else {
5944       SETERRQ(PETSC_ERR_SUP,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
5945     }
5946   }
5947   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5948   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5949   PetscFunctionReturn(0);
5950 }
5951 
5952 #undef __FUNCT__
5953 #define __FUNCT__ "MatGetInertia"
5954 /*@
5955    MatGetInertia - Gets the inertia from a factored matrix
5956 
5957    Collective on Mat
5958 
5959    Input Parameter:
5960 .  mat - the matrix
5961 
5962    Output Parameters:
5963 +   nneg - number of negative eigenvalues
5964 .   nzero - number of zero eigenvalues
5965 -   npos - number of positive eigenvalues
5966 
5967    Level: advanced
5968 
5969    Notes: Matrix must have been factored by MatCholeskyFactor()
5970 
5971 
5972 @*/
5973 PetscErrorCode PETSCMAT_DLLEXPORT MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
5974 {
5975   PetscErrorCode ierr;
5976 
5977   PetscFunctionBegin;
5978   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5979   PetscValidType(mat,1);
5980   if (!mat->factor)    SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
5981   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
5982   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5983   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
5984   PetscFunctionReturn(0);
5985 }
5986 
5987 /* ----------------------------------------------------------------*/
5988 #undef __FUNCT__
5989 #define __FUNCT__ "MatSolves"
5990 /*@
5991    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
5992 
5993    Collective on Mat and Vecs
5994 
5995    Input Parameters:
5996 +  mat - the factored matrix
5997 -  b - the right-hand-side vectors
5998 
5999    Output Parameter:
6000 .  x - the result vectors
6001 
6002    Notes:
6003    The vectors b and x cannot be the same.  I.e., one cannot
6004    call MatSolves(A,x,x).
6005 
6006    Notes:
6007    Most users should employ the simplified KSP interface for linear solvers
6008    instead of working directly with matrix algebra routines such as this.
6009    See, e.g., KSPCreate().
6010 
6011    Level: developer
6012 
6013    Concepts: matrices^triangular solves
6014 
6015 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
6016 @*/
6017 PetscErrorCode PETSCMAT_DLLEXPORT MatSolves(Mat mat,Vecs b,Vecs x)
6018 {
6019   PetscErrorCode ierr;
6020 
6021   PetscFunctionBegin;
6022   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6023   PetscValidType(mat,1);
6024   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
6025   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6026   if (!mat->rmap.N && !mat->cmap.N) PetscFunctionReturn(0);
6027 
6028   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
6029   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6030   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
6031   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
6032   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
6033   PetscFunctionReturn(0);
6034 }
6035 
6036 #undef __FUNCT__
6037 #define __FUNCT__ "MatIsSymmetric"
6038 /*@
6039    MatIsSymmetric - Test whether a matrix is symmetric
6040 
6041    Collective on Mat
6042 
6043    Input Parameter:
6044 +  A - the matrix to test
6045 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
6046 
6047    Output Parameters:
6048 .  flg - the result
6049 
6050    Level: intermediate
6051 
6052    Concepts: matrix^symmetry
6053 
6054 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6055 @*/
6056 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetric(Mat A,PetscReal tol,PetscTruth *flg)
6057 {
6058   PetscErrorCode ierr;
6059 
6060   PetscFunctionBegin;
6061   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6062   PetscValidPointer(flg,2);
6063   if (!A->symmetric_set) {
6064     if (!A->ops->issymmetric) {
6065       MatType mattype;
6066       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
6067       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
6068     }
6069     ierr = (*A->ops->issymmetric)(A,tol,&A->symmetric);CHKERRQ(ierr);
6070     A->symmetric_set = PETSC_TRUE;
6071     if (A->symmetric) {
6072       A->structurally_symmetric_set = PETSC_TRUE;
6073       A->structurally_symmetric     = PETSC_TRUE;
6074     }
6075   }
6076   *flg = A->symmetric;
6077   PetscFunctionReturn(0);
6078 }
6079 
6080 #undef __FUNCT__
6081 #define __FUNCT__ "MatIsSymmetricKnown"
6082 /*@
6083    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
6084 
6085    Collective on Mat
6086 
6087    Input Parameter:
6088 .  A - the matrix to check
6089 
6090    Output Parameters:
6091 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
6092 -  flg - the result
6093 
6094    Level: advanced
6095 
6096    Concepts: matrix^symmetry
6097 
6098    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
6099          if you want it explicitly checked
6100 
6101 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6102 @*/
6103 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetricKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6104 {
6105   PetscFunctionBegin;
6106   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6107   PetscValidPointer(set,2);
6108   PetscValidPointer(flg,3);
6109   if (A->symmetric_set) {
6110     *set = PETSC_TRUE;
6111     *flg = A->symmetric;
6112   } else {
6113     *set = PETSC_FALSE;
6114   }
6115   PetscFunctionReturn(0);
6116 }
6117 
6118 #undef __FUNCT__
6119 #define __FUNCT__ "MatIsHermitianKnown"
6120 /*@
6121    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
6122 
6123    Collective on Mat
6124 
6125    Input Parameter:
6126 .  A - the matrix to check
6127 
6128    Output Parameters:
6129 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
6130 -  flg - the result
6131 
6132    Level: advanced
6133 
6134    Concepts: matrix^symmetry
6135 
6136    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
6137          if you want it explicitly checked
6138 
6139 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6140 @*/
6141 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitianKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6142 {
6143   PetscFunctionBegin;
6144   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6145   PetscValidPointer(set,2);
6146   PetscValidPointer(flg,3);
6147   if (A->hermitian_set) {
6148     *set = PETSC_TRUE;
6149     *flg = A->hermitian;
6150   } else {
6151     *set = PETSC_FALSE;
6152   }
6153   PetscFunctionReturn(0);
6154 }
6155 
6156 #undef __FUNCT__
6157 #define __FUNCT__ "MatIsStructurallySymmetric"
6158 /*@
6159    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
6160 
6161    Collective on Mat
6162 
6163    Input Parameter:
6164 .  A - the matrix to test
6165 
6166    Output Parameters:
6167 .  flg - the result
6168 
6169    Level: intermediate
6170 
6171    Concepts: matrix^symmetry
6172 
6173 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
6174 @*/
6175 PetscErrorCode PETSCMAT_DLLEXPORT MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
6176 {
6177   PetscErrorCode ierr;
6178 
6179   PetscFunctionBegin;
6180   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6181   PetscValidPointer(flg,2);
6182   if (!A->structurally_symmetric_set) {
6183     if (!A->ops->isstructurallysymmetric) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
6184     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
6185     A->structurally_symmetric_set = PETSC_TRUE;
6186   }
6187   *flg = A->structurally_symmetric;
6188   PetscFunctionReturn(0);
6189 }
6190 
6191 #undef __FUNCT__
6192 #define __FUNCT__ "MatIsHermitian"
6193 /*@
6194    MatIsHermitian - Test whether a matrix is Hermitian, i.e. it is the complex conjugate of its transpose.
6195 
6196    Collective on Mat
6197 
6198    Input Parameter:
6199 .  A - the matrix to test
6200 
6201    Output Parameters:
6202 .  flg - the result
6203 
6204    Level: intermediate
6205 
6206    Concepts: matrix^symmetry
6207 
6208 .seealso: MatTranspose(), MatIsTranspose(), MatIsSymmetric(), MatIsStructurallySymmetric(), MatSetOption()
6209 @*/
6210 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitian(Mat A,PetscTruth *flg)
6211 {
6212   PetscErrorCode ierr;
6213 
6214   PetscFunctionBegin;
6215   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6216   PetscValidPointer(flg,2);
6217   if (!A->hermitian_set) {
6218     if (!A->ops->ishermitian) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for being Hermitian");
6219     ierr = (*A->ops->ishermitian)(A,&A->hermitian);CHKERRQ(ierr);
6220     A->hermitian_set = PETSC_TRUE;
6221     if (A->hermitian) {
6222       A->structurally_symmetric_set = PETSC_TRUE;
6223       A->structurally_symmetric     = PETSC_TRUE;
6224     }
6225   }
6226   *flg = A->hermitian;
6227   PetscFunctionReturn(0);
6228 }
6229 
6230 #undef __FUNCT__
6231 #define __FUNCT__ "MatStashGetInfo"
6232 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
6233 /*@
6234    MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
6235        to be communicated to other processors during the MatAssemblyBegin/End() process
6236 
6237     Not collective
6238 
6239    Input Parameter:
6240 .   vec - the vector
6241 
6242    Output Parameters:
6243 +   nstash   - the size of the stash
6244 .   reallocs - the number of additional mallocs incurred.
6245 .   bnstash   - the size of the block stash
6246 -   breallocs - the number of additional mallocs incurred.in the block stash
6247 
6248    Level: advanced
6249 
6250 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
6251 
6252 @*/
6253 PetscErrorCode PETSCMAT_DLLEXPORT MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
6254 {
6255   PetscErrorCode ierr;
6256   PetscFunctionBegin;
6257   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
6258   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
6259   PetscFunctionReturn(0);
6260 }
6261 
6262 #undef __FUNCT__
6263 #define __FUNCT__ "MatGetVecs"
6264 /*@
6265    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
6266      parallel layout
6267 
6268    Collective on Mat
6269 
6270    Input Parameter:
6271 .  mat - the matrix
6272 
6273    Output Parameter:
6274 +   right - (optional) vector that the matrix can be multiplied against
6275 -   left - (optional) vector that the matrix vector product can be stored in
6276 
6277   Level: advanced
6278 
6279 .seealso: MatCreate()
6280 @*/
6281 PetscErrorCode PETSCMAT_DLLEXPORT MatGetVecs(Mat mat,Vec *right,Vec *left)
6282 {
6283   PetscErrorCode ierr;
6284 
6285   PetscFunctionBegin;
6286   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6287   PetscValidType(mat,1);
6288   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6289   if (mat->ops->getvecs) {
6290     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
6291   } else {
6292     PetscMPIInt size;
6293     ierr = MPI_Comm_size(mat->comm, &size);CHKERRQ(ierr);
6294     if (right) {
6295       ierr = VecCreate(mat->comm,right);CHKERRQ(ierr);
6296       ierr = VecSetSizes(*right,mat->cmap.n,PETSC_DETERMINE);CHKERRQ(ierr);
6297       if (size > 1) {ierr = VecSetType(*right,VECMPI);CHKERRQ(ierr);}
6298       else {ierr = VecSetType(*right,VECSEQ);CHKERRQ(ierr);}
6299     }
6300     if (left) {
6301       ierr = VecCreate(mat->comm,left);CHKERRQ(ierr);
6302       ierr = VecSetSizes(*left,mat->rmap.n,PETSC_DETERMINE);CHKERRQ(ierr);
6303       if (size > 1) {ierr = VecSetType(*left,VECMPI);CHKERRQ(ierr);}
6304       else {ierr = VecSetType(*left,VECSEQ);CHKERRQ(ierr);}
6305     }
6306   }
6307   if (right) {ierr = VecSetBlockSize(*right,mat->rmap.bs);CHKERRQ(ierr);}
6308   if (left) {ierr = VecSetBlockSize(*left,mat->rmap.bs);CHKERRQ(ierr);}
6309   PetscFunctionReturn(0);
6310 }
6311 
6312 #undef __FUNCT__
6313 #define __FUNCT__ "MatFactorInfoInitialize"
6314 /*@
6315    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
6316      with default values.
6317 
6318    Not Collective
6319 
6320    Input Parameters:
6321 .    info - the MatFactorInfo data structure
6322 
6323 
6324    Notes: The solvers are generally used through the KSP and PC objects, for example
6325           PCLU, PCILU, PCCHOLESKY, PCICC
6326 
6327    Level: developer
6328 
6329 .seealso: MatFactorInfo
6330 @*/
6331 
6332 PetscErrorCode PETSCMAT_DLLEXPORT MatFactorInfoInitialize(MatFactorInfo *info)
6333 {
6334   PetscErrorCode ierr;
6335 
6336   PetscFunctionBegin;
6337   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
6338   PetscFunctionReturn(0);
6339 }
6340 
6341 #undef __FUNCT__
6342 #define __FUNCT__ "MatPtAP"
6343 /*@
6344    MatPtAP - Creates the matrix projection C = P^T * A * P
6345 
6346    Collective on Mat
6347 
6348    Input Parameters:
6349 +  A - the matrix
6350 .  P - the projection matrix
6351 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6352 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))
6353 
6354    Output Parameters:
6355 .  C - the product matrix
6356 
6357    Notes:
6358    C will be created and must be destroyed by the user with MatDestroy().
6359 
6360    This routine is currently only implemented for pairs of AIJ matrices and classes
6361    which inherit from AIJ.
6362 
6363    Level: intermediate
6364 
6365 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
6366 @*/
6367 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
6368 {
6369   PetscErrorCode ierr;
6370 
6371   PetscFunctionBegin;
6372   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6373   PetscValidType(A,1);
6374   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6375   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6376   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
6377   PetscValidType(P,2);
6378   MatPreallocated(P);
6379   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6380   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6381   PetscValidPointer(C,3);
6382   if (P->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap.N,A->cmap.N);
6383   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
6384   ierr = MatPreallocated(A);CHKERRQ(ierr);
6385 
6386   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
6387   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
6388   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
6389 
6390   PetscFunctionReturn(0);
6391 }
6392 
6393 #undef __FUNCT__
6394 #define __FUNCT__ "MatPtAPNumeric"
6395 /*@
6396    MatPtAPNumeric - Computes the matrix projection C = P^T * A * P
6397 
6398    Collective on Mat
6399 
6400    Input Parameters:
6401 +  A - the matrix
6402 -  P - the projection matrix
6403 
6404    Output Parameters:
6405 .  C - the product matrix
6406 
6407    Notes:
6408    C must have been created by calling MatPtAPSymbolic and must be destroyed by
6409    the user using MatDeatroy().
6410 
6411    This routine is currently only implemented for pairs of AIJ matrices and classes
6412    which inherit from AIJ.  C will be of type MATAIJ.
6413 
6414    Level: intermediate
6415 
6416 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
6417 @*/
6418 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPNumeric(Mat A,Mat P,Mat C)
6419 {
6420   PetscErrorCode ierr;
6421 
6422   PetscFunctionBegin;
6423   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6424   PetscValidType(A,1);
6425   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6426   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6427   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
6428   PetscValidType(P,2);
6429   MatPreallocated(P);
6430   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6431   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6432   PetscValidHeaderSpecific(C,MAT_COOKIE,3);
6433   PetscValidType(C,3);
6434   MatPreallocated(C);
6435   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6436   if (P->cmap.N!=C->rmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap.N,C->rmap.N);
6437   if (P->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap.N,A->cmap.N);
6438   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);
6439   if (P->cmap.N!=C->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap.N,C->cmap.N);
6440   ierr = MatPreallocated(A);CHKERRQ(ierr);
6441 
6442   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
6443   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
6444   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
6445   PetscFunctionReturn(0);
6446 }
6447 
6448 #undef __FUNCT__
6449 #define __FUNCT__ "MatPtAPSymbolic"
6450 /*@
6451    MatPtAPSymbolic - Creates the (i,j) structure of the matrix projection C = P^T * A * P
6452 
6453    Collective on Mat
6454 
6455    Input Parameters:
6456 +  A - the matrix
6457 -  P - the projection matrix
6458 
6459    Output Parameters:
6460 .  C - the (i,j) structure of the product matrix
6461 
6462    Notes:
6463    C will be created and must be destroyed by the user with MatDestroy().
6464 
6465    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
6466    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
6467    this (i,j) structure by calling MatPtAPNumeric().
6468 
6469    Level: intermediate
6470 
6471 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
6472 @*/
6473 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
6474 {
6475   PetscErrorCode ierr;
6476 
6477   PetscFunctionBegin;
6478   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6479   PetscValidType(A,1);
6480   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6481   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6482   if (fill <1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
6483   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
6484   PetscValidType(P,2);
6485   MatPreallocated(P);
6486   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6487   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6488   PetscValidPointer(C,3);
6489 
6490   if (P->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap.N,A->cmap.N);
6491   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);
6492   ierr = MatPreallocated(A);CHKERRQ(ierr);
6493   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
6494   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
6495   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
6496 
6497   ierr = MatSetBlockSize(*C,A->rmap.bs);CHKERRQ(ierr);
6498 
6499   PetscFunctionReturn(0);
6500 }
6501 
6502 #undef __FUNCT__
6503 #define __FUNCT__ "MatMatMult"
6504 /*@
6505    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
6506 
6507    Collective on Mat
6508 
6509    Input Parameters:
6510 +  A - the left matrix
6511 .  B - the right matrix
6512 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6513 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B))
6514 
6515    Output Parameters:
6516 .  C - the product matrix
6517 
6518    Notes:
6519    C will be created and must be destroyed by the user with MatDestroy().
6520    Unless scall is MAT_REUSE_MATRIX
6521 
6522    If you have many matrices with the same non-zero structure to multiply, you
6523    should either
6524 $   1) use MAT_REUSE_MATRIX in all calls but the first or
6525 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
6526 
6527    Level: intermediate
6528 
6529 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
6530 @*/
6531 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
6532 {
6533   PetscErrorCode ierr;
6534   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
6535   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
6536   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
6537 
6538   PetscFunctionBegin;
6539   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6540   PetscValidType(A,1);
6541   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6542   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6543   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
6544   PetscValidType(B,2);
6545   MatPreallocated(B);
6546   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6547   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6548   PetscValidPointer(C,3);
6549   if (B->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->cmap.N);
6550   if (fill <1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill=%G must be >= 1.0",fill);
6551   ierr = MatPreallocated(A);CHKERRQ(ierr);
6552 
6553   fA = A->ops->matmult;
6554   fB = B->ops->matmult;
6555   if (fB == fA) {
6556     if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",B->type_name);
6557     mult = fB;
6558   } else {
6559     /* dispatch based on the type of A and B */
6560     char  multname[256];
6561     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
6562     ierr = PetscStrcat(multname,A->type_name);CHKERRQ(ierr);
6563     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
6564     ierr = PetscStrcat(multname,B->type_name);CHKERRQ(ierr);
6565     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_aij_dense_C" */
6566     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
6567     if (!mult) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",A->type_name,B->type_name);
6568   }
6569   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
6570   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
6571   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
6572   PetscFunctionReturn(0);
6573 }
6574 
6575 #undef __FUNCT__
6576 #define __FUNCT__ "MatMatMultSymbolic"
6577 /*@
6578    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
6579    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
6580 
6581    Collective on Mat
6582 
6583    Input Parameters:
6584 +  A - the left matrix
6585 .  B - the right matrix
6586 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B))
6587 
6588    Output Parameters:
6589 .  C - the matrix containing the ij structure of product matrix
6590 
6591    Notes:
6592    C will be created and must be destroyed by the user with MatDestroy().
6593 
6594    This routine is currently implemented for
6595     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
6596     - pairs of AIJ (A) and Dense (B) matrix, C will be of type MATDENSE.
6597 
6598    Level: intermediate
6599 
6600 .seealso: MatMatMult(), MatMatMultNumeric()
6601 @*/
6602 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
6603 {
6604   PetscErrorCode ierr;
6605   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
6606   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
6607   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
6608 
6609   PetscFunctionBegin;
6610   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6611   PetscValidType(A,1);
6612   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6613   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6614 
6615   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
6616   PetscValidType(B,2);
6617   MatPreallocated(B);
6618   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6619   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6620   PetscValidPointer(C,3);
6621 
6622   if (B->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->cmap.N);
6623   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
6624   ierr = MatPreallocated(A);CHKERRQ(ierr);
6625 
6626   Asymbolic = A->ops->matmultsymbolic;
6627   Bsymbolic = B->ops->matmultsymbolic;
6628   if (Asymbolic == Bsymbolic){
6629     if (!Bsymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",B->type_name);
6630     symbolic = Bsymbolic;
6631   } else { /* dispatch based on the type of A and B */
6632     char  symbolicname[256];
6633     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
6634     ierr = PetscStrcat(symbolicname,A->type_name);CHKERRQ(ierr);
6635     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
6636     ierr = PetscStrcat(symbolicname,B->type_name);CHKERRQ(ierr);
6637     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
6638     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
6639     if (!symbolic) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",A->type_name,B->type_name);
6640   }
6641   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
6642   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
6643   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
6644   PetscFunctionReturn(0);
6645 }
6646 
6647 #undef __FUNCT__
6648 #define __FUNCT__ "MatMatMultNumeric"
6649 /*@
6650    MatMatMultNumeric - Performs the numeric matrix-matrix product.
6651    Call this routine after first calling MatMatMultSymbolic().
6652 
6653    Collective on Mat
6654 
6655    Input Parameters:
6656 +  A - the left matrix
6657 -  B - the right matrix
6658 
6659    Output Parameters:
6660 .  C - the product matrix, whose ij structure was defined from MatMatMultSymbolic().
6661 
6662    Notes:
6663    C must have been created with MatMatMultSymbolic.
6664 
6665    This routine is currently implemented for
6666     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
6667     - pairs of AIJ (A) and Dense (B) matrix, C will be of type MATDENSE.
6668 
6669    Level: intermediate
6670 
6671 .seealso: MatMatMult(), MatMatMultSymbolic()
6672 @*/
6673 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultNumeric(Mat A,Mat B,Mat C)
6674 {
6675   PetscErrorCode ierr;
6676   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
6677   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
6678   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
6679 
6680   PetscFunctionBegin;
6681   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6682   PetscValidType(A,1);
6683   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6684   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6685 
6686   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
6687   PetscValidType(B,2);
6688   MatPreallocated(B);
6689   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6690   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6691 
6692   PetscValidHeaderSpecific(C,MAT_COOKIE,3);
6693   PetscValidType(C,3);
6694   MatPreallocated(C);
6695   if (!C->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6696   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6697 
6698   if (B->cmap.N!=C->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap.N,C->cmap.N);
6699   if (B->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->cmap.N);
6700   if (A->rmap.N!=C->rmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap.N,C->rmap.N);
6701   ierr = MatPreallocated(A);CHKERRQ(ierr);
6702 
6703   Anumeric = A->ops->matmultnumeric;
6704   Bnumeric = B->ops->matmultnumeric;
6705   if (Anumeric == Bnumeric){
6706     if (!Bnumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",B->type_name);
6707     numeric = Bnumeric;
6708   } else {
6709     char  numericname[256];
6710     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
6711     ierr = PetscStrcat(numericname,A->type_name);CHKERRQ(ierr);
6712     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
6713     ierr = PetscStrcat(numericname,B->type_name);CHKERRQ(ierr);
6714     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
6715     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
6716     if (!numeric)
6717       SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",A->type_name,B->type_name);
6718   }
6719   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
6720   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
6721   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
6722   PetscFunctionReturn(0);
6723 }
6724 
6725 #undef __FUNCT__
6726 #define __FUNCT__ "MatMatMultTranspose"
6727 /*@
6728    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
6729 
6730    Collective on Mat
6731 
6732    Input Parameters:
6733 +  A - the left matrix
6734 .  B - the right matrix
6735 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6736 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B))
6737 
6738    Output Parameters:
6739 .  C - the product matrix
6740 
6741    Notes:
6742    C will be created and must be destroyed by the user with MatDestroy().
6743 
6744    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
6745    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
6746 
6747    Level: intermediate
6748 
6749 .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
6750 @*/
6751 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
6752 {
6753   PetscErrorCode ierr;
6754   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
6755   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
6756 
6757   PetscFunctionBegin;
6758   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6759   PetscValidType(A,1);
6760   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6761   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6762   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
6763   PetscValidType(B,2);
6764   MatPreallocated(B);
6765   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6766   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6767   PetscValidPointer(C,3);
6768   if (B->rmap.N!=A->rmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->rmap.N);
6769   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
6770   ierr = MatPreallocated(A);CHKERRQ(ierr);
6771 
6772   fA = A->ops->matmulttranspose;
6773   if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",A->type_name);
6774   fB = B->ops->matmulttranspose;
6775   if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",B->type_name);
6776   if (fB!=fA) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultTranspose requires A, %s, to be compatible with B, %s",A->type_name,B->type_name);
6777 
6778   ierr = PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
6779   ierr = (*A->ops->matmulttranspose)(A,B,scall,fill,C);CHKERRQ(ierr);
6780   ierr = PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
6781 
6782   PetscFunctionReturn(0);
6783 }
6784