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