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