xref: /petsc/src/mat/interface/matrix.c (revision 92af4f6aefc23844bea461c68f556382c28b7521)
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   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 = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3113 
3114   ierr = PetscTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
3115   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
3116   if ((reuse==MAT_REUSE_MATRIX) && (mat != *M)) {
3117     SETERRQ(PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3118   }
3119   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3120     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
3121   } else {
3122     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=PETSC_NULL;
3123     const char     *prefix[3] = {"seq","mpi",""};
3124     PetscInt       i;
3125 
3126     /*
3127        Order of precedence:
3128        1) See if a specialized converter is known to the current matrix.
3129        2) See if a specialized converter is known to the desired matrix class.
3130        3) See if a good general converter is registered for the desired class
3131           (as of 6/27/03 only MATMPIADJ falls into this category).
3132        4) See if a good general converter is known for the current matrix.
3133        5) Use a really basic converter.
3134     */
3135     for (i=0; i<3; i++) {
3136       /* 1) See if a specialized converter is known to the current matrix and the desired class */
3137       ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
3138       ierr = PetscStrcat(convname,mat->type_name);CHKERRQ(ierr);
3139       ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3140       ierr = PetscStrcat(convname,prefix[i]);CHKERRQ(ierr);
3141       ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
3142       ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3143       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3144       if (conv) goto foundconv;
3145     }
3146 
3147     /* 2)  See if a specialized converter is known to the desired matrix class. */
3148     ierr = MatCreate(mat->comm,&B);CHKERRQ(ierr);
3149     ierr = MatSetSizes(B,mat->rmap.n,mat->cmap.n,mat->rmap.N,mat->cmap.N);CHKERRQ(ierr);
3150     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
3151     for (i=0; i<3; i++) {
3152       ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
3153       ierr = PetscStrcat(convname,mat->type_name);CHKERRQ(ierr);
3154       ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3155       ierr = PetscStrcat(convname,prefix[i]);CHKERRQ(ierr);
3156       ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
3157       ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3158       ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3159       if (conv) {
3160         ierr = MatDestroy(B);CHKERRQ(ierr);
3161         goto foundconv;
3162       }
3163     }
3164 
3165     /* 3) See if a good general converter is registered for the desired class */
3166     conv = B->ops->convertfrom;
3167     ierr = MatDestroy(B);CHKERRQ(ierr);
3168     if (conv) goto foundconv;
3169 
3170     /* 4) See if a good general converter is known for the current matrix */
3171     if (mat->ops->convert) {
3172       conv = mat->ops->convert;
3173     }
3174     if (conv) goto foundconv;
3175 
3176     /* 5) Use a really basic converter. */
3177     conv = MatConvert_Basic;
3178 
3179     foundconv:
3180     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
3181   }
3182   B = *M;
3183   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3184   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3185   PetscFunctionReturn(0);
3186 }
3187 
3188 
3189 #undef __FUNCT__
3190 #define __FUNCT__ "MatDuplicate"
3191 /*@
3192    MatDuplicate - Duplicates a matrix including the non-zero structure.
3193 
3194    Collective on Mat
3195 
3196    Input Parameters:
3197 +  mat - the matrix
3198 -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
3199         values as well or not
3200 
3201    Output Parameter:
3202 .  M - pointer to place new matrix
3203 
3204    Level: intermediate
3205 
3206    Concepts: matrices^duplicating
3207 
3208 .seealso: MatCopy(), MatConvert()
3209 @*/
3210 PetscErrorCode PETSCMAT_DLLEXPORT MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
3211 {
3212   PetscErrorCode ierr;
3213   Mat            B;
3214 
3215   PetscFunctionBegin;
3216   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3217   PetscValidType(mat,1);
3218   PetscValidPointer(M,3);
3219   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3220   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3221   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3222 
3223   *M  = 0;
3224   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3225   if (!mat->ops->duplicate) {
3226     SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type");
3227   }
3228   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
3229   B = *M;
3230   if (mat->mapping) {
3231     ierr = MatSetLocalToGlobalMapping(B,mat->mapping);CHKERRQ(ierr);
3232   }
3233   if (mat->bmapping) {
3234     ierr = MatSetLocalToGlobalMappingBlock(B,mat->bmapping);CHKERRQ(ierr);
3235   }
3236   ierr = PetscMapCopy(mat->comm,&mat->rmap,&B->rmap);CHKERRQ(ierr);
3237   ierr = PetscMapCopy(mat->comm,&mat->cmap,&B->cmap);CHKERRQ(ierr);
3238 
3239   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3240   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3241   PetscFunctionReturn(0);
3242 }
3243 
3244 #undef __FUNCT__
3245 #define __FUNCT__ "MatGetDiagonal"
3246 /*@
3247    MatGetDiagonal - Gets the diagonal of a matrix.
3248 
3249    Collective on Mat and Vec
3250 
3251    Input Parameters:
3252 +  mat - the matrix
3253 -  v - the vector for storing the diagonal
3254 
3255    Output Parameter:
3256 .  v - the diagonal of the matrix
3257 
3258    Notes: The result of this call are the same as if one converted the matrix to dense format
3259       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
3260 
3261    Level: intermediate
3262 
3263    Concepts: matrices^accessing diagonals
3264 
3265 .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
3266 @*/
3267 PetscErrorCode PETSCMAT_DLLEXPORT MatGetDiagonal(Mat mat,Vec v)
3268 {
3269   PetscErrorCode ierr;
3270 
3271   PetscFunctionBegin;
3272   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3273   PetscValidType(mat,1);
3274   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3275   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3276   if (!mat->ops->getdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3277   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3278 
3279   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
3280   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3281   PetscFunctionReturn(0);
3282 }
3283 
3284 #undef __FUNCT__
3285 #define __FUNCT__ "MatGetRowMin"
3286 /*@
3287    MatGetRowMin - Gets the minimum value (of the real part) of each
3288         row of the matrix
3289 
3290    Collective on Mat and Vec
3291 
3292    Input Parameters:
3293 .  mat - the matrix
3294 
3295    Output Parameter:
3296 +  v - the vector for storing the maximums
3297 -  idx - the indices of the column found for each row (optional)
3298 
3299    Level: intermediate
3300 
3301    Notes: The result of this call are the same as if one converted the matrix to dense format
3302       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
3303 
3304     This code is only implemented for a couple of matrix formats.
3305 
3306    Concepts: matrices^getting row maximums
3307 
3308 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
3309           MatGetRowMax()
3310 @*/
3311 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
3312 {
3313   PetscErrorCode ierr;
3314 
3315   PetscFunctionBegin;
3316   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3317   PetscValidType(mat,1);
3318   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3319   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3320   if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3321   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3322 
3323   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
3324   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3325   PetscFunctionReturn(0);
3326 }
3327 
3328 #undef __FUNCT__
3329 #define __FUNCT__ "MatGetRowMax"
3330 /*@
3331    MatGetRowMax - Gets the maximum value (of the real part) of each
3332         row of the matrix
3333 
3334    Collective on Mat and Vec
3335 
3336    Input Parameters:
3337 .  mat - the matrix
3338 
3339    Output Parameter:
3340 +  v - the vector for storing the maximums
3341 -  idx - the indices of the column found for each row (optional)
3342 
3343    Level: intermediate
3344 
3345    Notes: The result of this call are the same as if one converted the matrix to dense format
3346       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
3347 
3348     This code is only implemented for a couple of matrix formats.
3349 
3350    Concepts: matrices^getting row maximums
3351 
3352 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
3353 @*/
3354 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
3355 {
3356   PetscErrorCode ierr;
3357 
3358   PetscFunctionBegin;
3359   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3360   PetscValidType(mat,1);
3361   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3362   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3363   if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3364   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3365 
3366   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
3367   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3368   PetscFunctionReturn(0);
3369 }
3370 
3371 #undef __FUNCT__
3372 #define __FUNCT__ "MatGetRowMaxAbs"
3373 /*@
3374    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
3375         row of the matrix
3376 
3377    Collective on Mat and Vec
3378 
3379    Input Parameters:
3380 .  mat - the matrix
3381 
3382    Output Parameter:
3383 +  v - the vector for storing the maximums
3384 -  idx - the indices of the column found for each row (optional)
3385 
3386    Level: intermediate
3387 
3388    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
3389     row is 0 (the first column).
3390 
3391     This code is only implemented for a couple of matrix formats.
3392 
3393    Concepts: matrices^getting row maximums
3394 
3395 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3396 @*/
3397 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
3398 {
3399   PetscErrorCode ierr;
3400 
3401   PetscFunctionBegin;
3402   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3403   PetscValidType(mat,1);
3404   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3405   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3406   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3407   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3408 
3409   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
3410   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3411   PetscFunctionReturn(0);
3412 }
3413 
3414 #undef __FUNCT__
3415 #define __FUNCT__ "MatGetRowSum"
3416 /*@
3417    MatGetRowSum - Gets the sum of each row of the matrix
3418 
3419    Collective on Mat and Vec
3420 
3421    Input Parameters:
3422 .  mat - the matrix
3423 
3424    Output Parameter:
3425 .  v - the vector for storing the maximums
3426 
3427    Level: intermediate
3428 
3429    Notes: This code is slow since it is not currently specialized for different formats
3430 
3431    Concepts: matrices^getting row sums
3432 
3433 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3434 @*/
3435 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowSum(Mat mat, Vec v)
3436 {
3437   PetscInt       start, end, row;
3438   PetscScalar   *array;
3439   PetscErrorCode ierr;
3440 
3441   PetscFunctionBegin;
3442   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3443   PetscValidType(mat,1);
3444   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3445   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3446   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3447   ierr = MatGetOwnershipRange(mat, &start, &end);CHKERRQ(ierr);
3448   ierr = VecGetArray(v, &array);CHKERRQ(ierr);
3449   for(row = start; row < end; ++row) {
3450     PetscInt           ncols, col;
3451     const PetscInt    *cols;
3452     const PetscScalar *vals;
3453 
3454     array[row - start] = 0.0;
3455     ierr = MatGetRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr);
3456     for(col = 0; col < ncols; col++) {
3457       array[row - start] += vals[col];
3458     }
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__ "MatZeroRowsLocal"
4541 /*@C
4542    MatZeroRowsLocal - 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 MatZeroRowsLocal(), 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()
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 
5229     Output Parameters:
5230 +   n - number of rows in the (possibly compressed) matrix
5231 .   ia - the row pointers
5232 .   ja - the column indices
5233 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
5234            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
5235 
5236     Level: developer
5237 
5238     Notes: You CANNOT change any of the ia[] or ja[] values.
5239 
5240            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
5241 
5242 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
5243 @*/
5244 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5245 {
5246   PetscErrorCode ierr;
5247 
5248   PetscFunctionBegin;
5249   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5250   PetscValidType(mat,1);
5251   PetscValidIntPointer(n,4);
5252   if (ia) PetscValidIntPointer(ia,5);
5253   if (ja) PetscValidIntPointer(ja,6);
5254   PetscValidIntPointer(done,7);
5255   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5256   if (!mat->ops->getrowij) *done = PETSC_FALSE;
5257   else {
5258     *done = PETSC_TRUE;
5259     ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
5260     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
5261     ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
5262   }
5263   PetscFunctionReturn(0);
5264 }
5265 
5266 #undef __FUNCT__
5267 #define __FUNCT__ "MatGetColumnIJ"
5268 /*@C
5269     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
5270 
5271     Collective on Mat
5272 
5273     Input Parameters:
5274 +   mat - the matrix
5275 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5276 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5277                 symmetrized
5278 
5279     Output Parameters:
5280 +   n - number of columns in the (possibly compressed) matrix
5281 .   ia - the column pointers
5282 .   ja - the row indices
5283 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
5284 
5285     Level: developer
5286 
5287 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5288 @*/
5289 PetscErrorCode PETSCMAT_DLLEXPORT MatGetColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5290 {
5291   PetscErrorCode ierr;
5292 
5293   PetscFunctionBegin;
5294   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5295   PetscValidType(mat,1);
5296   PetscValidIntPointer(n,4);
5297   if (ia) PetscValidIntPointer(ia,5);
5298   if (ja) PetscValidIntPointer(ja,6);
5299   PetscValidIntPointer(done,7);
5300   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5301   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
5302   else {
5303     *done = PETSC_TRUE;
5304     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
5305   }
5306   PetscFunctionReturn(0);
5307 }
5308 
5309 #undef __FUNCT__
5310 #define __FUNCT__ "MatRestoreRowIJ"
5311 /*@C
5312     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
5313     MatGetRowIJ().
5314 
5315     Collective on Mat
5316 
5317     Input Parameters:
5318 +   mat - the matrix
5319 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5320 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5321                 symmetrized
5322 
5323     Output Parameters:
5324 +   n - size of (possibly compressed) matrix
5325 .   ia - the row pointers
5326 .   ja - the column indices
5327 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5328 
5329     Level: developer
5330 
5331 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5332 @*/
5333 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5334 {
5335   PetscErrorCode ierr;
5336 
5337   PetscFunctionBegin;
5338   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5339   PetscValidType(mat,1);
5340   if (ia) PetscValidIntPointer(ia,5);
5341   if (ja) PetscValidIntPointer(ja,6);
5342   PetscValidIntPointer(done,7);
5343   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5344 
5345   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
5346   else {
5347     *done = PETSC_TRUE;
5348     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
5349   }
5350   PetscFunctionReturn(0);
5351 }
5352 
5353 #undef __FUNCT__
5354 #define __FUNCT__ "MatRestoreColumnIJ"
5355 /*@C
5356     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
5357     MatGetColumnIJ().
5358 
5359     Collective on Mat
5360 
5361     Input Parameters:
5362 +   mat - the matrix
5363 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5364 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5365                 symmetrized
5366 
5367     Output Parameters:
5368 +   n - size of (possibly compressed) matrix
5369 .   ia - the column pointers
5370 .   ja - the row indices
5371 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5372 
5373     Level: developer
5374 
5375 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
5376 @*/
5377 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5378 {
5379   PetscErrorCode ierr;
5380 
5381   PetscFunctionBegin;
5382   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5383   PetscValidType(mat,1);
5384   if (ia) PetscValidIntPointer(ia,5);
5385   if (ja) PetscValidIntPointer(ja,6);
5386   PetscValidIntPointer(done,7);
5387   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5388 
5389   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
5390   else {
5391     *done = PETSC_TRUE;
5392     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
5393   }
5394   PetscFunctionReturn(0);
5395 }
5396 
5397 #undef __FUNCT__
5398 #define __FUNCT__ "MatColoringPatch"
5399 /*@C
5400     MatColoringPatch -Used inside matrix coloring routines that
5401     use MatGetRowIJ() and/or MatGetColumnIJ().
5402 
5403     Collective on Mat
5404 
5405     Input Parameters:
5406 +   mat - the matrix
5407 .   ncolors - max color value
5408 .   n   - number of entries in colorarray
5409 -   colorarray - array indicating color for each column
5410 
5411     Output Parameters:
5412 .   iscoloring - coloring generated using colorarray information
5413 
5414     Level: developer
5415 
5416 .seealso: MatGetRowIJ(), MatGetColumnIJ()
5417 
5418 @*/
5419 PetscErrorCode PETSCMAT_DLLEXPORT MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
5420 {
5421   PetscErrorCode ierr;
5422 
5423   PetscFunctionBegin;
5424   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5425   PetscValidType(mat,1);
5426   PetscValidIntPointer(colorarray,4);
5427   PetscValidPointer(iscoloring,5);
5428   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5429 
5430   if (!mat->ops->coloringpatch){
5431     ierr = ISColoringCreate(mat->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
5432   } else {
5433     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
5434   }
5435   PetscFunctionReturn(0);
5436 }
5437 
5438 
5439 #undef __FUNCT__
5440 #define __FUNCT__ "MatSetUnfactored"
5441 /*@
5442    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
5443 
5444    Collective on Mat
5445 
5446    Input Parameter:
5447 .  mat - the factored matrix to be reset
5448 
5449    Notes:
5450    This routine should be used only with factored matrices formed by in-place
5451    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
5452    format).  This option can save memory, for example, when solving nonlinear
5453    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
5454    ILU(0) preconditioner.
5455 
5456    Note that one can specify in-place ILU(0) factorization by calling
5457 .vb
5458      PCType(pc,PCILU);
5459      PCFactorSeUseInPlace(pc);
5460 .ve
5461    or by using the options -pc_type ilu -pc_factor_in_place
5462 
5463    In-place factorization ILU(0) can also be used as a local
5464    solver for the blocks within the block Jacobi or additive Schwarz
5465    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
5466    of these preconditioners in the users manual for details on setting
5467    local solver options.
5468 
5469    Most users should employ the simplified KSP interface for linear solvers
5470    instead of working directly with matrix algebra routines such as this.
5471    See, e.g., KSPCreate().
5472 
5473    Level: developer
5474 
5475 .seealso: PCFactorSetUseInPlace()
5476 
5477    Concepts: matrices^unfactored
5478 
5479 @*/
5480 PetscErrorCode PETSCMAT_DLLEXPORT MatSetUnfactored(Mat mat)
5481 {
5482   PetscErrorCode ierr;
5483 
5484   PetscFunctionBegin;
5485   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5486   PetscValidType(mat,1);
5487   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5488   mat->factor = 0;
5489   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
5490   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
5491   PetscFunctionReturn(0);
5492 }
5493 
5494 /*MC
5495     MatGetArrayF90 - Accesses a matrix array from Fortran90.
5496 
5497     Synopsis:
5498     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
5499 
5500     Not collective
5501 
5502     Input Parameter:
5503 .   x - matrix
5504 
5505     Output Parameters:
5506 +   xx_v - the Fortran90 pointer to the array
5507 -   ierr - error code
5508 
5509     Example of Usage:
5510 .vb
5511       PetscScalar, pointer xx_v(:)
5512       ....
5513       call MatGetArrayF90(x,xx_v,ierr)
5514       a = xx_v(3)
5515       call MatRestoreArrayF90(x,xx_v,ierr)
5516 .ve
5517 
5518     Notes:
5519     Not yet supported for all F90 compilers
5520 
5521     Level: advanced
5522 
5523 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
5524 
5525     Concepts: matrices^accessing array
5526 
5527 M*/
5528 
5529 /*MC
5530     MatRestoreArrayF90 - Restores a matrix array that has been
5531     accessed with MatGetArrayF90().
5532 
5533     Synopsis:
5534     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
5535 
5536     Not collective
5537 
5538     Input Parameters:
5539 +   x - matrix
5540 -   xx_v - the Fortran90 pointer to the array
5541 
5542     Output Parameter:
5543 .   ierr - error code
5544 
5545     Example of Usage:
5546 .vb
5547        PetscScalar, pointer xx_v(:)
5548        ....
5549        call MatGetArrayF90(x,xx_v,ierr)
5550        a = xx_v(3)
5551        call MatRestoreArrayF90(x,xx_v,ierr)
5552 .ve
5553 
5554     Notes:
5555     Not yet supported for all F90 compilers
5556 
5557     Level: advanced
5558 
5559 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
5560 
5561 M*/
5562 
5563 
5564 #undef __FUNCT__
5565 #define __FUNCT__ "MatGetSubMatrix"
5566 /*@
5567     MatGetSubMatrix - Gets a single submatrix on the same number of processors
5568                       as the original matrix.
5569 
5570     Collective on Mat
5571 
5572     Input Parameters:
5573 +   mat - the original matrix
5574 .   isrow - rows this processor should obtain
5575 .   iscol - columns for all processors you wish to keep
5576 .   csize - number of columns "local" to this processor (does nothing for sequential
5577             matrices). This should match the result from VecGetLocalSize(x,...) if you
5578             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
5579 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
5580 
5581     Output Parameter:
5582 .   newmat - the new submatrix, of the same type as the old
5583 
5584     Level: advanced
5585 
5586     Notes: the iscol argument MUST be the same on each processor. You might be
5587     able to create the iscol argument with ISAllGather(). The rows is isrow will be
5588     sorted into the same order as the original matrix.
5589 
5590       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
5591    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
5592    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
5593    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
5594    you are finished using it.
5595 
5596     Concepts: matrices^submatrices
5597 
5598 .seealso: MatGetSubMatrices(), ISAllGather()
5599 @*/
5600 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrix(Mat mat,IS isrow,IS iscol,PetscInt csize,MatReuse cll,Mat *newmat)
5601 {
5602   PetscErrorCode ierr;
5603   PetscMPIInt    size;
5604   Mat            *local;
5605 
5606   PetscFunctionBegin;
5607   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5608   PetscValidHeaderSpecific(isrow,IS_COOKIE,2);
5609   PetscValidHeaderSpecific(iscol,IS_COOKIE,3);
5610   PetscValidPointer(newmat,6);
5611   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_COOKIE,6);
5612   PetscValidType(mat,1);
5613   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5614   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5615   ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr);
5616 
5617   /* if original matrix is on just one processor then use submatrix generated */
5618   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
5619     ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
5620     PetscFunctionReturn(0);
5621   } else if (!mat->ops->getsubmatrix && size == 1) {
5622     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
5623     *newmat = *local;
5624     ierr    = PetscFree(local);CHKERRQ(ierr);
5625     PetscFunctionReturn(0);
5626   }
5627 
5628   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5629   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscol,csize,cll,newmat);CHKERRQ(ierr);
5630   ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);
5631   PetscFunctionReturn(0);
5632 }
5633 
5634 #undef __FUNCT__
5635 #define __FUNCT__ "MatGetSubMatrixRaw"
5636 /*@
5637     MatGetSubMatrixRaw - Gets a single submatrix on the same number of processors
5638                          as the original matrix.
5639 
5640     Collective on Mat
5641 
5642     Input Parameters:
5643 +   mat - the original matrix
5644 .   nrows - the number of rows this processor should obtain
5645 .   rows - rows this processor should obtain
5646 .   ncols - the number of columns for all processors you wish to keep
5647 .   cols - columns for all processors you wish to keep
5648 .   csize - number of columns "local" to this processor (does nothing for sequential
5649             matrices). This should match the result from VecGetLocalSize(x,...) if you
5650             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
5651 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
5652 
5653     Output Parameter:
5654 .   newmat - the new submatrix, of the same type as the old
5655 
5656     Level: advanced
5657 
5658     Notes: the iscol argument MUST be the same on each processor. You might be
5659     able to create the iscol argument with ISAllGather().
5660 
5661       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
5662    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
5663    to this routine with a mat of the same nonzero structure and with a cll of MAT_REUSE_MATRIX
5664    will reuse the matrix generated the first time.
5665 
5666     Concepts: matrices^submatrices
5667 
5668 .seealso: MatGetSubMatrices(), ISAllGather()
5669 @*/
5670 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrixRaw(Mat mat,PetscInt nrows,const PetscInt rows[],PetscInt ncols,const PetscInt cols[],PetscInt csize,MatReuse cll,Mat *newmat)
5671 {
5672   IS             isrow, iscol;
5673   PetscErrorCode ierr;
5674 
5675   PetscFunctionBegin;
5676   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5677   PetscValidIntPointer(rows,2);
5678   PetscValidIntPointer(cols,3);
5679   PetscValidPointer(newmat,6);
5680   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_COOKIE,6);
5681   PetscValidType(mat,1);
5682   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5683   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5684   ierr = ISCreateGeneralWithArray(PETSC_COMM_SELF, nrows, (PetscInt *) rows, &isrow);CHKERRQ(ierr);
5685   ierr = ISCreateGeneralWithArray(PETSC_COMM_SELF, ncols, (PetscInt *) cols, &iscol);CHKERRQ(ierr);
5686   ierr = MatGetSubMatrix(mat, isrow, iscol, csize, cll, newmat);CHKERRQ(ierr);
5687   ierr = ISDestroy(isrow);CHKERRQ(ierr);
5688   ierr = ISDestroy(iscol);CHKERRQ(ierr);
5689   PetscFunctionReturn(0);
5690 }
5691 
5692 #undef __FUNCT__
5693 #define __FUNCT__ "MatStashSetInitialSize"
5694 /*@
5695    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
5696    used during the assembly process to store values that belong to
5697    other processors.
5698 
5699    Not Collective
5700 
5701    Input Parameters:
5702 +  mat   - the matrix
5703 .  size  - the initial size of the stash.
5704 -  bsize - the initial size of the block-stash(if used).
5705 
5706    Options Database Keys:
5707 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
5708 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
5709 
5710    Level: intermediate
5711 
5712    Notes:
5713      The block-stash is used for values set with MatSetValuesBlocked() while
5714      the stash is used for values set with MatSetValues()
5715 
5716      Run with the option -info and look for output of the form
5717      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
5718      to determine the appropriate value, MM, to use for size and
5719      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
5720      to determine the value, BMM to use for bsize
5721 
5722    Concepts: stash^setting matrix size
5723    Concepts: matrices^stash
5724 
5725 @*/
5726 PetscErrorCode PETSCMAT_DLLEXPORT MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
5727 {
5728   PetscErrorCode ierr;
5729 
5730   PetscFunctionBegin;
5731   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5732   PetscValidType(mat,1);
5733   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
5734   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
5735   PetscFunctionReturn(0);
5736 }
5737 
5738 #undef __FUNCT__
5739 #define __FUNCT__ "MatInterpolateAdd"
5740 /*@
5741    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
5742      the matrix
5743 
5744    Collective on Mat
5745 
5746    Input Parameters:
5747 +  mat   - the matrix
5748 .  x,y - the vectors
5749 -  w - where the result is stored
5750 
5751    Level: intermediate
5752 
5753    Notes:
5754     w may be the same vector as y.
5755 
5756     This allows one to use either the restriction or interpolation (its transpose)
5757     matrix to do the interpolation
5758 
5759     Concepts: interpolation
5760 
5761 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
5762 
5763 @*/
5764 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
5765 {
5766   PetscErrorCode ierr;
5767   PetscInt       M,N;
5768 
5769   PetscFunctionBegin;
5770   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5771   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
5772   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
5773   PetscValidHeaderSpecific(w,VEC_COOKIE,4);
5774   PetscValidType(A,1);
5775   ierr = MatPreallocated(A);CHKERRQ(ierr);
5776   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
5777   if (N > M) {
5778     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
5779   } else {
5780     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
5781   }
5782   PetscFunctionReturn(0);
5783 }
5784 
5785 #undef __FUNCT__
5786 #define __FUNCT__ "MatInterpolate"
5787 /*@
5788    MatInterpolate - y = A*x or A'*x depending on the shape of
5789      the matrix
5790 
5791    Collective on Mat
5792 
5793    Input Parameters:
5794 +  mat   - the matrix
5795 -  x,y - the vectors
5796 
5797    Level: intermediate
5798 
5799    Notes:
5800     This allows one to use either the restriction or interpolation (its transpose)
5801     matrix to do the interpolation
5802 
5803    Concepts: matrices^interpolation
5804 
5805 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
5806 
5807 @*/
5808 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolate(Mat A,Vec x,Vec y)
5809 {
5810   PetscErrorCode ierr;
5811   PetscInt       M,N;
5812 
5813   PetscFunctionBegin;
5814   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5815   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
5816   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
5817   PetscValidType(A,1);
5818   ierr = MatPreallocated(A);CHKERRQ(ierr);
5819   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
5820   if (N > M) {
5821     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
5822   } else {
5823     ierr = MatMult(A,x,y);CHKERRQ(ierr);
5824   }
5825   PetscFunctionReturn(0);
5826 }
5827 
5828 #undef __FUNCT__
5829 #define __FUNCT__ "MatRestrict"
5830 /*@
5831    MatRestrict - y = A*x or A'*x
5832 
5833    Collective on Mat
5834 
5835    Input Parameters:
5836 +  mat   - the matrix
5837 -  x,y - the vectors
5838 
5839    Level: intermediate
5840 
5841    Notes:
5842     This allows one to use either the restriction or interpolation (its transpose)
5843     matrix to do the restriction
5844 
5845    Concepts: matrices^restriction
5846 
5847 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
5848 
5849 @*/
5850 PetscErrorCode PETSCMAT_DLLEXPORT MatRestrict(Mat A,Vec x,Vec y)
5851 {
5852   PetscErrorCode ierr;
5853   PetscInt       M,N;
5854 
5855   PetscFunctionBegin;
5856   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5857   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
5858   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
5859   PetscValidType(A,1);
5860   ierr = MatPreallocated(A);CHKERRQ(ierr);
5861 
5862   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
5863   if (N > M) {
5864     ierr = MatMult(A,x,y);CHKERRQ(ierr);
5865   } else {
5866     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
5867   }
5868   PetscFunctionReturn(0);
5869 }
5870 
5871 #undef __FUNCT__
5872 #define __FUNCT__ "MatNullSpaceAttach"
5873 /*@C
5874    MatNullSpaceAttach - attaches a null space to a matrix.
5875         This null space will be removed from the resulting vector whenever
5876         MatMult() is called
5877 
5878    Collective on Mat
5879 
5880    Input Parameters:
5881 +  mat - the matrix
5882 -  nullsp - the null space object
5883 
5884    Level: developer
5885 
5886    Notes:
5887       Overwrites any previous null space that may have been attached
5888 
5889    Concepts: null space^attaching to matrix
5890 
5891 .seealso: MatCreate(), MatNullSpaceCreate()
5892 @*/
5893 PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
5894 {
5895   PetscErrorCode ierr;
5896 
5897   PetscFunctionBegin;
5898   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5899   PetscValidType(mat,1);
5900   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_COOKIE,2);
5901   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5902   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
5903   if (mat->nullsp) { ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr); }
5904   mat->nullsp = nullsp;
5905   PetscFunctionReturn(0);
5906 }
5907 
5908 #undef __FUNCT__
5909 #define __FUNCT__ "MatICCFactor"
5910 /*@
5911    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
5912 
5913    Collective on Mat
5914 
5915    Input Parameters:
5916 +  mat - the matrix
5917 .  row - row/column permutation
5918 .  fill - expected fill factor >= 1.0
5919 -  level - level of fill, for ICC(k)
5920 
5921    Notes:
5922    Probably really in-place only when level of fill is zero, otherwise allocates
5923    new space to store factored matrix and deletes previous memory.
5924 
5925    Most users should employ the simplified KSP interface for linear solvers
5926    instead of working directly with matrix algebra routines such as this.
5927    See, e.g., KSPCreate().
5928 
5929    Level: developer
5930 
5931    Concepts: matrices^incomplete Cholesky factorization
5932    Concepts: Cholesky factorization
5933 
5934 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5935 @*/
5936 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactor(Mat mat,IS row,MatFactorInfo* info)
5937 {
5938   PetscErrorCode ierr;
5939 
5940   PetscFunctionBegin;
5941   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5942   PetscValidType(mat,1);
5943   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
5944   PetscValidPointer(info,3);
5945   if (mat->rmap.N != mat->cmap.N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
5946   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5947   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5948   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5949   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5950   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
5951   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5952   PetscFunctionReturn(0);
5953 }
5954 
5955 #undef __FUNCT__
5956 #define __FUNCT__ "MatSetValuesAdic"
5957 /*@
5958    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
5959 
5960    Not Collective
5961 
5962    Input Parameters:
5963 +  mat - the matrix
5964 -  v - the values compute with ADIC
5965 
5966    Level: developer
5967 
5968    Notes:
5969      Must call MatSetColoring() before using this routine. Also this matrix must already
5970      have its nonzero pattern determined.
5971 
5972 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5973           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
5974 @*/
5975 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdic(Mat mat,void *v)
5976 {
5977   PetscErrorCode ierr;
5978 
5979   PetscFunctionBegin;
5980   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5981   PetscValidType(mat,1);
5982   PetscValidPointer(mat,2);
5983 
5984   if (!mat->assembled) {
5985     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
5986   }
5987   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5988   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5989   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
5990   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5991   ierr = MatView_Private(mat);CHKERRQ(ierr);
5992   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5993   PetscFunctionReturn(0);
5994 }
5995 
5996 
5997 #undef __FUNCT__
5998 #define __FUNCT__ "MatSetColoring"
5999 /*@
6000    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
6001 
6002    Not Collective
6003 
6004    Input Parameters:
6005 +  mat - the matrix
6006 -  coloring - the coloring
6007 
6008    Level: developer
6009 
6010 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6011           MatSetValues(), MatSetValuesAdic()
6012 @*/
6013 PetscErrorCode PETSCMAT_DLLEXPORT MatSetColoring(Mat mat,ISColoring coloring)
6014 {
6015   PetscErrorCode ierr;
6016 
6017   PetscFunctionBegin;
6018   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6019   PetscValidType(mat,1);
6020   PetscValidPointer(coloring,2);
6021 
6022   if (!mat->assembled) {
6023     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6024   }
6025   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
6026   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
6027   PetscFunctionReturn(0);
6028 }
6029 
6030 #undef __FUNCT__
6031 #define __FUNCT__ "MatSetValuesAdifor"
6032 /*@
6033    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
6034 
6035    Not Collective
6036 
6037    Input Parameters:
6038 +  mat - the matrix
6039 .  nl - leading dimension of v
6040 -  v - the values compute with ADIFOR
6041 
6042    Level: developer
6043 
6044    Notes:
6045      Must call MatSetColoring() before using this routine. Also this matrix must already
6046      have its nonzero pattern determined.
6047 
6048 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6049           MatSetValues(), MatSetColoring()
6050 @*/
6051 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
6052 {
6053   PetscErrorCode ierr;
6054 
6055   PetscFunctionBegin;
6056   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6057   PetscValidType(mat,1);
6058   PetscValidPointer(v,3);
6059 
6060   if (!mat->assembled) {
6061     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6062   }
6063   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6064   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
6065   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
6066   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6067   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6068   PetscFunctionReturn(0);
6069 }
6070 
6071 #undef __FUNCT__
6072 #define __FUNCT__ "MatDiagonalScaleLocal"
6073 /*@
6074    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
6075          ghosted ones.
6076 
6077    Not Collective
6078 
6079    Input Parameters:
6080 +  mat - the matrix
6081 -  diag = the diagonal values, including ghost ones
6082 
6083    Level: developer
6084 
6085    Notes: Works only for MPIAIJ and MPIBAIJ matrices
6086 
6087 .seealso: MatDiagonalScale()
6088 @*/
6089 PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalScaleLocal(Mat mat,Vec diag)
6090 {
6091   PetscErrorCode ierr;
6092   PetscMPIInt    size;
6093 
6094   PetscFunctionBegin;
6095   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6096   PetscValidHeaderSpecific(diag,VEC_COOKIE,2);
6097   PetscValidType(mat,1);
6098 
6099   if (!mat->assembled) {
6100     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6101   }
6102   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
6103   ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr);
6104   if (size == 1) {
6105     PetscInt n,m;
6106     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
6107     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
6108     if (m == n) {
6109       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
6110     } else {
6111       SETERRQ(PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
6112     }
6113   } else {
6114     PetscErrorCode (*f)(Mat,Vec);
6115     ierr = PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);CHKERRQ(ierr);
6116     if (f) {
6117       ierr = (*f)(mat,diag);CHKERRQ(ierr);
6118     } else {
6119       SETERRQ(PETSC_ERR_SUP,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
6120     }
6121   }
6122   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
6123   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6124   PetscFunctionReturn(0);
6125 }
6126 
6127 #undef __FUNCT__
6128 #define __FUNCT__ "MatGetInertia"
6129 /*@
6130    MatGetInertia - Gets the inertia from a factored matrix
6131 
6132    Collective on Mat
6133 
6134    Input Parameter:
6135 .  mat - the matrix
6136 
6137    Output Parameters:
6138 +   nneg - number of negative eigenvalues
6139 .   nzero - number of zero eigenvalues
6140 -   npos - number of positive eigenvalues
6141 
6142    Level: advanced
6143 
6144    Notes: Matrix must have been factored by MatCholeskyFactor()
6145 
6146 
6147 @*/
6148 PetscErrorCode PETSCMAT_DLLEXPORT MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
6149 {
6150   PetscErrorCode ierr;
6151 
6152   PetscFunctionBegin;
6153   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6154   PetscValidType(mat,1);
6155   if (!mat->factor)    SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6156   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
6157   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
6158   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
6159   PetscFunctionReturn(0);
6160 }
6161 
6162 /* ----------------------------------------------------------------*/
6163 #undef __FUNCT__
6164 #define __FUNCT__ "MatSolves"
6165 /*@
6166    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
6167 
6168    Collective on Mat and Vecs
6169 
6170    Input Parameters:
6171 +  mat - the factored matrix
6172 -  b - the right-hand-side vectors
6173 
6174    Output Parameter:
6175 .  x - the result vectors
6176 
6177    Notes:
6178    The vectors b and x cannot be the same.  I.e., one cannot
6179    call MatSolves(A,x,x).
6180 
6181    Notes:
6182    Most users should employ the simplified KSP interface for linear solvers
6183    instead of working directly with matrix algebra routines such as this.
6184    See, e.g., KSPCreate().
6185 
6186    Level: developer
6187 
6188    Concepts: matrices^triangular solves
6189 
6190 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
6191 @*/
6192 PetscErrorCode PETSCMAT_DLLEXPORT MatSolves(Mat mat,Vecs b,Vecs x)
6193 {
6194   PetscErrorCode ierr;
6195 
6196   PetscFunctionBegin;
6197   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6198   PetscValidType(mat,1);
6199   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
6200   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6201   if (!mat->rmap.N && !mat->cmap.N) PetscFunctionReturn(0);
6202 
6203   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
6204   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6205   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
6206   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
6207   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
6208   PetscFunctionReturn(0);
6209 }
6210 
6211 #undef __FUNCT__
6212 #define __FUNCT__ "MatIsSymmetric"
6213 /*@
6214    MatIsSymmetric - Test whether a matrix is symmetric
6215 
6216    Collective on Mat
6217 
6218    Input Parameter:
6219 +  A - the matrix to test
6220 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
6221 
6222    Output Parameters:
6223 .  flg - the result
6224 
6225    Level: intermediate
6226 
6227    Concepts: matrix^symmetry
6228 
6229 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6230 @*/
6231 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetric(Mat A,PetscReal tol,PetscTruth *flg)
6232 {
6233   PetscErrorCode ierr;
6234 
6235   PetscFunctionBegin;
6236   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6237   PetscValidPointer(flg,2);
6238   if (!A->symmetric_set) {
6239     if (!A->ops->issymmetric) {
6240       MatType mattype;
6241       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
6242       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
6243     }
6244     ierr = (*A->ops->issymmetric)(A,tol,&A->symmetric);CHKERRQ(ierr);
6245     A->symmetric_set = PETSC_TRUE;
6246     if (A->symmetric) {
6247       A->structurally_symmetric_set = PETSC_TRUE;
6248       A->structurally_symmetric     = PETSC_TRUE;
6249     }
6250   }
6251   *flg = A->symmetric;
6252   PetscFunctionReturn(0);
6253 }
6254 
6255 #undef __FUNCT__
6256 #define __FUNCT__ "MatIsSymmetricKnown"
6257 /*@
6258    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
6259 
6260    Collective on Mat
6261 
6262    Input Parameter:
6263 .  A - the matrix to check
6264 
6265    Output Parameters:
6266 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
6267 -  flg - the result
6268 
6269    Level: advanced
6270 
6271    Concepts: matrix^symmetry
6272 
6273    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
6274          if you want it explicitly checked
6275 
6276 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6277 @*/
6278 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetricKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6279 {
6280   PetscFunctionBegin;
6281   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6282   PetscValidPointer(set,2);
6283   PetscValidPointer(flg,3);
6284   if (A->symmetric_set) {
6285     *set = PETSC_TRUE;
6286     *flg = A->symmetric;
6287   } else {
6288     *set = PETSC_FALSE;
6289   }
6290   PetscFunctionReturn(0);
6291 }
6292 
6293 #undef __FUNCT__
6294 #define __FUNCT__ "MatIsHermitianKnown"
6295 /*@
6296    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
6297 
6298    Collective on Mat
6299 
6300    Input Parameter:
6301 .  A - the matrix to check
6302 
6303    Output Parameters:
6304 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
6305 -  flg - the result
6306 
6307    Level: advanced
6308 
6309    Concepts: matrix^symmetry
6310 
6311    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
6312          if you want it explicitly checked
6313 
6314 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6315 @*/
6316 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitianKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6317 {
6318   PetscFunctionBegin;
6319   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6320   PetscValidPointer(set,2);
6321   PetscValidPointer(flg,3);
6322   if (A->hermitian_set) {
6323     *set = PETSC_TRUE;
6324     *flg = A->hermitian;
6325   } else {
6326     *set = PETSC_FALSE;
6327   }
6328   PetscFunctionReturn(0);
6329 }
6330 
6331 #undef __FUNCT__
6332 #define __FUNCT__ "MatIsStructurallySymmetric"
6333 /*@
6334    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
6335 
6336    Collective on Mat
6337 
6338    Input Parameter:
6339 .  A - the matrix to test
6340 
6341    Output Parameters:
6342 .  flg - the result
6343 
6344    Level: intermediate
6345 
6346    Concepts: matrix^symmetry
6347 
6348 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
6349 @*/
6350 PetscErrorCode PETSCMAT_DLLEXPORT MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
6351 {
6352   PetscErrorCode ierr;
6353 
6354   PetscFunctionBegin;
6355   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6356   PetscValidPointer(flg,2);
6357   if (!A->structurally_symmetric_set) {
6358     if (!A->ops->isstructurallysymmetric) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
6359     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
6360     A->structurally_symmetric_set = PETSC_TRUE;
6361   }
6362   *flg = A->structurally_symmetric;
6363   PetscFunctionReturn(0);
6364 }
6365 
6366 #undef __FUNCT__
6367 #define __FUNCT__ "MatIsHermitian"
6368 /*@
6369    MatIsHermitian - Test whether a matrix is Hermitian, i.e. it is the complex conjugate of its transpose.
6370 
6371    Collective on Mat
6372 
6373    Input Parameter:
6374 .  A - the matrix to test
6375 
6376    Output Parameters:
6377 .  flg - the result
6378 
6379    Level: intermediate
6380 
6381    Concepts: matrix^symmetry
6382 
6383 .seealso: MatTranspose(), MatIsTranspose(), MatIsSymmetric(), MatIsStructurallySymmetric(), MatSetOption()
6384 @*/
6385 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitian(Mat A,PetscTruth *flg)
6386 {
6387   PetscErrorCode ierr;
6388 
6389   PetscFunctionBegin;
6390   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6391   PetscValidPointer(flg,2);
6392   if (!A->hermitian_set) {
6393     if (!A->ops->ishermitian) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for being Hermitian");
6394     ierr = (*A->ops->ishermitian)(A,&A->hermitian);CHKERRQ(ierr);
6395     A->hermitian_set = PETSC_TRUE;
6396     if (A->hermitian) {
6397       A->structurally_symmetric_set = PETSC_TRUE;
6398       A->structurally_symmetric     = PETSC_TRUE;
6399     }
6400   }
6401   *flg = A->hermitian;
6402   PetscFunctionReturn(0);
6403 }
6404 
6405 #undef __FUNCT__
6406 #define __FUNCT__ "MatStashGetInfo"
6407 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
6408 /*@
6409    MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
6410        to be communicated to other processors during the MatAssemblyBegin/End() process
6411 
6412     Not collective
6413 
6414    Input Parameter:
6415 .   vec - the vector
6416 
6417    Output Parameters:
6418 +   nstash   - the size of the stash
6419 .   reallocs - the number of additional mallocs incurred.
6420 .   bnstash   - the size of the block stash
6421 -   breallocs - the number of additional mallocs incurred.in the block stash
6422 
6423    Level: advanced
6424 
6425 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
6426 
6427 @*/
6428 PetscErrorCode PETSCMAT_DLLEXPORT MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
6429 {
6430   PetscErrorCode ierr;
6431   PetscFunctionBegin;
6432   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
6433   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
6434   PetscFunctionReturn(0);
6435 }
6436 
6437 #undef __FUNCT__
6438 #define __FUNCT__ "MatGetVecs"
6439 /*@
6440    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
6441      parallel layout
6442 
6443    Collective on Mat
6444 
6445    Input Parameter:
6446 .  mat - the matrix
6447 
6448    Output Parameter:
6449 +   right - (optional) vector that the matrix can be multiplied against
6450 -   left - (optional) vector that the matrix vector product can be stored in
6451 
6452   Level: advanced
6453 
6454 .seealso: MatCreate()
6455 @*/
6456 PetscErrorCode PETSCMAT_DLLEXPORT MatGetVecs(Mat mat,Vec *right,Vec *left)
6457 {
6458   PetscErrorCode ierr;
6459 
6460   PetscFunctionBegin;
6461   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6462   PetscValidType(mat,1);
6463   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6464   if (mat->ops->getvecs) {
6465     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
6466   } else {
6467     PetscMPIInt size;
6468     ierr = MPI_Comm_size(mat->comm, &size);CHKERRQ(ierr);
6469     if (right) {
6470       ierr = VecCreate(mat->comm,right);CHKERRQ(ierr);
6471       ierr = VecSetSizes(*right,mat->cmap.n,PETSC_DETERMINE);CHKERRQ(ierr);
6472       if (size > 1) {ierr = VecSetType(*right,VECMPI);CHKERRQ(ierr);}
6473       else {ierr = VecSetType(*right,VECSEQ);CHKERRQ(ierr);}
6474     }
6475     if (left) {
6476       ierr = VecCreate(mat->comm,left);CHKERRQ(ierr);
6477       ierr = VecSetSizes(*left,mat->rmap.n,PETSC_DETERMINE);CHKERRQ(ierr);
6478       if (size > 1) {ierr = VecSetType(*left,VECMPI);CHKERRQ(ierr);}
6479       else {ierr = VecSetType(*left,VECSEQ);CHKERRQ(ierr);}
6480     }
6481   }
6482   if (right) {ierr = VecSetBlockSize(*right,mat->rmap.bs);CHKERRQ(ierr);}
6483   if (left) {ierr = VecSetBlockSize(*left,mat->rmap.bs);CHKERRQ(ierr);}
6484   if (mat->mapping) {
6485     if (right) {ierr = VecSetLocalToGlobalMapping(*right,mat->mapping);CHKERRQ(ierr);}
6486     if (left) {ierr = VecSetLocalToGlobalMapping(*left,mat->mapping);CHKERRQ(ierr);}
6487   }
6488   if (mat->bmapping) {
6489     if (right) {ierr = VecSetLocalToGlobalMappingBlock(*right,mat->bmapping);CHKERRQ(ierr);}
6490     if (left) {ierr = VecSetLocalToGlobalMappingBlock(*left,mat->bmapping);CHKERRQ(ierr);}
6491   }
6492   PetscFunctionReturn(0);
6493 }
6494 
6495 #undef __FUNCT__
6496 #define __FUNCT__ "MatFactorInfoInitialize"
6497 /*@
6498    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
6499      with default values.
6500 
6501    Not Collective
6502 
6503    Input Parameters:
6504 .    info - the MatFactorInfo data structure
6505 
6506 
6507    Notes: The solvers are generally used through the KSP and PC objects, for example
6508           PCLU, PCILU, PCCHOLESKY, PCICC
6509 
6510    Level: developer
6511 
6512 .seealso: MatFactorInfo
6513 @*/
6514 
6515 PetscErrorCode PETSCMAT_DLLEXPORT MatFactorInfoInitialize(MatFactorInfo *info)
6516 {
6517   PetscErrorCode ierr;
6518 
6519   PetscFunctionBegin;
6520   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
6521   PetscFunctionReturn(0);
6522 }
6523 
6524 #undef __FUNCT__
6525 #define __FUNCT__ "MatPtAP"
6526 /*@
6527    MatPtAP - Creates the matrix projection C = P^T * A * P
6528 
6529    Collective on Mat
6530 
6531    Input Parameters:
6532 +  A - the matrix
6533 .  P - the projection matrix
6534 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6535 -  fill - expected fill as ratio of nnz(C)/nnz(A)
6536 
6537    Output Parameters:
6538 .  C - the product matrix
6539 
6540    Notes:
6541    C will be created and must be destroyed by the user with MatDestroy().
6542 
6543    This routine is currently only implemented for pairs of AIJ matrices and classes
6544    which inherit from AIJ.
6545 
6546    Level: intermediate
6547 
6548 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
6549 @*/
6550 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
6551 {
6552   PetscErrorCode ierr;
6553 
6554   PetscFunctionBegin;
6555   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6556   PetscValidType(A,1);
6557   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6558   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6559   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
6560   PetscValidType(P,2);
6561   MatPreallocated(P);
6562   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6563   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6564   PetscValidPointer(C,3);
6565   if (P->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap.N,A->cmap.N);
6566   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
6567   ierr = MatPreallocated(A);CHKERRQ(ierr);
6568 
6569   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
6570   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
6571   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
6572 
6573   PetscFunctionReturn(0);
6574 }
6575 
6576 #undef __FUNCT__
6577 #define __FUNCT__ "MatPtAPNumeric"
6578 /*@
6579    MatPtAPNumeric - Computes the matrix projection C = P^T * A * P
6580 
6581    Collective on Mat
6582 
6583    Input Parameters:
6584 +  A - the matrix
6585 -  P - the projection matrix
6586 
6587    Output Parameters:
6588 .  C - the product matrix
6589 
6590    Notes:
6591    C must have been created by calling MatPtAPSymbolic and must be destroyed by
6592    the user using MatDeatroy().
6593 
6594    This routine is currently only implemented for pairs of AIJ matrices and classes
6595    which inherit from AIJ.  C will be of type MATAIJ.
6596 
6597    Level: intermediate
6598 
6599 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
6600 @*/
6601 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPNumeric(Mat A,Mat P,Mat C)
6602 {
6603   PetscErrorCode ierr;
6604 
6605   PetscFunctionBegin;
6606   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6607   PetscValidType(A,1);
6608   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6609   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6610   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
6611   PetscValidType(P,2);
6612   MatPreallocated(P);
6613   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6614   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6615   PetscValidHeaderSpecific(C,MAT_COOKIE,3);
6616   PetscValidType(C,3);
6617   MatPreallocated(C);
6618   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6619   if (P->cmap.N!=C->rmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap.N,C->rmap.N);
6620   if (P->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap.N,A->cmap.N);
6621   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);
6622   if (P->cmap.N!=C->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap.N,C->cmap.N);
6623   ierr = MatPreallocated(A);CHKERRQ(ierr);
6624 
6625   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
6626   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
6627   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
6628   PetscFunctionReturn(0);
6629 }
6630 
6631 #undef __FUNCT__
6632 #define __FUNCT__ "MatPtAPSymbolic"
6633 /*@
6634    MatPtAPSymbolic - Creates the (i,j) structure of the matrix projection C = P^T * A * P
6635 
6636    Collective on Mat
6637 
6638    Input Parameters:
6639 +  A - the matrix
6640 -  P - the projection matrix
6641 
6642    Output Parameters:
6643 .  C - the (i,j) structure of the product matrix
6644 
6645    Notes:
6646    C will be created and must be destroyed by the user with MatDestroy().
6647 
6648    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
6649    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
6650    this (i,j) structure by calling MatPtAPNumeric().
6651 
6652    Level: intermediate
6653 
6654 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
6655 @*/
6656 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
6657 {
6658   PetscErrorCode ierr;
6659 
6660   PetscFunctionBegin;
6661   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6662   PetscValidType(A,1);
6663   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6664   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6665   if (fill <1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
6666   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
6667   PetscValidType(P,2);
6668   MatPreallocated(P);
6669   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6670   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6671   PetscValidPointer(C,3);
6672 
6673   if (P->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap.N,A->cmap.N);
6674   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);
6675   ierr = MatPreallocated(A);CHKERRQ(ierr);
6676   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
6677   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
6678   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
6679 
6680   ierr = MatSetBlockSize(*C,A->rmap.bs);CHKERRQ(ierr);
6681 
6682   PetscFunctionReturn(0);
6683 }
6684 
6685 #undef __FUNCT__
6686 #define __FUNCT__ "MatMatMult"
6687 /*@
6688    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
6689 
6690    Collective on Mat
6691 
6692    Input Parameters:
6693 +  A - the left matrix
6694 .  B - the right matrix
6695 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6696 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B))
6697 
6698    Output Parameters:
6699 .  C - the product matrix
6700 
6701    Notes:
6702    C will be created and must be destroyed by the user with MatDestroy().
6703    Unless scall is MAT_REUSE_MATRIX
6704 
6705    If you have many matrices with the same non-zero structure to multiply, you
6706    should either
6707 $   1) use MAT_REUSE_MATRIX in all calls but the first or
6708 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
6709 
6710    Level: intermediate
6711 
6712 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
6713 @*/
6714 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
6715 {
6716   PetscErrorCode ierr;
6717   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
6718   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
6719   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
6720 
6721   PetscFunctionBegin;
6722   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6723   PetscValidType(A,1);
6724   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6725   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6726   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
6727   PetscValidType(B,2);
6728   MatPreallocated(B);
6729   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6730   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6731   PetscValidPointer(C,3);
6732   if (B->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->cmap.N);
6733   if (fill == PETSC_DEFAULT) fill = 2.0;
6734   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
6735   ierr = MatPreallocated(A);CHKERRQ(ierr);
6736 
6737   fA = A->ops->matmult;
6738   fB = B->ops->matmult;
6739   if (fB == fA) {
6740     if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",B->type_name);
6741     mult = fB;
6742   } else {
6743     /* dispatch based on the type of A and B */
6744     char  multname[256];
6745     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
6746     ierr = PetscStrcat(multname,A->type_name);CHKERRQ(ierr);
6747     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
6748     ierr = PetscStrcat(multname,B->type_name);CHKERRQ(ierr);
6749     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_aij_dense_C" */
6750     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
6751     if (!mult) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",A->type_name,B->type_name);
6752   }
6753   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
6754   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
6755   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
6756   PetscFunctionReturn(0);
6757 }
6758 
6759 #undef __FUNCT__
6760 #define __FUNCT__ "MatMatMultSymbolic"
6761 /*@
6762    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
6763    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
6764 
6765    Collective on Mat
6766 
6767    Input Parameters:
6768 +  A - the left matrix
6769 .  B - the right matrix
6770 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B))
6771 
6772    Output Parameters:
6773 .  C - the matrix containing the ij structure of product matrix
6774 
6775    Notes:
6776    C will be created and must be destroyed by the user with MatDestroy().
6777 
6778    This routine is currently implemented for
6779     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
6780     - pairs of AIJ (A) and Dense (B) matrix, C will be of type MATDENSE.
6781 
6782    Level: intermediate
6783 
6784 .seealso: MatMatMult(), MatMatMultNumeric()
6785 @*/
6786 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
6787 {
6788   PetscErrorCode ierr;
6789   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
6790   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
6791   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
6792 
6793   PetscFunctionBegin;
6794   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6795   PetscValidType(A,1);
6796   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6797   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6798 
6799   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
6800   PetscValidType(B,2);
6801   MatPreallocated(B);
6802   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6803   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6804   PetscValidPointer(C,3);
6805 
6806   if (B->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->cmap.N);
6807   if (fill == PETSC_DEFAULT) fill = 2.0;
6808   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
6809   ierr = MatPreallocated(A);CHKERRQ(ierr);
6810 
6811   Asymbolic = A->ops->matmultsymbolic;
6812   Bsymbolic = B->ops->matmultsymbolic;
6813   if (Asymbolic == Bsymbolic){
6814     if (!Bsymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",B->type_name);
6815     symbolic = Bsymbolic;
6816   } else { /* dispatch based on the type of A and B */
6817     char  symbolicname[256];
6818     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
6819     ierr = PetscStrcat(symbolicname,A->type_name);CHKERRQ(ierr);
6820     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
6821     ierr = PetscStrcat(symbolicname,B->type_name);CHKERRQ(ierr);
6822     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
6823     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
6824     if (!symbolic) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",A->type_name,B->type_name);
6825   }
6826   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
6827   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
6828   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
6829   PetscFunctionReturn(0);
6830 }
6831 
6832 #undef __FUNCT__
6833 #define __FUNCT__ "MatMatMultNumeric"
6834 /*@
6835    MatMatMultNumeric - Performs the numeric matrix-matrix product.
6836    Call this routine after first calling MatMatMultSymbolic().
6837 
6838    Collective on Mat
6839 
6840    Input Parameters:
6841 +  A - the left matrix
6842 -  B - the right matrix
6843 
6844    Output Parameters:
6845 .  C - the product matrix, whose ij structure was defined from MatMatMultSymbolic().
6846 
6847    Notes:
6848    C must have been created with MatMatMultSymbolic.
6849 
6850    This routine is currently implemented for
6851     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
6852     - pairs of AIJ (A) and Dense (B) matrix, C will be of type MATDENSE.
6853 
6854    Level: intermediate
6855 
6856 .seealso: MatMatMult(), MatMatMultSymbolic()
6857 @*/
6858 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultNumeric(Mat A,Mat B,Mat C)
6859 {
6860   PetscErrorCode ierr;
6861   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
6862   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
6863   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
6864 
6865   PetscFunctionBegin;
6866   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6867   PetscValidType(A,1);
6868   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6869   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6870 
6871   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
6872   PetscValidType(B,2);
6873   MatPreallocated(B);
6874   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6875   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6876 
6877   PetscValidHeaderSpecific(C,MAT_COOKIE,3);
6878   PetscValidType(C,3);
6879   MatPreallocated(C);
6880   if (!C->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6881   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6882 
6883   if (B->cmap.N!=C->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap.N,C->cmap.N);
6884   if (B->rmap.N!=A->cmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->cmap.N);
6885   if (A->rmap.N!=C->rmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap.N,C->rmap.N);
6886   ierr = MatPreallocated(A);CHKERRQ(ierr);
6887 
6888   Anumeric = A->ops->matmultnumeric;
6889   Bnumeric = B->ops->matmultnumeric;
6890   if (Anumeric == Bnumeric){
6891     if (!Bnumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",B->type_name);
6892     numeric = Bnumeric;
6893   } else {
6894     char  numericname[256];
6895     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
6896     ierr = PetscStrcat(numericname,A->type_name);CHKERRQ(ierr);
6897     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
6898     ierr = PetscStrcat(numericname,B->type_name);CHKERRQ(ierr);
6899     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
6900     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
6901     if (!numeric)
6902       SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",A->type_name,B->type_name);
6903   }
6904   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
6905   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
6906   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
6907   PetscFunctionReturn(0);
6908 }
6909 
6910 #undef __FUNCT__
6911 #define __FUNCT__ "MatMatMultTranspose"
6912 /*@
6913    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
6914 
6915    Collective on Mat
6916 
6917    Input Parameters:
6918 +  A - the left matrix
6919 .  B - the right matrix
6920 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6921 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B))
6922 
6923    Output Parameters:
6924 .  C - the product matrix
6925 
6926    Notes:
6927    C will be created and must be destroyed by the user with MatDestroy().
6928 
6929    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
6930    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
6931 
6932    Level: intermediate
6933 
6934 .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
6935 @*/
6936 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
6937 {
6938   PetscErrorCode ierr;
6939   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
6940   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
6941 
6942   PetscFunctionBegin;
6943   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6944   PetscValidType(A,1);
6945   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6946   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6947   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
6948   PetscValidType(B,2);
6949   MatPreallocated(B);
6950   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6951   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6952   PetscValidPointer(C,3);
6953   if (B->rmap.N!=A->rmap.N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap.N,A->rmap.N);
6954   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
6955   ierr = MatPreallocated(A);CHKERRQ(ierr);
6956 
6957   fA = A->ops->matmulttranspose;
6958   if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",A->type_name);
6959   fB = B->ops->matmulttranspose;
6960   if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",B->type_name);
6961   if (fB!=fA) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultTranspose requires A, %s, to be compatible with B, %s",A->type_name,B->type_name);
6962 
6963   ierr = PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
6964   ierr = (*A->ops->matmulttranspose)(A,B,scall,fill,C);CHKERRQ(ierr);
6965   ierr = PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
6966 
6967   PetscFunctionReturn(0);
6968 }
6969 
6970 #undef __FUNCT__
6971 #define __FUNCT__ "MatGetRedundantMatrix"
6972 /*@C
6973    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
6974 
6975    Collective on Mat
6976 
6977    Input Parameters:
6978 +  mat - the matrix
6979 .  nsubcomm - the number of subcommunicators (= number of redundant pareallel or sequential matrices)
6980 .  subcomm - MPI communicator split from the communicator where mat resides in
6981 .  mlocal_red - number of local rows of the redundant matrix
6982 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6983 
6984    Output Parameter:
6985 .  matredundant - redundant matrix
6986 
6987    Notes:
6988    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6989    original matrix has not changed from that last call to MatGetRedundantMatrix().
6990 
6991    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
6992    calling it.
6993 
6994    Only MPIAIJ matrix is supported.
6995 
6996    Level: advanced
6997 
6998    Concepts: subcommunicator
6999    Concepts: duplicate matrix
7000 
7001 .seealso: MatDestroy()
7002 @*/
7003 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
7004 {
7005   PetscErrorCode ierr;
7006 
7007   PetscFunctionBegin;
7008   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
7009   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
7010     PetscValidPointer(*matredundant,6);
7011     PetscValidHeaderSpecific(*matredundant,MAT_COOKIE,6);
7012   }
7013   if (!mat->ops->getredundantmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
7014   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7015   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7016   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7017 
7018   ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
7019   ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr);
7020   ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
7021   PetscFunctionReturn(0);
7022 }
7023