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