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