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