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