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