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