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