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