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