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