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