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