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