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