xref: /petsc/src/mat/interface/matrix.c (revision 8eb2139f285127b90816fa224279e30dd84c25c8)
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   case MAT_NOT_SYMMETRY_ETERNAL:
3663     mat->symmetric_eternal          = PETSC_FALSE;
3664   default:
3665     break;
3666   }
3667   if (mat->ops->setoption) {
3668     ierr = (*mat->ops->setoption)(mat,op);CHKERRQ(ierr);
3669   }
3670   PetscFunctionReturn(0);
3671 }
3672 
3673 #undef __FUNCT__
3674 #define __FUNCT__ "MatZeroEntries"
3675 /*@
3676    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
3677    this routine retains the old nonzero structure.
3678 
3679    Collective on Mat
3680 
3681    Input Parameters:
3682 .  mat - the matrix
3683 
3684    Level: intermediate
3685 
3686    Concepts: matrices^zeroing
3687 
3688 .seealso: MatZeroRows()
3689 @*/
3690 int MatZeroEntries(Mat mat)
3691 {
3692   int ierr;
3693 
3694   PetscFunctionBegin;
3695   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3696   PetscValidType(mat,1);
3697   MatPreallocated(mat);
3698   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3699   if (!mat->ops->zeroentries) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3700 
3701   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
3702   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
3703   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
3704   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3705   PetscFunctionReturn(0);
3706 }
3707 
3708 #undef __FUNCT__
3709 #define __FUNCT__ "MatZeroRows"
3710 /*@C
3711    MatZeroRows - Zeros all entries (except possibly the main diagonal)
3712    of a set of rows of a matrix.
3713 
3714    Collective on Mat
3715 
3716    Input Parameters:
3717 +  mat - the matrix
3718 .  is - index set of rows to remove
3719 -  diag - pointer to value put in all diagonals of eliminated rows.
3720           Note that diag is not a pointer to an array, but merely a
3721           pointer to a single value.
3722 
3723    Notes:
3724    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
3725    but does not release memory.  For the dense and block diagonal
3726    formats this does not alter the nonzero structure.
3727 
3728    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
3729    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
3730    merely zeroed.
3731 
3732    The user can set a value in the diagonal entry (or for the AIJ and
3733    row formats can optionally remove the main diagonal entry from the
3734    nonzero structure as well, by passing a null pointer (PETSC_NULL
3735    in C or PETSC_NULL_SCALAR in Fortran) as the final argument).
3736 
3737    For the parallel case, all processes that share the matrix (i.e.,
3738    those in the communicator used for matrix creation) MUST call this
3739    routine, regardless of whether any rows being zeroed are owned by
3740    them.
3741 
3742    Level: intermediate
3743 
3744    Concepts: matrices^zeroing rows
3745 
3746 .seealso: MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
3747 @*/
3748 int MatZeroRows(Mat mat,IS is,const PetscScalar *diag)
3749 {
3750   int ierr;
3751 
3752   PetscFunctionBegin;
3753   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3754   PetscValidType(mat,1);
3755   MatPreallocated(mat);
3756   PetscValidHeaderSpecific(is,IS_COOKIE,2);
3757   if (diag) PetscValidScalarPointer(diag,3);
3758   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3759   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3760   if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3761 
3762   ierr = (*mat->ops->zerorows)(mat,is,diag);CHKERRQ(ierr);
3763   ierr = MatView_Private(mat);CHKERRQ(ierr);
3764   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3765   PetscFunctionReturn(0);
3766 }
3767 
3768 #undef __FUNCT__
3769 #define __FUNCT__ "MatZeroRowsLocal"
3770 /*@C
3771    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
3772    of a set of rows of a matrix; using local numbering of rows.
3773 
3774    Collective on Mat
3775 
3776    Input Parameters:
3777 +  mat - the matrix
3778 .  is - index set of rows to remove
3779 -  diag - pointer to value put in all diagonals of eliminated rows.
3780           Note that diag is not a pointer to an array, but merely a
3781           pointer to a single value.
3782 
3783    Notes:
3784    Before calling MatZeroRowsLocal(), the user must first set the
3785    local-to-global mapping by calling MatSetLocalToGlobalMapping().
3786 
3787    For the AIJ matrix formats this removes the old nonzero structure,
3788    but does not release memory.  For the dense and block diagonal
3789    formats this does not alter the nonzero structure.
3790 
3791    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
3792    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
3793    merely zeroed.
3794 
3795    The user can set a value in the diagonal entry (or for the AIJ and
3796    row formats can optionally remove the main diagonal entry from the
3797    nonzero structure as well, by passing a null pointer (PETSC_NULL
3798    in C or PETSC_NULL_SCALAR in Fortran) as the final argument).
3799 
3800    Level: intermediate
3801 
3802    Concepts: matrices^zeroing
3803 
3804 .seealso: MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
3805 @*/
3806 int MatZeroRowsLocal(Mat mat,IS is,const PetscScalar *diag)
3807 {
3808   int ierr;
3809   IS  newis;
3810 
3811   PetscFunctionBegin;
3812   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3813   PetscValidType(mat,1);
3814   MatPreallocated(mat);
3815   PetscValidHeaderSpecific(is,IS_COOKIE,2);
3816   if (diag) PetscValidScalarPointer(diag,3);
3817   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3818   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3819 
3820   if (mat->ops->zerorowslocal) {
3821     ierr = (*mat->ops->zerorowslocal)(mat,is,diag);CHKERRQ(ierr);
3822   } else {
3823     if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
3824     ierr = ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);CHKERRQ(ierr);
3825     ierr = (*mat->ops->zerorows)(mat,newis,diag);CHKERRQ(ierr);
3826     ierr = ISDestroy(newis);CHKERRQ(ierr);
3827   }
3828   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3829   PetscFunctionReturn(0);
3830 }
3831 
3832 #undef __FUNCT__
3833 #define __FUNCT__ "MatGetSize"
3834 /*@
3835    MatGetSize - Returns the numbers of rows and columns in a matrix.
3836 
3837    Not Collective
3838 
3839    Input Parameter:
3840 .  mat - the matrix
3841 
3842    Output Parameters:
3843 +  m - the number of global rows
3844 -  n - the number of global columns
3845 
3846    Level: beginner
3847 
3848    Concepts: matrices^size
3849 
3850 .seealso: MatGetLocalSize()
3851 @*/
3852 int MatGetSize(Mat mat,int *m,int* n)
3853 {
3854   PetscFunctionBegin;
3855   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3856   if (m) *m = mat->M;
3857   if (n) *n = mat->N;
3858   PetscFunctionReturn(0);
3859 }
3860 
3861 #undef __FUNCT__
3862 #define __FUNCT__ "MatGetLocalSize"
3863 /*@
3864    MatGetLocalSize - Returns the number of rows and columns in a matrix
3865    stored locally.  This information may be implementation dependent, so
3866    use with care.
3867 
3868    Not Collective
3869 
3870    Input Parameters:
3871 .  mat - the matrix
3872 
3873    Output Parameters:
3874 +  m - the number of local rows
3875 -  n - the number of local columns
3876 
3877    Level: beginner
3878 
3879    Concepts: matrices^local size
3880 
3881 .seealso: MatGetSize()
3882 @*/
3883 int MatGetLocalSize(Mat mat,int *m,int* n)
3884 {
3885   PetscFunctionBegin;
3886   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3887   if (m) PetscValidIntPointer(m,2);
3888   if (n) PetscValidIntPointer(n,3);
3889   if (m) *m = mat->m;
3890   if (n) *n = mat->n;
3891   PetscFunctionReturn(0);
3892 }
3893 
3894 #undef __FUNCT__
3895 #define __FUNCT__ "MatGetOwnershipRange"
3896 /*@
3897    MatGetOwnershipRange - Returns the range of matrix rows owned by
3898    this processor, assuming that the matrix is laid out with the first
3899    n1 rows on the first processor, the next n2 rows on the second, etc.
3900    For certain parallel layouts this range may not be well defined.
3901 
3902    Not Collective
3903 
3904    Input Parameters:
3905 .  mat - the matrix
3906 
3907    Output Parameters:
3908 +  m - the global index of the first local row
3909 -  n - one more than the global index of the last local row
3910 
3911    Level: beginner
3912 
3913    Concepts: matrices^row ownership
3914 @*/
3915 int MatGetOwnershipRange(Mat mat,int *m,int* n)
3916 {
3917   int ierr;
3918 
3919   PetscFunctionBegin;
3920   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3921   PetscValidType(mat,1);
3922   MatPreallocated(mat);
3923   if (m) PetscValidIntPointer(m,2);
3924   if (n) PetscValidIntPointer(n,3);
3925   ierr = PetscMapGetLocalRange(mat->rmap,m,n);CHKERRQ(ierr);
3926   PetscFunctionReturn(0);
3927 }
3928 
3929 #undef __FUNCT__
3930 #define __FUNCT__ "MatILUFactorSymbolic"
3931 /*@
3932    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
3933    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
3934    to complete the factorization.
3935 
3936    Collective on Mat
3937 
3938    Input Parameters:
3939 +  mat - the matrix
3940 .  row - row permutation
3941 .  column - column permutation
3942 -  info - structure containing
3943 $      levels - number of levels of fill.
3944 $      expected fill - as ratio of original fill.
3945 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
3946                 missing diagonal entries)
3947 
3948    Output Parameters:
3949 .  fact - new matrix that has been symbolically factored
3950 
3951    Notes:
3952    See the users manual for additional information about
3953    choosing the fill factor for better efficiency.
3954 
3955    Most users should employ the simplified KSP interface for linear solvers
3956    instead of working directly with matrix algebra routines such as this.
3957    See, e.g., KSPCreate().
3958 
3959    Level: developer
3960 
3961   Concepts: matrices^symbolic LU factorization
3962   Concepts: matrices^factorization
3963   Concepts: LU^symbolic factorization
3964 
3965 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
3966           MatGetOrdering(), MatFactorInfo
3967 
3968 @*/
3969 int MatILUFactorSymbolic(Mat mat,IS row,IS col,MatFactorInfo *info,Mat *fact)
3970 {
3971   int ierr;
3972 
3973   PetscFunctionBegin;
3974   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3975   PetscValidType(mat,1);
3976   MatPreallocated(mat);
3977   PetscValidHeaderSpecific(row,IS_COOKIE,2);
3978   PetscValidHeaderSpecific(col,IS_COOKIE,3);
3979   PetscValidPointer(info,4);
3980   PetscValidPointer(fact,5);
3981   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %d",(int)info->levels);
3982   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",info->fill);
3983   if (!mat->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",mat->type_name);
3984   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3985   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3986 
3987   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3988   ierr = (*mat->ops->ilufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
3989   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3990   PetscFunctionReturn(0);
3991 }
3992 
3993 #undef __FUNCT__
3994 #define __FUNCT__ "MatICCFactorSymbolic"
3995 /*@
3996    MatICCFactorSymbolic - Performs symbolic incomplete
3997    Cholesky factorization for a symmetric matrix.  Use
3998    MatCholeskyFactorNumeric() to complete the factorization.
3999 
4000    Collective on Mat
4001 
4002    Input Parameters:
4003 +  mat - the matrix
4004 .  perm - row and column permutation
4005 -  info - structure containing
4006 $      levels - number of levels of fill.
4007 $      expected fill - as ratio of original fill.
4008 
4009    Output Parameter:
4010 .  fact - the factored matrix
4011 
4012    Notes:
4013    Currently only no-fill factorization is supported.
4014 
4015    Most users should employ the simplified KSP interface for linear solvers
4016    instead of working directly with matrix algebra routines such as this.
4017    See, e.g., KSPCreate().
4018 
4019    Level: developer
4020 
4021   Concepts: matrices^symbolic incomplete Cholesky factorization
4022   Concepts: matrices^factorization
4023   Concepts: Cholsky^symbolic factorization
4024 
4025 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
4026 @*/
4027 int MatICCFactorSymbolic(Mat mat,IS perm,MatFactorInfo *info,Mat *fact)
4028 {
4029   int ierr;
4030 
4031   PetscFunctionBegin;
4032   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4033   PetscValidType(mat,1);
4034   MatPreallocated(mat);
4035   PetscValidHeaderSpecific(perm,IS_COOKIE,2);
4036   PetscValidPointer(info,3);
4037   PetscValidPointer(fact,4);
4038   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4039   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %d",(int) info->levels);
4040   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",info->fill);
4041   if (!mat->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",mat->type_name);
4042   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4043 
4044   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
4045   ierr = (*mat->ops->iccfactorsymbolic)(mat,perm,info,fact);CHKERRQ(ierr);
4046   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
4047   PetscFunctionReturn(0);
4048 }
4049 
4050 #undef __FUNCT__
4051 #define __FUNCT__ "MatGetArray"
4052 /*@C
4053    MatGetArray - Returns a pointer to the element values in the matrix.
4054    The result of this routine is dependent on the underlying matrix data
4055    structure, and may not even work for certain matrix types.  You MUST
4056    call MatRestoreArray() when you no longer need to access the array.
4057 
4058    Not Collective
4059 
4060    Input Parameter:
4061 .  mat - the matrix
4062 
4063    Output Parameter:
4064 .  v - the location of the values
4065 
4066 
4067    Fortran Note:
4068    This routine is used differently from Fortran, e.g.,
4069 .vb
4070         Mat         mat
4071         PetscScalar mat_array(1)
4072         PetscOffset i_mat
4073         int         ierr
4074         call MatGetArray(mat,mat_array,i_mat,ierr)
4075 
4076   C  Access first local entry in matrix; note that array is
4077   C  treated as one dimensional
4078         value = mat_array(i_mat + 1)
4079 
4080         [... other code ...]
4081         call MatRestoreArray(mat,mat_array,i_mat,ierr)
4082 .ve
4083 
4084    See the Fortran chapter of the users manual and
4085    petsc/src/mat/examples/tests for details.
4086 
4087    Level: advanced
4088 
4089    Concepts: matrices^access array
4090 
4091 .seealso: MatRestoreArray(), MatGetArrayF90()
4092 @*/
4093 int MatGetArray(Mat mat,PetscScalar *v[])
4094 {
4095   int ierr;
4096 
4097   PetscFunctionBegin;
4098   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4099   PetscValidType(mat,1);
4100   MatPreallocated(mat);
4101   PetscValidPointer(v,2);
4102   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4103   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
4104   PetscFunctionReturn(0);
4105 }
4106 
4107 #undef __FUNCT__
4108 #define __FUNCT__ "MatRestoreArray"
4109 /*@C
4110    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
4111 
4112    Not Collective
4113 
4114    Input Parameter:
4115 +  mat - the matrix
4116 -  v - the location of the values
4117 
4118    Fortran Note:
4119    This routine is used differently from Fortran, e.g.,
4120 .vb
4121         Mat         mat
4122         PetscScalar mat_array(1)
4123         PetscOffset i_mat
4124         int         ierr
4125         call MatGetArray(mat,mat_array,i_mat,ierr)
4126 
4127   C  Access first local entry in matrix; note that array is
4128   C  treated as one dimensional
4129         value = mat_array(i_mat + 1)
4130 
4131         [... other code ...]
4132         call MatRestoreArray(mat,mat_array,i_mat,ierr)
4133 .ve
4134 
4135    See the Fortran chapter of the users manual and
4136    petsc/src/mat/examples/tests for details
4137 
4138    Level: advanced
4139 
4140 .seealso: MatGetArray(), MatRestoreArrayF90()
4141 @*/
4142 int MatRestoreArray(Mat mat,PetscScalar *v[])
4143 {
4144   int ierr;
4145 
4146   PetscFunctionBegin;
4147   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4148   PetscValidType(mat,1);
4149   MatPreallocated(mat);
4150   PetscValidPointer(v,2);
4151 #if defined(PETSC_USE_BOPT_g)
4152   CHKMEMQ;
4153 #endif
4154   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4155   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
4156   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
4157   PetscFunctionReturn(0);
4158 }
4159 
4160 #undef __FUNCT__
4161 #define __FUNCT__ "MatGetSubMatrices"
4162 /*@C
4163    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
4164    points to an array of valid matrices, they may be reused to store the new
4165    submatrices.
4166 
4167    Collective on Mat
4168 
4169    Input Parameters:
4170 +  mat - the matrix
4171 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
4172 .  irow, icol - index sets of rows and columns to extract
4173 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4174 
4175    Output Parameter:
4176 .  submat - the array of submatrices
4177 
4178    Notes:
4179    MatGetSubMatrices() can extract only sequential submatrices
4180    (from both sequential and parallel matrices). Use MatGetSubMatrix()
4181    to extract a parallel submatrix.
4182 
4183    When extracting submatrices from a parallel matrix, each processor can
4184    form a different submatrix by setting the rows and columns of its
4185    individual index sets according to the local submatrix desired.
4186 
4187    When finished using the submatrices, the user should destroy
4188    them with MatDestroyMatrices().
4189 
4190    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
4191    original matrix has not changed from that last call to MatGetSubMatrices().
4192 
4193    This routine creates the matrices in submat; you should NOT create them before
4194    calling it. It also allocates the array of matrix pointers submat.
4195 
4196    Fortran Note:
4197    The Fortran interface is slightly different from that given below; it
4198    requires one to pass in  as submat a Mat (integer) array of size at least m.
4199 
4200    Level: advanced
4201 
4202    Concepts: matrices^accessing submatrices
4203    Concepts: submatrices
4204 
4205 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal()
4206 @*/
4207 int MatGetSubMatrices(Mat mat,int n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
4208 {
4209   int        ierr;
4210 
4211   PetscFunctionBegin;
4212   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4213   PetscValidType(mat,1);
4214   MatPreallocated(mat);
4215   if (n) {
4216     PetscValidPointer(irow,3);
4217     PetscValidHeaderSpecific(*irow,IS_COOKIE,3);
4218     PetscValidPointer(icol,4);
4219     PetscValidHeaderSpecific(*icol,IS_COOKIE,4);
4220   }
4221   PetscValidPointer(submat,6);
4222   if (n && scall == MAT_REUSE_MATRIX) {
4223     PetscValidPointer(*submat,6);
4224     PetscValidHeaderSpecific(**submat,MAT_COOKIE,6);
4225   }
4226   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4227   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4228   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4229 
4230   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
4231   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
4232   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
4233   PetscFunctionReturn(0);
4234 }
4235 
4236 #undef __FUNCT__
4237 #define __FUNCT__ "MatDestroyMatrices"
4238 /*@C
4239    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
4240 
4241    Collective on Mat
4242 
4243    Input Parameters:
4244 +  n - the number of local matrices
4245 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
4246                        sequence of MatGetSubMatrices())
4247 
4248    Level: advanced
4249 
4250     Notes: Frees not only the matrices, but also the array that contains the matrices
4251 
4252 .seealso: MatGetSubMatrices()
4253 @*/
4254 int MatDestroyMatrices(int n,Mat *mat[])
4255 {
4256   int ierr,i;
4257 
4258   PetscFunctionBegin;
4259   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %d",n);
4260   PetscValidPointer(mat,2);
4261   for (i=0; i<n; i++) {
4262     ierr = MatDestroy((*mat)[i]);CHKERRQ(ierr);
4263   }
4264   /* memory is allocated even if n = 0 */
4265   ierr = PetscFree(*mat);CHKERRQ(ierr);
4266   PetscFunctionReturn(0);
4267 }
4268 
4269 #undef __FUNCT__
4270 #define __FUNCT__ "MatIncreaseOverlap"
4271 /*@
4272    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
4273    replaces the index sets by larger ones that represent submatrices with
4274    additional overlap.
4275 
4276    Collective on Mat
4277 
4278    Input Parameters:
4279 +  mat - the matrix
4280 .  n   - the number of index sets
4281 .  is  - the array of index sets (these index sets will changed during the call)
4282 -  ov  - the additional overlap requested
4283 
4284    Level: developer
4285 
4286    Concepts: overlap
4287    Concepts: ASM^computing overlap
4288 
4289 .seealso: MatGetSubMatrices()
4290 @*/
4291 int MatIncreaseOverlap(Mat mat,int n,IS is[],int ov)
4292 {
4293   int ierr;
4294 
4295   PetscFunctionBegin;
4296   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4297   PetscValidType(mat,1);
4298   MatPreallocated(mat);
4299   if (n < 0) SETERRQ1(1,"Must have one or more domains, you have %d",n);
4300   if (n) {
4301     PetscValidPointer(is,3);
4302     PetscValidHeaderSpecific(*is,IS_COOKIE,3);
4303   }
4304   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4305   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4306 
4307   if (!ov) PetscFunctionReturn(0);
4308   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4309   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
4310   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
4311   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
4312   PetscFunctionReturn(0);
4313 }
4314 
4315 #undef __FUNCT__
4316 #define __FUNCT__ "MatPrintHelp"
4317 /*@
4318    MatPrintHelp - Prints all the options for the matrix.
4319 
4320    Collective on Mat
4321 
4322    Input Parameter:
4323 .  mat - the matrix
4324 
4325    Options Database Keys:
4326 +  -help - Prints matrix options
4327 -  -h - Prints matrix options
4328 
4329    Level: developer
4330 
4331 .seealso: MatCreate(), MatCreateXXX()
4332 @*/
4333 int MatPrintHelp(Mat mat)
4334 {
4335   static PetscTruth called = PETSC_FALSE;
4336   int               ierr;
4337 
4338   PetscFunctionBegin;
4339   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4340   PetscValidType(mat,1);
4341   MatPreallocated(mat);
4342 
4343   if (!called) {
4344     if (mat->ops->printhelp) {
4345       ierr = (*mat->ops->printhelp)(mat);CHKERRQ(ierr);
4346     }
4347     called = PETSC_TRUE;
4348   }
4349   PetscFunctionReturn(0);
4350 }
4351 
4352 #undef __FUNCT__
4353 #define __FUNCT__ "MatGetBlockSize"
4354 /*@
4355    MatGetBlockSize - Returns the matrix block size; useful especially for the
4356    block row and block diagonal formats.
4357 
4358    Not Collective
4359 
4360    Input Parameter:
4361 .  mat - the matrix
4362 
4363    Output Parameter:
4364 .  bs - block size
4365 
4366    Notes:
4367    Block diagonal formats are MATSEQBDIAG, MATMPIBDIAG.
4368    Block row formats are MATSEQBAIJ, MATMPIBAIJ
4369 
4370    Level: intermediate
4371 
4372    Concepts: matrices^block size
4373 
4374 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatCreateSeqBDiag(), MatCreateMPIBDiag()
4375 @*/
4376 int MatGetBlockSize(Mat mat,int *bs)
4377 {
4378   int ierr;
4379 
4380   PetscFunctionBegin;
4381   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4382   PetscValidType(mat,1);
4383   MatPreallocated(mat);
4384   PetscValidIntPointer(bs,2);
4385   if (!mat->ops->getblocksize) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4386   ierr = (*mat->ops->getblocksize)(mat,bs);CHKERRQ(ierr);
4387   PetscFunctionReturn(0);
4388 }
4389 
4390 #undef __FUNCT__
4391 #define __FUNCT__ "MatGetRowIJ"
4392 /*@C
4393     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
4394 
4395    Collective on Mat
4396 
4397     Input Parameters:
4398 +   mat - the matrix
4399 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
4400 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4401                 symmetrized
4402 
4403     Output Parameters:
4404 +   n - number of rows in the (possibly compressed) matrix
4405 .   ia - the row pointers
4406 .   ja - the column indices
4407 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
4408 
4409     Level: developer
4410 
4411 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
4412 @*/
4413 int MatGetRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4414 {
4415   int ierr;
4416 
4417   PetscFunctionBegin;
4418   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4419   PetscValidType(mat,1);
4420   MatPreallocated(mat);
4421   PetscValidIntPointer(n,4);
4422   if (ia) PetscValidIntPointer(ia,5);
4423   if (ja) PetscValidIntPointer(ja,6);
4424   PetscValidIntPointer(done,7);
4425   if (!mat->ops->getrowij) *done = PETSC_FALSE;
4426   else {
4427     *done = PETSC_TRUE;
4428     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4429   }
4430   PetscFunctionReturn(0);
4431 }
4432 
4433 #undef __FUNCT__
4434 #define __FUNCT__ "MatGetColumnIJ"
4435 /*@C
4436     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
4437 
4438     Collective on Mat
4439 
4440     Input Parameters:
4441 +   mat - the matrix
4442 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4443 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4444                 symmetrized
4445 
4446     Output Parameters:
4447 +   n - number of columns in the (possibly compressed) matrix
4448 .   ia - the column pointers
4449 .   ja - the row indices
4450 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
4451 
4452     Level: developer
4453 
4454 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
4455 @*/
4456 int MatGetColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4457 {
4458   int ierr;
4459 
4460   PetscFunctionBegin;
4461   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4462   PetscValidType(mat,1);
4463   MatPreallocated(mat);
4464   PetscValidIntPointer(n,4);
4465   if (ia) PetscValidIntPointer(ia,5);
4466   if (ja) PetscValidIntPointer(ja,6);
4467   PetscValidIntPointer(done,7);
4468 
4469   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
4470   else {
4471     *done = PETSC_TRUE;
4472     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4473   }
4474   PetscFunctionReturn(0);
4475 }
4476 
4477 #undef __FUNCT__
4478 #define __FUNCT__ "MatRestoreRowIJ"
4479 /*@C
4480     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
4481     MatGetRowIJ().
4482 
4483     Collective on Mat
4484 
4485     Input Parameters:
4486 +   mat - the matrix
4487 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4488 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4489                 symmetrized
4490 
4491     Output Parameters:
4492 +   n - size of (possibly compressed) matrix
4493 .   ia - the row pointers
4494 .   ja - the column indices
4495 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
4496 
4497     Level: developer
4498 
4499 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
4500 @*/
4501 int MatRestoreRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4502 {
4503   int ierr;
4504 
4505   PetscFunctionBegin;
4506   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4507   PetscValidType(mat,1);
4508   MatPreallocated(mat);
4509   if (ia) PetscValidIntPointer(ia,5);
4510   if (ja) PetscValidIntPointer(ja,6);
4511   PetscValidIntPointer(done,7);
4512 
4513   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
4514   else {
4515     *done = PETSC_TRUE;
4516     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4517   }
4518   PetscFunctionReturn(0);
4519 }
4520 
4521 #undef __FUNCT__
4522 #define __FUNCT__ "MatRestoreColumnIJ"
4523 /*@C
4524     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
4525     MatGetColumnIJ().
4526 
4527     Collective on Mat
4528 
4529     Input Parameters:
4530 +   mat - the matrix
4531 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4532 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4533                 symmetrized
4534 
4535     Output Parameters:
4536 +   n - size of (possibly compressed) matrix
4537 .   ia - the column pointers
4538 .   ja - the row indices
4539 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
4540 
4541     Level: developer
4542 
4543 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
4544 @*/
4545 int MatRestoreColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4546 {
4547   int ierr;
4548 
4549   PetscFunctionBegin;
4550   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4551   PetscValidType(mat,1);
4552   MatPreallocated(mat);
4553   if (ia) PetscValidIntPointer(ia,5);
4554   if (ja) PetscValidIntPointer(ja,6);
4555   PetscValidIntPointer(done,7);
4556 
4557   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
4558   else {
4559     *done = PETSC_TRUE;
4560     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4561   }
4562   PetscFunctionReturn(0);
4563 }
4564 
4565 #undef __FUNCT__
4566 #define __FUNCT__ "MatColoringPatch"
4567 /*@C
4568     MatColoringPatch -Used inside matrix coloring routines that
4569     use MatGetRowIJ() and/or MatGetColumnIJ().
4570 
4571     Collective on Mat
4572 
4573     Input Parameters:
4574 +   mat - the matrix
4575 .   n   - number of colors
4576 -   colorarray - array indicating color for each column
4577 
4578     Output Parameters:
4579 .   iscoloring - coloring generated using colorarray information
4580 
4581     Level: developer
4582 
4583 .seealso: MatGetRowIJ(), MatGetColumnIJ()
4584 
4585 @*/
4586 int MatColoringPatch(Mat mat,int n,int ncolors,const ISColoringValue colorarray[],ISColoring *iscoloring)
4587 {
4588   int ierr;
4589 
4590   PetscFunctionBegin;
4591   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4592   PetscValidType(mat,1);
4593   MatPreallocated(mat);
4594   PetscValidIntPointer(colorarray,4);
4595   PetscValidPointer(iscoloring,5);
4596 
4597   if (!mat->ops->coloringpatch){
4598     ierr = ISColoringCreate(mat->comm,n,colorarray,iscoloring);CHKERRQ(ierr);
4599   } else {
4600     ierr = (*mat->ops->coloringpatch)(mat,n,ncolors,colorarray,iscoloring);CHKERRQ(ierr);
4601   }
4602   PetscFunctionReturn(0);
4603 }
4604 
4605 
4606 #undef __FUNCT__
4607 #define __FUNCT__ "MatSetUnfactored"
4608 /*@
4609    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
4610 
4611    Collective on Mat
4612 
4613    Input Parameter:
4614 .  mat - the factored matrix to be reset
4615 
4616    Notes:
4617    This routine should be used only with factored matrices formed by in-place
4618    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
4619    format).  This option can save memory, for example, when solving nonlinear
4620    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
4621    ILU(0) preconditioner.
4622 
4623    Note that one can specify in-place ILU(0) factorization by calling
4624 .vb
4625      PCType(pc,PCILU);
4626      PCILUSeUseInPlace(pc);
4627 .ve
4628    or by using the options -pc_type ilu -pc_ilu_in_place
4629 
4630    In-place factorization ILU(0) can also be used as a local
4631    solver for the blocks within the block Jacobi or additive Schwarz
4632    methods (runtime option: -sub_pc_ilu_in_place).  See the discussion
4633    of these preconditioners in the users manual for details on setting
4634    local solver options.
4635 
4636    Most users should employ the simplified KSP interface for linear solvers
4637    instead of working directly with matrix algebra routines such as this.
4638    See, e.g., KSPCreate().
4639 
4640    Level: developer
4641 
4642 .seealso: PCILUSetUseInPlace(), PCLUSetUseInPlace()
4643 
4644    Concepts: matrices^unfactored
4645 
4646 @*/
4647 int MatSetUnfactored(Mat mat)
4648 {
4649   int ierr;
4650 
4651   PetscFunctionBegin;
4652   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4653   PetscValidType(mat,1);
4654   MatPreallocated(mat);
4655   mat->factor = 0;
4656   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
4657   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
4658   PetscFunctionReturn(0);
4659 }
4660 
4661 /*MC
4662     MatGetArrayF90 - Accesses a matrix array from Fortran90.
4663 
4664     Synopsis:
4665     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
4666 
4667     Not collective
4668 
4669     Input Parameter:
4670 .   x - matrix
4671 
4672     Output Parameters:
4673 +   xx_v - the Fortran90 pointer to the array
4674 -   ierr - error code
4675 
4676     Example of Usage:
4677 .vb
4678       PetscScalar, pointer xx_v(:)
4679       ....
4680       call MatGetArrayF90(x,xx_v,ierr)
4681       a = xx_v(3)
4682       call MatRestoreArrayF90(x,xx_v,ierr)
4683 .ve
4684 
4685     Notes:
4686     Not yet supported for all F90 compilers
4687 
4688     Level: advanced
4689 
4690 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
4691 
4692     Concepts: matrices^accessing array
4693 
4694 M*/
4695 
4696 /*MC
4697     MatRestoreArrayF90 - Restores a matrix array that has been
4698     accessed with MatGetArrayF90().
4699 
4700     Synopsis:
4701     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
4702 
4703     Not collective
4704 
4705     Input Parameters:
4706 +   x - matrix
4707 -   xx_v - the Fortran90 pointer to the array
4708 
4709     Output Parameter:
4710 .   ierr - error code
4711 
4712     Example of Usage:
4713 .vb
4714        PetscScalar, pointer xx_v(:)
4715        ....
4716        call MatGetArrayF90(x,xx_v,ierr)
4717        a = xx_v(3)
4718        call MatRestoreArrayF90(x,xx_v,ierr)
4719 .ve
4720 
4721     Notes:
4722     Not yet supported for all F90 compilers
4723 
4724     Level: advanced
4725 
4726 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
4727 
4728 M*/
4729 
4730 
4731 #undef __FUNCT__
4732 #define __FUNCT__ "MatGetSubMatrix"
4733 /*@
4734     MatGetSubMatrix - Gets a single submatrix on the same number of processors
4735                       as the original matrix.
4736 
4737     Collective on Mat
4738 
4739     Input Parameters:
4740 +   mat - the original matrix
4741 .   isrow - rows this processor should obtain
4742 .   iscol - columns for all processors you wish to keep
4743 .   csize - number of columns "local" to this processor (does nothing for sequential
4744             matrices). This should match the result from VecGetLocalSize(x,...) if you
4745             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
4746 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4747 
4748     Output Parameter:
4749 .   newmat - the new submatrix, of the same type as the old
4750 
4751     Level: advanced
4752 
4753     Notes: the iscol argument MUST be the same on each processor. You might be
4754     able to create the iscol argument with ISAllGather().
4755 
4756       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
4757    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
4758    to this routine with a mat of the same nonzero structure will reuse the matrix
4759    generated the first time.
4760 
4761     Concepts: matrices^submatrices
4762 
4763 .seealso: MatGetSubMatrices(), ISAllGather()
4764 @*/
4765 int MatGetSubMatrix(Mat mat,IS isrow,IS iscol,int csize,MatReuse cll,Mat *newmat)
4766 {
4767   int     ierr, size;
4768   Mat     *local;
4769 
4770   PetscFunctionBegin;
4771   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4772   PetscValidHeaderSpecific(isrow,IS_COOKIE,2);
4773   PetscValidHeaderSpecific(iscol,IS_COOKIE,3);
4774   PetscValidPointer(newmat,6);
4775   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_COOKIE,6);
4776   PetscValidType(mat,1);
4777   MatPreallocated(mat);
4778   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4779   ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr);
4780 
4781   /* if original matrix is on just one processor then use submatrix generated */
4782   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
4783     ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
4784     PetscFunctionReturn(0);
4785   } else if (!mat->ops->getsubmatrix && size == 1) {
4786     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
4787     *newmat = *local;
4788     ierr    = PetscFree(local);CHKERRQ(ierr);
4789     PetscFunctionReturn(0);
4790   }
4791 
4792   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4793   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscol,csize,cll,newmat);CHKERRQ(ierr);
4794   ierr = PetscObjectIncreaseState((PetscObject)*newmat); CHKERRQ(ierr);
4795   PetscFunctionReturn(0);
4796 }
4797 
4798 #undef __FUNCT__
4799 #define __FUNCT__ "MatGetPetscMaps"
4800 /*@C
4801    MatGetPetscMaps - Returns the maps associated with the matrix.
4802 
4803    Not Collective
4804 
4805    Input Parameter:
4806 .  mat - the matrix
4807 
4808    Output Parameters:
4809 +  rmap - the row (right) map
4810 -  cmap - the column (left) map
4811 
4812    Level: developer
4813 
4814    Concepts: maps^getting from matrix
4815 
4816 @*/
4817 int MatGetPetscMaps(Mat mat,PetscMap *rmap,PetscMap *cmap)
4818 {
4819   int ierr;
4820 
4821   PetscFunctionBegin;
4822   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4823   PetscValidType(mat,1);
4824   MatPreallocated(mat);
4825   ierr = (*mat->ops->getmaps)(mat,rmap,cmap);CHKERRQ(ierr);
4826   PetscFunctionReturn(0);
4827 }
4828 
4829 /*
4830       Version that works for all PETSc matrices
4831 */
4832 #undef __FUNCT__
4833 #define __FUNCT__ "MatGetPetscMaps_Petsc"
4834 int MatGetPetscMaps_Petsc(Mat mat,PetscMap *rmap,PetscMap *cmap)
4835 {
4836   PetscFunctionBegin;
4837   if (rmap) *rmap = mat->rmap;
4838   if (cmap) *cmap = mat->cmap;
4839   PetscFunctionReturn(0);
4840 }
4841 
4842 #undef __FUNCT__
4843 #define __FUNCT__ "MatSetStashInitialSize"
4844 /*@
4845    MatSetStashInitialSize - sets the sizes of the matrix stash, that is
4846    used during the assembly process to store values that belong to
4847    other processors.
4848 
4849    Not Collective
4850 
4851    Input Parameters:
4852 +  mat   - the matrix
4853 .  size  - the initial size of the stash.
4854 -  bsize - the initial size of the block-stash(if used).
4855 
4856    Options Database Keys:
4857 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
4858 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
4859 
4860    Level: intermediate
4861 
4862    Notes:
4863      The block-stash is used for values set with VecSetValuesBlocked() while
4864      the stash is used for values set with VecSetValues()
4865 
4866      Run with the option -log_info and look for output of the form
4867      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
4868      to determine the appropriate value, MM, to use for size and
4869      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
4870      to determine the value, BMM to use for bsize
4871 
4872    Concepts: stash^setting matrix size
4873    Concepts: matrices^stash
4874 
4875 @*/
4876 int MatSetStashInitialSize(Mat mat,int size, int bsize)
4877 {
4878   int ierr;
4879 
4880   PetscFunctionBegin;
4881   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4882   PetscValidType(mat,1);
4883   MatPreallocated(mat);
4884   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
4885   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
4886   PetscFunctionReturn(0);
4887 }
4888 
4889 #undef __FUNCT__
4890 #define __FUNCT__ "MatInterpolateAdd"
4891 /*@
4892    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
4893      the matrix
4894 
4895    Collective on Mat
4896 
4897    Input Parameters:
4898 +  mat   - the matrix
4899 .  x,y - the vectors
4900 -  w - where the result is stored
4901 
4902    Level: intermediate
4903 
4904    Notes:
4905     w may be the same vector as y.
4906 
4907     This allows one to use either the restriction or interpolation (its transpose)
4908     matrix to do the interpolation
4909 
4910     Concepts: interpolation
4911 
4912 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
4913 
4914 @*/
4915 int MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
4916 {
4917   int M,N,ierr;
4918 
4919   PetscFunctionBegin;
4920   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
4921   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
4922   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
4923   PetscValidHeaderSpecific(w,VEC_COOKIE,4);
4924   PetscValidType(A,1);
4925   MatPreallocated(A);
4926   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4927   if (N > M) {
4928     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
4929   } else {
4930     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
4931   }
4932   PetscFunctionReturn(0);
4933 }
4934 
4935 #undef __FUNCT__
4936 #define __FUNCT__ "MatInterpolate"
4937 /*@
4938    MatInterpolate - y = A*x or A'*x depending on the shape of
4939      the matrix
4940 
4941    Collective on Mat
4942 
4943    Input Parameters:
4944 +  mat   - the matrix
4945 -  x,y - the vectors
4946 
4947    Level: intermediate
4948 
4949    Notes:
4950     This allows one to use either the restriction or interpolation (its transpose)
4951     matrix to do the interpolation
4952 
4953    Concepts: matrices^interpolation
4954 
4955 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
4956 
4957 @*/
4958 int MatInterpolate(Mat A,Vec x,Vec y)
4959 {
4960   int M,N,ierr;
4961 
4962   PetscFunctionBegin;
4963   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
4964   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
4965   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
4966   PetscValidType(A,1);
4967   MatPreallocated(A);
4968   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4969   if (N > M) {
4970     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
4971   } else {
4972     ierr = MatMult(A,x,y);CHKERRQ(ierr);
4973   }
4974   PetscFunctionReturn(0);
4975 }
4976 
4977 #undef __FUNCT__
4978 #define __FUNCT__ "MatRestrict"
4979 /*@
4980    MatRestrict - y = A*x or A'*x
4981 
4982    Collective on Mat
4983 
4984    Input Parameters:
4985 +  mat   - the matrix
4986 -  x,y - the vectors
4987 
4988    Level: intermediate
4989 
4990    Notes:
4991     This allows one to use either the restriction or interpolation (its transpose)
4992     matrix to do the restriction
4993 
4994    Concepts: matrices^restriction
4995 
4996 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
4997 
4998 @*/
4999 int MatRestrict(Mat A,Vec x,Vec y)
5000 {
5001   int M,N,ierr;
5002 
5003   PetscFunctionBegin;
5004   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5005   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
5006   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
5007   PetscValidType(A,1);
5008   MatPreallocated(A);
5009   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
5010   if (N > M) {
5011     ierr = MatMult(A,x,y);CHKERRQ(ierr);
5012   } else {
5013     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
5014   }
5015   PetscFunctionReturn(0);
5016 }
5017 
5018 #undef __FUNCT__
5019 #define __FUNCT__ "MatNullSpaceAttach"
5020 /*@C
5021    MatNullSpaceAttach - attaches a null space to a matrix.
5022         This null space will be removed from the resulting vector whenever
5023         MatMult() is called
5024 
5025    Collective on Mat
5026 
5027    Input Parameters:
5028 +  mat - the matrix
5029 -  nullsp - the null space object
5030 
5031    Level: developer
5032 
5033    Notes:
5034       Overwrites any previous null space that may have been attached
5035 
5036    Concepts: null space^attaching to matrix
5037 
5038 .seealso: MatCreate(), MatNullSpaceCreate()
5039 @*/
5040 int MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
5041 {
5042   int ierr;
5043 
5044   PetscFunctionBegin;
5045   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5046   PetscValidType(mat,1);
5047   MatPreallocated(mat);
5048   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_COOKIE,2);
5049 
5050   if (mat->nullsp) {
5051     ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr);
5052   }
5053   mat->nullsp = nullsp;
5054   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
5055   PetscFunctionReturn(0);
5056 }
5057 
5058 #undef __FUNCT__
5059 #define __FUNCT__ "MatICCFactor"
5060 /*@
5061    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
5062 
5063    Collective on Mat
5064 
5065    Input Parameters:
5066 +  mat - the matrix
5067 .  row - row/column permutation
5068 .  fill - expected fill factor >= 1.0
5069 -  level - level of fill, for ICC(k)
5070 
5071    Notes:
5072    Probably really in-place only when level of fill is zero, otherwise allocates
5073    new space to store factored matrix and deletes previous memory.
5074 
5075    Most users should employ the simplified KSP interface for linear solvers
5076    instead of working directly with matrix algebra routines such as this.
5077    See, e.g., KSPCreate().
5078 
5079    Level: developer
5080 
5081    Concepts: matrices^incomplete Cholesky factorization
5082    Concepts: Cholesky factorization
5083 
5084 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5085 @*/
5086 int MatICCFactor(Mat mat,IS row,MatFactorInfo* info)
5087 {
5088   int ierr;
5089 
5090   PetscFunctionBegin;
5091   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5092   PetscValidType(mat,1);
5093   MatPreallocated(mat);
5094   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
5095   PetscValidPointer(info,3);
5096   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
5097   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5098   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5099   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5100   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
5101   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
5102   PetscFunctionReturn(0);
5103 }
5104 
5105 #undef __FUNCT__
5106 #define __FUNCT__ "MatSetValuesAdic"
5107 /*@
5108    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
5109 
5110    Not Collective
5111 
5112    Input Parameters:
5113 +  mat - the matrix
5114 -  v - the values compute with ADIC
5115 
5116    Level: developer
5117 
5118    Notes:
5119      Must call MatSetColoring() before using this routine. Also this matrix must already
5120      have its nonzero pattern determined.
5121 
5122 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5123           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
5124 @*/
5125 int MatSetValuesAdic(Mat mat,void *v)
5126 {
5127   int ierr;
5128 
5129   PetscFunctionBegin;
5130   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5131   PetscValidType(mat,1);
5132   PetscValidPointer(mat,2);
5133 
5134   if (!mat->assembled) {
5135     SETERRQ(1,"Matrix must be already assembled");
5136   }
5137   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5138   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5139   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
5140   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5141   ierr = MatView_Private(mat);CHKERRQ(ierr);
5142   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
5143   PetscFunctionReturn(0);
5144 }
5145 
5146 
5147 #undef __FUNCT__
5148 #define __FUNCT__ "MatSetColoring"
5149 /*@
5150    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
5151 
5152    Not Collective
5153 
5154    Input Parameters:
5155 +  mat - the matrix
5156 -  coloring - the coloring
5157 
5158    Level: developer
5159 
5160 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5161           MatSetValues(), MatSetValuesAdic()
5162 @*/
5163 int MatSetColoring(Mat mat,ISColoring coloring)
5164 {
5165   int ierr;
5166 
5167   PetscFunctionBegin;
5168   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5169   PetscValidType(mat,1);
5170   PetscValidPointer(coloring,2);
5171 
5172   if (!mat->assembled) {
5173     SETERRQ(1,"Matrix must be already assembled");
5174   }
5175   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5176   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
5177   PetscFunctionReturn(0);
5178 }
5179 
5180 #undef __FUNCT__
5181 #define __FUNCT__ "MatSetValuesAdifor"
5182 /*@
5183    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
5184 
5185    Not Collective
5186 
5187    Input Parameters:
5188 +  mat - the matrix
5189 .  nl - leading dimension of v
5190 -  v - the values compute with ADIFOR
5191 
5192    Level: developer
5193 
5194    Notes:
5195      Must call MatSetColoring() before using this routine. Also this matrix must already
5196      have its nonzero pattern determined.
5197 
5198 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5199           MatSetValues(), MatSetColoring()
5200 @*/
5201 int MatSetValuesAdifor(Mat mat,int nl,void *v)
5202 {
5203   int ierr;
5204 
5205   PetscFunctionBegin;
5206   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5207   PetscValidType(mat,1);
5208   PetscValidPointer(v,3);
5209 
5210   if (!mat->assembled) {
5211     SETERRQ(1,"Matrix must be already assembled");
5212   }
5213   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5214   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5215   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
5216   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5217   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
5218   PetscFunctionReturn(0);
5219 }
5220 
5221 EXTERN int MatMPIAIJDiagonalScaleLocal(Mat,Vec);
5222 EXTERN int MatMPIBAIJDiagonalScaleLocal(Mat,Vec);
5223 
5224 #undef __FUNCT__
5225 #define __FUNCT__ "MatDiagonalScaleLocal"
5226 /*@
5227    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
5228          ghosted ones.
5229 
5230    Not Collective
5231 
5232    Input Parameters:
5233 +  mat - the matrix
5234 -  diag = the diagonal values, including ghost ones
5235 
5236    Level: developer
5237 
5238    Notes: Works only for MPIAIJ and MPIBAIJ matrices
5239 
5240 .seealso: MatDiagonalScale()
5241 @*/
5242 int MatDiagonalScaleLocal(Mat mat,Vec diag)
5243 {
5244   int        ierr,size;
5245 
5246   PetscFunctionBegin;
5247   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5248   PetscValidHeaderSpecific(diag,VEC_COOKIE,2);
5249   PetscValidType(mat,1);
5250 
5251   if (!mat->assembled) {
5252     SETERRQ(1,"Matrix must be already assembled");
5253   }
5254   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5255   ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr);
5256   if (size == 1) {
5257     int n,m;
5258     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
5259     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
5260     if (m == n) {
5261       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
5262     } else {
5263       SETERRQ(1,"Only supprted for sequential matrices when no ghost points/periodic conditions");
5264     }
5265   } else {
5266     int (*f)(Mat,Vec);
5267     ierr = PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);CHKERRQ(ierr);
5268     if (f) {
5269       ierr = (*f)(mat,diag);CHKERRQ(ierr);
5270     } else {
5271       SETERRQ(1,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
5272     }
5273   }
5274   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5275   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
5276   PetscFunctionReturn(0);
5277 }
5278 
5279 #undef __FUNCT__
5280 #define __FUNCT__ "MatGetInertia"
5281 /*@
5282    MatGetInertia - Gets the inertia from a factored matrix
5283 
5284    Collective on Mat
5285 
5286    Input Parameter:
5287 .  mat - the matrix
5288 
5289    Output Parameters:
5290 +   nneg - number of negative eigenvalues
5291 .   nzero - number of zero eigenvalues
5292 -   npos - number of positive eigenvalues
5293 
5294    Level: advanced
5295 
5296    Notes: Matrix must have been factored by MatCholeskyFactor()
5297 
5298 
5299 @*/
5300 int MatGetInertia(Mat mat,int *nneg,int *nzero,int *npos)
5301 {
5302   int        ierr;
5303 
5304   PetscFunctionBegin;
5305   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5306   PetscValidType(mat,1);
5307   if (!mat->factor)    SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
5308   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
5309   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5310   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
5311   PetscFunctionReturn(0);
5312 }
5313 
5314 /* ----------------------------------------------------------------*/
5315 #undef __FUNCT__
5316 #define __FUNCT__ "MatSolves"
5317 /*@
5318    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
5319 
5320    Collective on Mat and Vecs
5321 
5322    Input Parameters:
5323 +  mat - the factored matrix
5324 -  b - the right-hand-side vectors
5325 
5326    Output Parameter:
5327 .  x - the result vectors
5328 
5329    Notes:
5330    The vectors b and x cannot be the same.  I.e., one cannot
5331    call MatSolves(A,x,x).
5332 
5333    Notes:
5334    Most users should employ the simplified KSP interface for linear solvers
5335    instead of working directly with matrix algebra routines such as this.
5336    See, e.g., KSPCreate().
5337 
5338    Level: developer
5339 
5340    Concepts: matrices^triangular solves
5341 
5342 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
5343 @*/
5344 int MatSolves(Mat mat,Vecs b,Vecs x)
5345 {
5346   int ierr;
5347 
5348   PetscFunctionBegin;
5349   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5350   PetscValidType(mat,1);
5351   MatPreallocated(mat);
5352   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
5353   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
5354   if (mat->M == 0 && mat->N == 0) PetscFunctionReturn(0);
5355 
5356   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5357   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
5358   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
5359   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
5360   PetscFunctionReturn(0);
5361 }
5362 
5363 #undef __FUNCT__
5364 #define __FUNCT__ "MatIsSymmetric"
5365 /*@C
5366    MatIsSymmetric - Test whether a matrix is symmetric
5367 
5368    Collective on Mat
5369 
5370    Input Parameter:
5371 .  A - the matrix to test
5372 
5373    Output Parameters:
5374 .  flg - the result
5375 
5376    Level: intermediate
5377 
5378    Concepts: matrix^symmetry
5379 
5380 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption()
5381 @*/
5382 int MatIsSymmetric(Mat A,PetscTruth *flg)
5383 {
5384   int ierr;
5385 
5386   PetscFunctionBegin;
5387   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5388   PetscValidPointer(flg,2);
5389   if (!A->symmetric_set) {
5390     if (!A->ops->issymmetric) {
5391       MatType mattype;
5392       ierr = MatGetType(A,&mattype); CHKERRQ(ierr);
5393       SETERRQ1(1,"Matrix of type <%s> does not support checking for symmetric",
5394 	       mattype);
5395     }
5396     ierr = (*A->ops->issymmetric)(A,&A->symmetric); CHKERRQ(ierr);
5397     A->symmetric_set = PETSC_TRUE;
5398     if (A->symmetric) {
5399       A->structurally_symmetric_set = PETSC_TRUE;
5400       A->structurally_symmetric     = PETSC_TRUE;
5401     }
5402   }
5403   *flg = A->symmetric;
5404   PetscFunctionReturn(0);
5405 }
5406 
5407 #undef __FUNCT__
5408 #define __FUNCT__ "MatIsStructurallySymmetric"
5409 /*@C
5410    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
5411 
5412    Collective on Mat
5413 
5414    Input Parameter:
5415 .  A - the matrix to test
5416 
5417    Output Parameters:
5418 .  flg - the result
5419 
5420    Level: intermediate
5421 
5422    Concepts: matrix^symmetry
5423 
5424 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
5425 @*/
5426 int MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
5427 {
5428   int ierr;
5429 
5430   PetscFunctionBegin;
5431   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5432   PetscValidPointer(flg,2);
5433   if (!A->structurally_symmetric_set) {
5434     if (!A->ops->isstructurallysymmetric) SETERRQ(1,"Matrix does not support checking for structural symmetric");
5435     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
5436     A->structurally_symmetric_set = PETSC_TRUE;
5437   }
5438   *flg = A->structurally_symmetric;
5439   PetscFunctionReturn(0);
5440 }
5441 
5442 #undef __FUNCT__
5443 #define __FUNCT__ "MatIsHermitian"
5444 /*@C
5445    MatIsHermitian - Test whether a matrix is Hermitian, i.e. it is the complex conjugate of its transpose.
5446 
5447    Collective on Mat
5448 
5449    Input Parameter:
5450 .  A - the matrix to test
5451 
5452    Output Parameters:
5453 .  flg - the result
5454 
5455    Level: intermediate
5456 
5457    Concepts: matrix^symmetry
5458 
5459 .seealso: MatTranspose(), MatIsTranspose(), MatIsSymmetric(), MatIsStructurallySymmetric(), MatSetOption()
5460 @*/
5461 int MatIsHermitian(Mat A,PetscTruth *flg)
5462 {
5463   int ierr;
5464 
5465   PetscFunctionBegin;
5466   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5467   PetscValidPointer(flg,2);
5468   if (!A->hermitian_set) {
5469     if (!A->ops->ishermitian) SETERRQ(1,"Matrix does not support checking for being Hermitian");
5470     ierr = (*A->ops->ishermitian)(A,&A->hermitian);CHKERRQ(ierr);
5471     A->hermitian_set = PETSC_TRUE;
5472     if (A->hermitian) {
5473       A->structurally_symmetric_set = PETSC_TRUE;
5474       A->structurally_symmetric     = PETSC_TRUE;
5475     }
5476   }
5477   *flg = A->hermitian;
5478   PetscFunctionReturn(0);
5479 }
5480