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