xref: /petsc/src/mat/interface/matrix.c (revision 22a18b75d3436e22c97e034b40198a1e463bacc5)
1 #ifdef PETSC_RCS_HEADER
2 static char vcid[] = "$Id: matrix.c,v 1.319 1999/02/26 16:55:35 balay Exp bsmith $";
3 #endif
4 
5 /*
6    This is where the abstract matrix operations are defined
7 */
8 
9 #include "src/mat/matimpl.h"        /*I "mat.h" I*/
10 #include "src/vec/vecimpl.h"
11 
12 #undef __FUNC__
13 #define __FUNC__ "MatGetRow"
14 /*@C
15    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
16    for each row that you get to ensure that your application does
17    not bleed memory.
18 
19    Not Collective
20 
21    Input Parameters:
22 +  mat - the matrix
23 -  row - the row to get
24 
25    Output Parameters:
26 +  ncols -  the number of nonzeros in the row
27 .  cols - if nonzero, the column numbers
28 -  vals - if nonzero, the values
29 
30    Notes:
31    This routine is provided for people who need to have direct access
32    to the structure of a matrix.  We hope that we provide enough
33    high-level matrix routines that few users will need it.
34 
35    MatGetRow() always returns 0-based column indices, regardless of
36    whether the internal representation is 0-based (default) or 1-based.
37 
38    For better efficiency, set cols and/or vals to PETSC_NULL if you do
39    not wish to extract these quantities.
40 
41    The user can only examine the values extracted with MatGetRow();
42    the values cannot be altered.  To change the matrix entries, one
43    must use MatSetValues().
44 
45    You can only have one call to MatGetRow() outstanding for a particular
46    matrix at a time.
47 
48    Fortran Notes:
49    The calling sequence from Fortran is
50 .vb
51    MatGetRow(matrix,row,ncols,cols,values,ierr)
52          Mat     matrix (input)
53          integer row    (input)
54          integer ncols  (output)
55          integer cols(maxcols) (output)
56          double precision (or double complex) values(maxcols) output
57 .ve
58    where maxcols >= maximum nonzeros in any row of the matrix.
59 
60    Caution:
61    Do not try to change the contents of the output arrays (cols and vals).
62    In some cases, this may corrupt the matrix.
63 
64 .keywords: matrix, row, get, extract
65 
66 .seealso: MatRestoreRow(), MatSetValues()
67 @*/
68 int MatGetRow(Mat mat,int row,int *ncols,int **cols,Scalar **vals)
69 {
70   int   ierr;
71 
72   PetscFunctionBegin;
73   PetscValidHeaderSpecific(mat,MAT_COOKIE);
74   PetscValidIntPointer(ncols);
75   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
76   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
77   if (!mat->ops->getrow) SETERRQ(PETSC_ERR_SUP,0,"");
78   PLogEventBegin(MAT_GetRow,mat,0,0,0);
79   ierr = (*mat->ops->getrow)(mat,row,ncols,cols,vals); CHKERRQ(ierr);
80   PLogEventEnd(MAT_GetRow,mat,0,0,0);
81   PetscFunctionReturn(0);
82 }
83 
84 #undef __FUNC__
85 #define __FUNC__ "MatRestoreRow"
86 /*@C
87    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
88 
89    Not Collective
90 
91    Input Parameters:
92 +  mat - the matrix
93 .  row - the row to get
94 .  ncols, cols - the number of nonzeros and their columns
95 -  vals - if nonzero the column values
96 
97    Notes:
98    This routine should be called after you have finished examining the entries.
99 
100    Fortran Notes:
101    The calling sequence from Fortran is
102 .vb
103    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
104       Mat     matrix (input)
105       integer row    (input)
106       integer ncols  (output)
107       integer cols(maxcols) (output)
108       double precision (or double complex) values(maxcols) output
109 .ve
110    Where maxcols >= maximum nonzeros in any row of the matrix.
111 
112    In Fortran MatRestoreRow() MUST be called after MatGetRow()
113    before another call to MatGetRow() can be made.
114 
115 .keywords: matrix, row, restore
116 
117 .seealso:  MatGetRow()
118 @*/
119 int MatRestoreRow(Mat mat,int row,int *ncols,int **cols,Scalar **vals)
120 {
121   int ierr;
122 
123   PetscFunctionBegin;
124   PetscValidHeaderSpecific(mat,MAT_COOKIE);
125   PetscValidIntPointer(ncols);
126   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
127   if (!mat->ops->restorerow) PetscFunctionReturn(0);
128   ierr = (*mat->ops->restorerow)(mat,row,ncols,cols,vals);CHKERRQ(ierr);
129   PetscFunctionReturn(0);
130 }
131 
132 #undef __FUNC__
133 #define __FUNC__ "MatView"
134 /*@C
135    MatView - Visualizes a matrix object.
136 
137    Collective on Mat unless Viewer is VIEWER_STDOUT_SELF
138 
139    Input Parameters:
140 +  mat - the matrix
141 -  ptr - visualization context
142 
143   Notes:
144   The available visualization contexts include
145 +    VIEWER_STDOUT_SELF - standard output (default)
146 .    VIEWER_STDOUT_WORLD - synchronized standard
147         output where only the first processor opens
148         the file.  All other processors send their
149         data to the first processor to print.
150 -     VIEWER_DRAW_WORLD - graphical display of nonzero structure
151 
152    The user can open alternative visualization contexts with
153 +    ViewerASCIIOpen() - Outputs matrix to a specified file
154 .    ViewerBinaryOpen() - Outputs matrix in binary to a
155          specified file; corresponding input uses MatLoad()
156 .    ViewerDrawOpen() - Outputs nonzero matrix structure to
157          an X window display
158 -    ViewerSocketOpen() - Outputs matrix to Socket viewer.
159          Currently only the sequential dense and AIJ
160          matrix types support the Socket viewer.
161 
162    The user can call ViewerSetFormat() to specify the output
163    format of ASCII printed objects (when using VIEWER_STDOUT_SELF,
164    VIEWER_STDOUT_WORLD and ViewerASCIIOpen).  Available formats include
165 +    VIEWER_FORMAT_ASCII_DEFAULT - default, prints matrix contents
166 .    VIEWER_FORMAT_ASCII_MATLAB - prints matrix contents in Matlab format
167 .    VIEWER_FORMAT_ASCII_DENSE - prints entire matrix including zeros
168 .    VIEWER_FORMAT_ASCII_COMMON - prints matrix contents, using a sparse
169          format common among all matrix types
170 .    VIEWER_FORMAT_ASCII_IMPL - prints matrix contents, using an implementation-specific
171          format (which is in many cases the same as the default)
172 .    VIEWER_FORMAT_ASCII_INFO - prints basic information about the matrix
173          size and structure (not the matrix entries)
174 -    VIEWER_FORMAT_ASCII_INFO_LONG - prints more detailed information about
175          the matrix structure
176 
177 .keywords: matrix, view, visualize, output, print, write, draw
178 
179 .seealso: ViewerSetFormat(), ViewerASCIIOpen(), ViewerDrawOpen(),
180           ViewerSocketOpen(), ViewerBinaryOpen(), MatLoad()
181 @*/
182 int MatView(Mat mat,Viewer viewer)
183 {
184   int          format, ierr, rows, cols;
185   char         *cstr;
186   ViewerType   vtype;
187 
188   PetscFunctionBegin;
189   PetscValidHeaderSpecific(mat,MAT_COOKIE);
190   if (viewer) PetscValidHeaderSpecific(viewer,VIEWER_COOKIE);
191   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
192 
193   if (!viewer) {
194     viewer = VIEWER_STDOUT_SELF;
195   }
196 
197   ierr = ViewerGetType(viewer,&vtype);
198   if (PetscTypeCompare(vtype,ASCII_VIEWER)) {
199     ierr = ViewerGetFormat(viewer,&format); CHKERRQ(ierr);
200     if (format == VIEWER_FORMAT_ASCII_INFO || format == VIEWER_FORMAT_ASCII_INFO_LONG) {
201       ViewerASCIIPrintf(viewer,"Matrix Object:\n");
202       ierr = MatGetType(mat,PETSC_NULL,&cstr); CHKERRQ(ierr);
203       ierr = MatGetSize(mat,&rows,&cols); CHKERRQ(ierr);
204       ViewerASCIIPrintf(viewer,"  type=%s, rows=%d, cols=%d\n",cstr,rows,cols);
205       if (mat->ops->getinfo) {
206         MatInfo info;
207         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info); CHKERRQ(ierr);
208         ViewerASCIIPrintf(viewer,"  total: nonzeros=%d, allocated nonzeros=%d\n",
209                           (int)info.nz_used,(int)info.nz_allocated);
210       }
211     }
212   }
213   if (mat->ops->view) {
214     ierr = ViewerASCIIPushTab(viewer);CHKERRQ(ierr);
215     ierr = (*mat->ops->view)(mat,viewer); CHKERRQ(ierr);
216     ierr = ViewerASCIIPopTab(viewer);CHKERRQ(ierr);
217   }
218   PetscFunctionReturn(0);
219 }
220 
221 #undef __FUNC__
222 #define __FUNC__ "MatScaleSystem"
223 /*@C
224    MatScaleSystem - Scale a vector solution and right hand side to
225      match the scaling of a scaled matrix.
226 
227    Collective on Mat
228 
229    Input Parameter:
230 +  mat - the matrix
231 .  x - solution vector (or PETSC_NULL)
232 +  b - right hand side vector (or PETSC_NULL)
233 
234 
235   Notes:
236     For AIJ, BAIJ, and BDiag matrices the matrices are not
237   internally scaled, so this does nothing. For MPIRowBS it
238   permutes and diagonally scales.
239 
240     The SLES methods automatically call this routine when required
241   (via PCPreSolve()) so it is rarely used directly.
242 
243   Level: Developer
244 
245 .keywords: matrix, scale
246 
247 .seealso: MatUseScaledForm(), MatUnScaleSystem()
248 @*/
249 int MatScaleSystem(Mat mat,Vec x,Vec b)
250 {
251   int ierr;
252 
253   PetscFunctionBegin;
254   PetscValidHeaderSpecific(mat,MAT_COOKIE);
255   if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE);}
256   if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE);}
257   if (mat->ops->scalesystem) {
258     ierr = (*mat->ops->scalesystem)(mat,x,b); CHKERRQ(ierr);
259   }
260   PetscFunctionReturn(0);
261 }
262 
263 #undef __FUNC__
264 #define __FUNC__ "MatUnScaleSystem"
265 /*@C
266    MatUnScaleSystem - Unscales a vector solution and right hand side to
267      match the original scaling of a scaled matrix.
268 
269    Collective on Mat
270 
271    Input Parameter:
272 +  mat - the matrix
273 .  x - solution vector (or PETSC_NULL)
274 +  b - right hand side vector (or PETSC_NULL)
275 
276 
277   Notes:
278     For AIJ, BAIJ, and BDiag matrices the matrices are not
279   internally scaled, so this does nothing. For MPIRowBS it
280   permutes and diagonally scales.
281 
282     The SLES methods automatically call this routine when required
283   (via PCPostSolve()) so it is rarely used directly.
284 
285   Level: Developer
286 
287 .keywords: matrix, scale
288 
289 .seealso: MatUseScaledForm(), MatScaleSystem()
290 @*/
291 int MatUnScaleSystem(Mat mat,Vec x,Vec b)
292 {
293   int ierr;
294 
295   PetscFunctionBegin;
296   PetscValidHeaderSpecific(mat,MAT_COOKIE);
297   if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE);}
298   if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE);}
299   if (mat->ops->unscalesystem) {
300     ierr = (*mat->ops->unscalesystem)(mat,x,b); CHKERRQ(ierr);
301   }
302   PetscFunctionReturn(0);
303 }
304 
305 #undef __FUNC__
306 #define __FUNC__ "MatUseScaledForm"
307 /*@C
308    MatUseScaledForm - For matrix storage formats that scale the
309      matrix (for example MPIRowbs matrices are diagonally scaled on
310      assembly) indicates matrix operations (MatMult() etc) are
311      applied using the scaled matrix.
312 
313    Collective on Mat
314 
315    Input Parameter:
316 +  mat - the matrix
317 -  scaled - PETSC_TRUE for applying the scaled, PETSC_FALSE for
318             applying the original matrix
319 
320   Notes:
321     For scaled formats applying the original, unscaled matrix
322    will be slightly more expensive
323 
324   Level: Developer
325 
326 .keywords: matrix, scale
327 
328 .seealso: MatScaleSystem(), MatUnScaleSystem()
329 @*/
330 int MatUseScaledForm(Mat mat,PetscTruth scaled)
331 {
332   int ierr;
333 
334   PetscFunctionBegin;
335   PetscValidHeaderSpecific(mat,MAT_COOKIE);
336   if (mat->ops->usescaledform) {
337     ierr = (*mat->ops->usescaledform)(mat,scaled); CHKERRQ(ierr);
338   }
339   PetscFunctionReturn(0);
340 }
341 
342 #undef __FUNC__
343 #define __FUNC__ "MatDestroy"
344 /*@C
345    MatDestroy - Frees space taken by a matrix.
346 
347    Collective on Mat
348 
349    Input Parameter:
350 .  mat - the matrix
351 
352 .keywords: matrix, destroy
353 @*/
354 int MatDestroy(Mat mat)
355 {
356   int ierr;
357 
358   PetscFunctionBegin;
359   PetscValidHeaderSpecific(mat,MAT_COOKIE);
360   ierr = (*mat->ops->destroy)(mat); CHKERRQ(ierr);
361   PetscFunctionReturn(0);
362 }
363 
364 #undef __FUNC__
365 #define __FUNC__ "MatValid"
366 /*@
367    MatValid - Checks whether a matrix object is valid.
368 
369    Collective on Mat
370 
371    Input Parameter:
372 .  m - the matrix to check
373 
374    Output Parameter:
375    flg - flag indicating matrix status, either
376    PETSC_TRUE if matrix is valid, or PETSC_FALSE otherwise.
377 
378 .keywords: matrix, valid
379 @*/
380 int MatValid(Mat m,PetscTruth *flg)
381 {
382   PetscFunctionBegin;
383   PetscValidIntPointer(flg);
384   if (!m)                           *flg = PETSC_FALSE;
385   else if (m->cookie != MAT_COOKIE) *flg = PETSC_FALSE;
386   else                              *flg = PETSC_TRUE;
387   PetscFunctionReturn(0);
388 }
389 
390 #undef __FUNC__
391 #define __FUNC__ "MatSetValues"
392 /*@
393    MatSetValues - Inserts or adds a block of values into a matrix.
394    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
395    MUST be called after all calls to MatSetValues() have been completed.
396 
397    Not Collective
398 
399    Input Parameters:
400 +  mat - the matrix
401 .  v - a logically two-dimensional array of values
402 .  m, idxm - the number of rows and their global indices
403 .  n, idxn - the number of columns and their global indices
404 -  addv - either ADD_VALUES or INSERT_VALUES, where
405    ADD_VALUES adds values to any existing entries, and
406    INSERT_VALUES replaces existing entries with new values
407 
408    Notes:
409    By default the values, v, are row-oriented and unsorted.
410    See MatSetOption() for other options.
411 
412    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
413    options cannot be mixed without intervening calls to the assembly
414    routines.
415 
416    MatSetValues() uses 0-based row and column numbers in Fortran
417    as well as in C.
418 
419    Negative indices may be passed in idxm and idxn, these rows and columns are
420    simply ignored. This allows easily inserting element stiffness matrices
421    with homogeneous Dirchlet boundary conditions that you don't want represented
422    in the matrix.
423 
424    Efficiency Alert:
425    The routine MatSetValuesBlocked() may offer much better efficiency
426    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
427 
428    Level: beginner
429 
430 .keywords: matrix, insert, add, set, values
431 
432 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
433 @*/
434 int MatSetValues(Mat mat,int m,int *idxm,int n,int *idxn,Scalar *v,InsertMode addv)
435 {
436   int ierr;
437 
438   PetscFunctionBegin;
439   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
440   PetscValidHeaderSpecific(mat,MAT_COOKIE);
441   PetscValidIntPointer(idxm);
442   PetscValidIntPointer(idxn);
443   PetscValidScalarPointer(v);
444   if (mat->insertmode == NOT_SET_VALUES) {
445     mat->insertmode = addv;
446   }
447 #if defined(USE_PETSC_BOPT_g)
448   else if (mat->insertmode != addv) {
449     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,1,"Cannot mix add values and insert values");
450   }
451   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
452 #endif
453 
454   if (mat->assembled) {
455     mat->was_assembled = PETSC_TRUE;
456     mat->assembled     = PETSC_FALSE;
457   }
458   PLogEventBegin(MAT_SetValues,mat,0,0,0);
459   if (!mat->ops->setvalues) SETERRQ(PETSC_ERR_SUP,1,"Not supported for this matrix type");
460   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
461   PLogEventEnd(MAT_SetValues,mat,0,0,0);
462   PetscFunctionReturn(0);
463 }
464 
465 #undef __FUNC__
466 #define __FUNC__ "MatSetValuesBlocked"
467 /*@
468    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
469 
470    Not Collective
471 
472    Input Parameters:
473 +  mat - the matrix
474 .  v - a logically two-dimensional array of values
475 .  m, idxm - the number of block rows and their global block indices
476 .  n, idxn - the number of block columns and their global block indices
477 -  addv - either ADD_VALUES or INSERT_VALUES, where
478    ADD_VALUES adds values to any existing entries, and
479    INSERT_VALUES replaces existing entries with new values
480 
481    Notes:
482    By default the values, v, are row-oriented and unsorted. So the layout of
483    v is the same as for MatSetValues(). See MatSetOption() for other options.
484 
485    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
486    options cannot be mixed without intervening calls to the assembly
487    routines.
488 
489    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
490    as well as in C.
491 
492    Negative indices may be passed in idxm and idxn, these rows and columns are
493    simply ignored. This allows easily inserting element stiffness matrices
494    with homogeneous Dirchlet boundary conditions that you don't want represented
495    in the matrix.
496 
497    Each time an entry is set within a sparse matrix via MatSetValues(),
498    internal searching must be done to determine where to place the the
499    data in the matrix storage space.  By instead inserting blocks of
500    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
501    reduced.
502 
503    Restrictions:
504    MatSetValuesBlocked() is currently supported only for the block AIJ
505    matrix format (MATSEQBAIJ and MATMPIBAIJ, which are created via
506    MatCreateSeqBAIJ() and MatCreateMPIBAIJ()).
507 
508 .keywords: matrix, insert, add, set, values
509 
510 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
511 @*/
512 int MatSetValuesBlocked(Mat mat,int m,int *idxm,int n,int *idxn,Scalar *v,InsertMode addv)
513 {
514   int ierr;
515 
516   PetscFunctionBegin;
517   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
518   PetscValidHeaderSpecific(mat,MAT_COOKIE);
519   PetscValidIntPointer(idxm);
520   PetscValidIntPointer(idxn);
521   PetscValidScalarPointer(v);
522   if (mat->insertmode == NOT_SET_VALUES) {
523     mat->insertmode = addv;
524   }
525 #if defined(USE_PETSC_BOPT_g)
526   else if (mat->insertmode != addv) {
527     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,1,"Cannot mix add values and insert values");
528   }
529   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
530 #endif
531 
532   if (mat->assembled) {
533     mat->was_assembled = PETSC_TRUE;
534     mat->assembled     = PETSC_FALSE;
535   }
536   PLogEventBegin(MAT_SetValues,mat,0,0,0);
537   if (!mat->ops->setvaluesblocked) SETERRQ(PETSC_ERR_SUP,1,"Not supported for this matrix type");
538   ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
539   PLogEventEnd(MAT_SetValues,mat,0,0,0);
540   PetscFunctionReturn(0);
541 }
542 
543 /*MC
544    MatSetValue - Set a single entry into a matrix.
545 
546    Synopsis:
547    void MatSetValue(Mat m,int row,int col,Scalar value,InsertMode mode);
548 
549    Not collective
550 
551    Input Parameters:
552 +  m - the matrix
553 .  row - the row location of the entry
554 .  col - the column location of the entry
555 .  value - the value to insert
556 -  mode - either INSERT_VALUES or ADD_VALUES
557 
558    Notes:
559    For efficiency one should use MatSetValues() and set several or many
560    values simultaneously if possible.
561 
562    Note that VecSetValue() does NOT return an error code (since this
563    is checked internally).
564 
565 .seealso: MatSetValues()
566 M*/
567 
568 #undef __FUNC__
569 #define __FUNC__ "MatGetValues"
570 /*@
571    MatGetValues - Gets a block of values from a matrix.
572 
573    Not Collective; currently only returns a local block
574 
575    Input Parameters:
576 +  mat - the matrix
577 .  v - a logically two-dimensional array for storing the values
578 .  m, idxm - the number of rows and their global indices
579 -  n, idxn - the number of columns and their global indices
580 
581    Notes:
582    The user must allocate space (m*n Scalars) for the values, v.
583    The values, v, are then returned in a row-oriented format,
584    analogous to that used by default in MatSetValues().
585 
586    MatGetValues() uses 0-based row and column numbers in
587    Fortran as well as in C.
588 
589    MatGetValues() requires that the matrix has been assembled
590    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
591    MatSetValues() and MatGetValues() CANNOT be made in succession
592    without intermediate matrix assembly.
593 
594 .keywords: matrix, get, values
595 
596 .seealso: MatGetRow(), MatGetSubmatrices(), MatSetValues()
597 @*/
598 int MatGetValues(Mat mat,int m,int *idxm,int n,int *idxn,Scalar *v)
599 {
600   int ierr;
601 
602   PetscFunctionBegin;
603   PetscValidHeaderSpecific(mat,MAT_COOKIE);
604   PetscValidIntPointer(idxm);
605   PetscValidIntPointer(idxn);
606   PetscValidScalarPointer(v);
607   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
608   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
609   if (!mat->ops->getvalues) SETERRQ(PETSC_ERR_SUP,0,"");
610 
611   PLogEventBegin(MAT_GetValues,mat,0,0,0);
612   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v); CHKERRQ(ierr);
613   PLogEventEnd(MAT_GetValues,mat,0,0,0);
614   PetscFunctionReturn(0);
615 }
616 
617 #undef __FUNC__
618 #define __FUNC__ "MatSetLocalToGlobalMapping"
619 /*@
620    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
621    the routine MatSetValuesLocal() to allow users to insert matrix entries
622    using a local (per-processor) numbering.
623 
624    Not Collective
625 
626    Input Parameters:
627 +  x - the matrix
628 -  mapping - mapping created with ISLocalToGlobalMappingCreate()
629              or ISLocalToGlobalMappingCreateIS()
630 
631 .keywords: matrix, set, values, local, global, mapping
632 
633 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
634 @*/
635 int MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping mapping)
636 {
637   PetscFunctionBegin;
638   PetscValidHeaderSpecific(x,MAT_COOKIE);
639   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE);
640 
641   if (x->mapping) {
642     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Mapping already set for matrix");
643   }
644 
645   x->mapping = mapping;
646   PetscObjectReference((PetscObject)mapping);
647   PetscFunctionReturn(0);
648 }
649 
650 #undef __FUNC__
651 #define __FUNC__ "MatSetLocalToGlobalMappingBlocked"
652 /*@
653    MatSetLocalToGlobalMappingBlocked - Sets a local-to-global numbering for use
654    by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
655    entries using a local (per-processor) numbering.
656 
657    Not Collective
658 
659    Input Parameters:
660 +  x - the matrix
661 -  mapping - mapping created with ISLocalToGlobalMappingCreate() or
662              ISLocalToGlobalMappingCreateIS()
663 
664 .keywords: matrix, set, values, local ordering
665 
666 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
667            MatSetValuesBlocked(), MatSetValuesLocal()
668 @*/
669 int MatSetLocalToGlobalMappingBlocked(Mat x,ISLocalToGlobalMapping mapping)
670 {
671   PetscFunctionBegin;
672   PetscValidHeaderSpecific(x,MAT_COOKIE);
673   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE);
674 
675   if (x->bmapping) {
676     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Mapping already set for matrix");
677   }
678 
679   x->bmapping = mapping;
680   PetscObjectReference((PetscObject)mapping);
681   PetscFunctionReturn(0);
682 }
683 
684 #undef __FUNC__
685 #define __FUNC__ "MatSetValuesLocal"
686 /*@
687    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
688    using a local ordering of the nodes.
689 
690    Not Collective
691 
692    Input Parameters:
693 +  x - the matrix
694 .  nrow, irow - number of rows and their local indices
695 .  ncol, icol - number of columns and their local indices
696 .  y -  a logically two-dimensional array of values
697 -  addv - either INSERT_VALUES or ADD_VALUES, where
698    ADD_VALUES adds values to any existing entries, and
699    INSERT_VALUES replaces existing entries with new values
700 
701    Notes:
702    Before calling MatSetValuesLocal(), the user must first set the
703    local-to-global mapping by calling MatSetLocalToGlobalMapping().
704 
705    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
706    options cannot be mixed without intervening calls to the assembly
707    routines.
708 
709    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
710    MUST be called after all calls to MatSetValuesLocal() have been completed.
711 
712 .keywords: matrix, set, values, local ordering
713 
714 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping()
715 @*/
716 int MatSetValuesLocal(Mat mat,int nrow,int *irow,int ncol, int *icol,Scalar *y,InsertMode addv)
717 {
718   int ierr,irowm[2048],icolm[2048];
719 
720   PetscFunctionBegin;
721   PetscValidHeaderSpecific(mat,MAT_COOKIE);
722   PetscValidIntPointer(irow);
723   PetscValidIntPointer(icol);
724   PetscValidScalarPointer(y);
725 
726   if (mat->insertmode == NOT_SET_VALUES) {
727     mat->insertmode = addv;
728   }
729 #if defined(USE_PETSC_BOPT_g)
730   else if (mat->insertmode != addv) {
731     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,1,"Cannot mix add values and insert values");
732   }
733   if (!mat->mapping) {
734     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Local to global never set with MatSetLocalToGlobalMapping()");
735   }
736   if (nrow > 2048 || ncol > 2048) {
737     SETERRQ2(PETSC_ERR_SUP,0,"Number column/row indices must be <= 2048: are %d %d",nrow,ncol);
738   }
739   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
740 #endif
741 
742   if (mat->assembled) {
743     mat->was_assembled = PETSC_TRUE;
744     mat->assembled     = PETSC_FALSE;
745   }
746   PLogEventBegin(MAT_SetValues,mat,0,0,0);
747   ierr = ISLocalToGlobalMappingApply(mat->mapping,nrow,irow,irowm); CHKERRQ(ierr);
748   ierr = ISLocalToGlobalMappingApply(mat->mapping,ncol,icol,icolm);CHKERRQ(ierr);
749   ierr = (*mat->ops->setvalues)(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
750   PLogEventEnd(MAT_SetValues,mat,0,0,0);
751   PetscFunctionReturn(0);
752 }
753 
754 #undef __FUNC__
755 #define __FUNC__ "MatSetValuesBlockedLocal"
756 /*@
757    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
758    using a local ordering of the nodes a block at a time.
759 
760    Not Collective
761 
762    Input Parameters:
763 +  x - the matrix
764 .  nrow, irow - number of rows and their local indices
765 .  ncol, icol - number of columns and their local indices
766 .  y -  a logically two-dimensional array of values
767 -  addv - either INSERT_VALUES or ADD_VALUES, where
768    ADD_VALUES adds values to any existing entries, and
769    INSERT_VALUES replaces existing entries with new values
770 
771    Notes:
772    Before calling MatSetValuesBlockedLocal(), the user must first set the
773    local-to-global mapping by calling MatSetLocalToGlobalMappingBlocked(),
774    where the mapping MUST be set for matrix blocks, not for matrix elements.
775 
776    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
777    options cannot be mixed without intervening calls to the assembly
778    routines.
779 
780    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
781    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
782 
783 .keywords: matrix, set, values, blocked, local
784 
785 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesLocal(), MatSetLocalToGlobalMappingBlocked(), MatSetValuesBlocked()
786 @*/
787 int MatSetValuesBlockedLocal(Mat mat,int nrow,int *irow,int ncol,int *icol,Scalar *y,InsertMode addv)
788 {
789   int ierr,irowm[2048],icolm[2048];
790 
791   PetscFunctionBegin;
792   PetscValidHeaderSpecific(mat,MAT_COOKIE);
793   PetscValidIntPointer(irow);
794   PetscValidIntPointer(icol);
795   PetscValidScalarPointer(y);
796   if (mat->insertmode == NOT_SET_VALUES) {
797     mat->insertmode = addv;
798   }
799 #if defined(USE_PETSC_BOPT_g)
800   else if (mat->insertmode != addv) {
801     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,1,"Cannot mix add values and insert values");
802   }
803   if (!mat->bmapping) {
804     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Local to global never set with MatSetLocalToGlobalMappingBlocked()");
805   }
806   if (nrow > 2048 || ncol > 2048) {
807     SETERRQ2(PETSC_ERR_SUP,0,"Number column/row indices must be <= 2048: are %d %d",nrow,ncol);
808   }
809   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
810 #endif
811 
812   if (mat->assembled) {
813     mat->was_assembled = PETSC_TRUE;
814     mat->assembled     = PETSC_FALSE;
815   }
816   PLogEventBegin(MAT_SetValues,mat,0,0,0);
817   ierr = ISLocalToGlobalMappingApply(mat->bmapping,nrow,irow,irowm); CHKERRQ(ierr);
818   ierr = ISLocalToGlobalMappingApply(mat->bmapping,ncol,icol,icolm); CHKERRQ(ierr);
819   ierr = (*mat->ops->setvaluesblocked)(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
820   PLogEventEnd(MAT_SetValues,mat,0,0,0);
821   PetscFunctionReturn(0);
822 }
823 
824 /* --------------------------------------------------------*/
825 #undef __FUNC__
826 #define __FUNC__ "MatMult"
827 /*@
828    MatMult - Computes the matrix-vector product, y = Ax.
829 
830    Collective on Mat and Vec
831 
832    Input Parameters:
833 +  mat - the matrix
834 -  x   - the vector to be multilplied
835 
836    Output Parameters:
837 .  y - the result
838 
839    Notes:
840    The vectors x and y cannot be the same.  I.e., one cannot
841    call MatMult(A,y,y).
842 
843 .keywords: matrix, multiply, matrix-vector product
844 
845 .seealso: MatMultTrans(), MatMultAdd(), MatMultTransAdd()
846 @*/
847 int MatMult(Mat mat,Vec x,Vec y)
848 {
849   int ierr;
850 
851   PetscFunctionBegin;
852   PetscValidHeaderSpecific(mat,MAT_COOKIE);
853   PetscValidHeaderSpecific(x,VEC_COOKIE);PetscValidHeaderSpecific(y,VEC_COOKIE);
854   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
855   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
856   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"x and y must be different vectors");
857   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
858   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
859   if (mat->m != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec y: local dim %d %d",mat->m,y->n);
860 
861   PLogEventBegin(MAT_Mult,mat,x,y,0);
862   ierr = (*mat->ops->mult)(mat,x,y); CHKERRQ(ierr);
863   PLogEventEnd(MAT_Mult,mat,x,y,0);
864 
865   PetscFunctionReturn(0);
866 }
867 
868 #undef __FUNC__
869 #define __FUNC__ "MatMultTrans"
870 /*@
871    MatMultTrans - Computes matrix transpose times a vector.
872 
873    Collective on Mat and Vec
874 
875    Input Parameters:
876 +  mat - the matrix
877 -  x   - the vector to be multilplied
878 
879    Output Parameters:
880 .  y - the result
881 
882    Notes:
883    The vectors x and y cannot be the same.  I.e., one cannot
884    call MatMultTrans(A,y,y).
885 
886 .keywords: matrix, multiply, matrix-vector product, transpose
887 
888 .seealso: MatMult(), MatMultAdd(), MatMultTransAdd()
889 @*/
890 int MatMultTrans(Mat mat,Vec x,Vec y)
891 {
892   int ierr;
893 
894   PetscFunctionBegin;
895   PetscValidHeaderSpecific(mat,MAT_COOKIE);
896   PetscValidHeaderSpecific(x,VEC_COOKIE); PetscValidHeaderSpecific(y,VEC_COOKIE);
897   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
898   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
899   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"x and y must be different vectors");
900   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
901   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec y: global dim %d %d",mat->N,y->N);
902   PLogEventBegin(MAT_MultTrans,mat,x,y,0);
903   ierr = (*mat->ops->multtrans)(mat,x,y); CHKERRQ(ierr);
904   PLogEventEnd(MAT_MultTrans,mat,x,y,0);
905   PetscFunctionReturn(0);
906 }
907 
908 #undef __FUNC__
909 #define __FUNC__ "MatMultAdd"
910 /*@
911     MatMultAdd -  Computes v3 = v2 + A * v1.
912 
913     Collective on Mat and Vec
914 
915     Input Parameters:
916 +   mat - the matrix
917 -   v1, v2 - the vectors
918 
919     Output Parameters:
920 .   v3 - the result
921 
922    Notes:
923    The vectors v1 and v3 cannot be the same.  I.e., one cannot
924    call MatMultAdd(A,v1,v2,v1).
925 
926 .keywords: matrix, multiply, matrix-vector product, add
927 
928 .seealso: MatMultTrans(), MatMult(), MatMultTransAdd()
929 @*/
930 int MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
931 {
932   int ierr;
933 
934   PetscFunctionBegin;
935   PetscValidHeaderSpecific(mat,MAT_COOKIE);PetscValidHeaderSpecific(v1,VEC_COOKIE);
936   PetscValidHeaderSpecific(v2,VEC_COOKIE); PetscValidHeaderSpecific(v3,VEC_COOKIE);
937   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
938   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
939   if (mat->N != v1->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v1: global dim %d %d",mat->N,v1->N);
940   if (mat->M != v2->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v2: global dim %d %d",mat->M,v2->N);
941   if (mat->M != v3->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v3: global dim %d %d",mat->M,v3->N);
942   if (mat->m != v3->n) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v3: local dim %d %d",mat->m,v3->n);
943   if (mat->m != v2->n) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v2: local dim %d %d",mat->m,v2->n);
944   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,0,"v1 and v3 must be different vectors");
945 
946   PLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
947   ierr = (*mat->ops->multadd)(mat,v1,v2,v3); CHKERRQ(ierr);
948   PLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
949   PetscFunctionReturn(0);
950 }
951 
952 #undef __FUNC__
953 #define __FUNC__ "MatMultTransAdd"
954 /*@
955    MatMultTransAdd - Computes v3 = v2 + A' * v1.
956 
957    Collective on Mat and Vec
958 
959    Input Parameters:
960 +  mat - the matrix
961 -  v1, v2 - the vectors
962 
963    Output Parameters:
964 .  v3 - the result
965 
966    Notes:
967    The vectors v1 and v3 cannot be the same.  I.e., one cannot
968    call MatMultTransAdd(A,v1,v2,v1).
969 
970 .keywords: matrix, multiply, matrix-vector product, transpose, add
971 
972 .seealso: MatMultTrans(), MatMultAdd(), MatMult()
973 @*/
974 int MatMultTransAdd(Mat mat,Vec v1,Vec v2,Vec v3)
975 {
976   int ierr;
977 
978   PetscFunctionBegin;
979   PetscValidHeaderSpecific(mat,MAT_COOKIE);PetscValidHeaderSpecific(v1,VEC_COOKIE);
980   PetscValidHeaderSpecific(v2,VEC_COOKIE);PetscValidHeaderSpecific(v3,VEC_COOKIE);
981   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
982   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
983   if (!mat->ops->multtransadd) SETERRQ(PETSC_ERR_SUP,0,"");
984   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,0,"v1 and v3 must be different vectors");
985   if (mat->M != v1->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v1: global dim %d %d",mat->M,v1->N);
986   if (mat->N != v2->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v2: global dim %d %d",mat->N,v2->N);
987   if (mat->N != v3->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v3: global dim %d %d",mat->N,v3->N);
988 
989   PLogEventBegin(MAT_MultTransAdd,mat,v1,v2,v3);
990   ierr = (*mat->ops->multtransadd)(mat,v1,v2,v3); CHKERRQ(ierr);
991   PLogEventEnd(MAT_MultTransAdd,mat,v1,v2,v3);
992   PetscFunctionReturn(0);
993 }
994 /* ------------------------------------------------------------*/
995 #undef __FUNC__
996 #define __FUNC__ "MatGetInfo"
997 /*@C
998    MatGetInfo - Returns information about matrix storage (number of
999    nonzeros, memory, etc.).
1000 
1001    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used
1002    as the flag
1003 
1004    Input Parameters:
1005 .  mat - the matrix
1006 
1007    Output Parameters:
1008 +  flag - flag indicating the type of parameters to be returned
1009    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
1010    MAT_GLOBAL_SUM - sum over all processors)
1011 -  info - matrix information context
1012 
1013    Notes:
1014    The MatInfo context contains a variety of matrix data, including
1015    number of nonzeros allocated and used, number of mallocs during
1016    matrix assembly, etc.  Additional information for factored matrices
1017    is provided (such as the fill ratio, number of mallocs during
1018    factorization, etc.).  Much of this info is printed to STDOUT
1019    when using the runtime options
1020 $       -log_info -mat_view_info
1021 
1022    Example for C/C++ Users:
1023    See the file ${PETSC_DIR}/include/mat.h for a complete list of
1024    data within the MatInfo context.  For example,
1025 .vb
1026       MatInfo info;
1027       Mat     A;
1028       double  mal, nz_a, nz_u;
1029 
1030       MatGetInfo(A,MAT_LOCAL,&info);
1031       mal  = info.mallocs;
1032       nz_a = info.nz_allocated;
1033 .ve
1034 
1035    Example for Fortran Users:
1036    Fortran users should declare info as a double precision
1037    array of dimension MAT_INFO_SIZE, and then extract the parameters
1038    of interest.  See the file ${PETSC_DIR}/include/finclude/mat.h
1039    a complete list of parameter names.
1040 .vb
1041       double  precision info(MAT_INFO_SIZE)
1042       double  precision mal, nz_a
1043       Mat     A
1044       integer ierr
1045 
1046       call MatGetInfo(A,MAT_LOCAL,info,ierr)
1047       mal = info(MAT_INFO_MALLOCS)
1048       nz_a = info(MAT_INFO_NZ_ALLOCATED)
1049 .ve
1050 
1051 .keywords: matrix, get, info, storage, nonzeros, memory, fill
1052 @*/
1053 int MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
1054 {
1055   int ierr;
1056 
1057   PetscFunctionBegin;
1058   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1059   PetscValidPointer(info);
1060   if (!mat->ops->getinfo) SETERRQ(PETSC_ERR_SUP,0,"");
1061   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
1062   PetscFunctionReturn(0);
1063 }
1064 
1065 /* ----------------------------------------------------------*/
1066 #undef __FUNC__
1067 #define __FUNC__ "MatILUDTFactor"
1068 /*@
1069    MatILUDTFactor - Performs a drop tolerance ILU factorization.
1070 
1071    Collective on Mat
1072 
1073    Input Parameters:
1074 +  mat - the matrix
1075 .  dt  - the drop tolerance
1076 .  maxnz - the maximum number of nonzeros per row allowed?
1077 .  row - row permutation
1078 -  col - column permutation
1079 
1080    Output Parameters:
1081 .  fact - the factored matrix
1082 
1083 .keywords: matrix, factor, LU, in-place
1084 
1085 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
1086 @*/
1087 int MatILUDTFactor(Mat mat,double dt,int maxnz,IS row,IS col,Mat *fact)
1088 {
1089   int ierr;
1090 
1091   PetscFunctionBegin;
1092   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1093   PetscValidPointer(fact);
1094   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1095   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
1096   if (!mat->ops->iludtfactor) SETERRQ(PETSC_ERR_SUP,0,"");
1097 
1098   PLogEventBegin(MAT_ILUFactor,mat,row,col,0);
1099   ierr = (*mat->ops->iludtfactor)(mat,dt,maxnz,row,col,fact); CHKERRQ(ierr);
1100   PLogEventEnd(MAT_ILUFactor,mat,row,col,0);
1101 
1102   PetscFunctionReturn(0);
1103 }
1104 
1105 #undef __FUNC__
1106 #define __FUNC__ "MatLUFactor"
1107 /*@
1108    MatLUFactor - Performs in-place LU factorization of matrix.
1109 
1110    Collective on Mat
1111 
1112    Input Parameters:
1113 +  mat - the matrix
1114 .  row - row permutation
1115 .  col - column permutation
1116 -  f - expected fill as ratio of original fill.
1117 
1118 .keywords: matrix, factor, LU, in-place
1119 
1120 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
1121 @*/
1122 int MatLUFactor(Mat mat,IS row,IS col,double f)
1123 {
1124   int ierr;
1125 
1126   PetscFunctionBegin;
1127   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1128   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,0,"matrix must be square");
1129   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1130   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
1131   if (!mat->ops->lufactor) SETERRQ(PETSC_ERR_SUP,0,"");
1132 
1133   PLogEventBegin(MAT_LUFactor,mat,row,col,0);
1134   ierr = (*mat->ops->lufactor)(mat,row,col,f); CHKERRQ(ierr);
1135   PLogEventEnd(MAT_LUFactor,mat,row,col,0);
1136   PetscFunctionReturn(0);
1137 }
1138 
1139 #undef __FUNC__
1140 #define __FUNC__ "MatILUFactor"
1141 /*@
1142    MatILUFactor - Performs in-place ILU factorization of matrix.
1143 
1144    Collective on Mat
1145 
1146    Input Parameters:
1147 +  mat - the matrix
1148 .  row - row permutation
1149 .  col - column permutation
1150 -  info - structure containing
1151 $      levels - number of levels of fill.
1152 $      expected fill - as ratio of original fill.
1153 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
1154                 missing diagonal entries)
1155 
1156    Notes:
1157    Probably really in-place only when level of fill is zero, otherwise allocates
1158    new space to store factored matrix and deletes previous memory.
1159 
1160 .keywords: matrix, factor, ILU, in-place
1161 
1162 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
1163 @*/
1164 int MatILUFactor(Mat mat,IS row,IS col,MatILUInfo *info)
1165 {
1166   int ierr;
1167 
1168   PetscFunctionBegin;
1169   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1170   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,0,"matrix must be square");
1171   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1172   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
1173   if (!mat->ops->ilufactor) SETERRQ(PETSC_ERR_SUP,0,"");
1174 
1175   PLogEventBegin(MAT_ILUFactor,mat,row,col,0);
1176   ierr = (*mat->ops->ilufactor)(mat,row,col,info); CHKERRQ(ierr);
1177   PLogEventEnd(MAT_ILUFactor,mat,row,col,0);
1178   PetscFunctionReturn(0);
1179 }
1180 
1181 #undef __FUNC__
1182 #define __FUNC__ "MatLUFactorSymbolic"
1183 /*@
1184    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
1185    Call this routine before calling MatLUFactorNumeric().
1186 
1187    Collective on Mat
1188 
1189    Input Parameters:
1190 +  mat - the matrix
1191 .  row, col - row and column permutations
1192 -  f - expected fill as ratio of the original number of nonzeros,
1193        for example 3.0; choosing this parameter well can result in
1194        more efficient use of time and space. Run with the option -log_info
1195        to determine an optimal value to use
1196 
1197    Output Parameter:
1198 .  fact - new matrix that has been symbolically factored
1199 
1200    Notes:
1201    See the file ${PETSC_DIR}/Performance for additional information about
1202    choosing the fill factor for better efficiency.
1203 
1204 .keywords: matrix, factor, LU, symbolic, fill
1205 
1206 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor()
1207 @*/
1208 int MatLUFactorSymbolic(Mat mat,IS row,IS col,double f,Mat *fact)
1209 {
1210   int ierr;
1211 
1212   PetscFunctionBegin;
1213   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1214   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,0,"matrix must be square");
1215   PetscValidPointer(fact);
1216   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1217   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
1218   if (!mat->ops->lufactorsymbolic) SETERRQ(PETSC_ERR_SUP,0,"");
1219 
1220   PLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
1221   ierr = (*mat->ops->lufactorsymbolic)(mat,row,col,f,fact); CHKERRQ(ierr);
1222   PLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
1223   PetscFunctionReturn(0);
1224 }
1225 
1226 #undef __FUNC__
1227 #define __FUNC__ "MatLUFactorNumeric"
1228 /*@
1229    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
1230    Call this routine after first calling MatLUFactorSymbolic().
1231 
1232    Collective on Mat
1233 
1234    Input Parameters:
1235 +  mat - the matrix
1236 -  row, col - row and  column permutations
1237 
1238    Output Parameters:
1239 .  fact - symbolically factored matrix that must have been generated
1240           by MatLUFactorSymbolic()
1241 
1242    Notes:
1243    See MatLUFactor() for in-place factorization.  See
1244    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
1245 
1246 .keywords: matrix, factor, LU, numeric
1247 
1248 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
1249 @*/
1250 int MatLUFactorNumeric(Mat mat,Mat *fact)
1251 {
1252   int ierr,flg;
1253 
1254   PetscFunctionBegin;
1255   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1256   PetscValidPointer(fact);
1257   PetscValidHeaderSpecific(*fact,MAT_COOKIE);
1258   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1259   if (mat->M != (*fact)->M || mat->N != (*fact)->N) {
1260     SETERRQ4(PETSC_ERR_ARG_SIZ,0,"Mat mat,Mat *fact: global dimensions are different %d should = %d %d should = %d",
1261             mat->M,(*fact)->M,mat->N,(*fact)->N);
1262   }
1263   if (!(*fact)->ops->lufactornumeric) SETERRQ(PETSC_ERR_SUP,0,"");
1264 
1265   PLogEventBegin(MAT_LUFactorNumeric,mat,*fact,0,0);
1266   ierr = (*(*fact)->ops->lufactornumeric)(mat,fact); CHKERRQ(ierr);
1267   PLogEventEnd(MAT_LUFactorNumeric,mat,*fact,0,0);
1268   ierr = OptionsHasName(PETSC_NULL,"-mat_view_draw",&flg); CHKERRQ(ierr);
1269   if (flg) {
1270     ierr = OptionsHasName(0,"-mat_view_contour",&flg); CHKERRQ(ierr);
1271     if (flg) {
1272       ViewerPushFormat(VIEWER_DRAW_(mat->comm),VIEWER_FORMAT_DRAW_CONTOUR,0);CHKERRQ(ierr);
1273     }
1274     ierr = MatView(*fact,VIEWER_DRAW_(mat->comm)); CHKERRQ(ierr);
1275     ierr = ViewerFlush(VIEWER_DRAW_(mat->comm)); CHKERRQ(ierr);
1276     if (flg) {
1277       ViewerPopFormat(VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
1278     }
1279   }
1280   PetscFunctionReturn(0);
1281 }
1282 
1283 #undef __FUNC__
1284 #define __FUNC__ "MatCholeskyFactor"
1285 /*@
1286    MatCholeskyFactor - Performs in-place Cholesky factorization of a
1287    symmetric matrix.
1288 
1289    Collective on Mat
1290 
1291    Input Parameters:
1292 +  mat - the matrix
1293 .  perm - row and column permutations
1294 -  f - expected fill as ratio of original fill
1295 
1296    Notes:
1297    See MatLUFactor() for the nonsymmetric case.  See also
1298    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
1299 
1300 .keywords: matrix, factor, in-place, Cholesky
1301 
1302 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
1303 @*/
1304 int MatCholeskyFactor(Mat mat,IS perm,double f)
1305 {
1306   int ierr;
1307 
1308   PetscFunctionBegin;
1309   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1310   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,0,"Matrix must be square");
1311   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1312   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
1313   if (!mat->ops->choleskyfactor) SETERRQ(PETSC_ERR_SUP,0,"");
1314 
1315   PLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
1316   ierr = (*mat->ops->choleskyfactor)(mat,perm,f); CHKERRQ(ierr);
1317   PLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
1318   PetscFunctionReturn(0);
1319 }
1320 
1321 #undef __FUNC__
1322 #define __FUNC__ "MatCholeskyFactorSymbolic"
1323 /*@
1324    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
1325    of a symmetric matrix.
1326 
1327    Collective on Mat
1328 
1329    Input Parameters:
1330 +  mat - the matrix
1331 .  perm - row and column permutations
1332 -  f - expected fill as ratio of original
1333 
1334    Output Parameter:
1335 .  fact - the factored matrix
1336 
1337    Notes:
1338    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
1339    MatCholeskyFactor() and MatCholeskyFactorNumeric().
1340 
1341 .keywords: matrix, factor, factorization, symbolic, Cholesky
1342 
1343 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
1344 @*/
1345 int MatCholeskyFactorSymbolic(Mat mat,IS perm,double f,Mat *fact)
1346 {
1347   int ierr;
1348 
1349   PetscFunctionBegin;
1350   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1351   PetscValidPointer(fact);
1352   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,0,"Matrix must be square");
1353   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1354   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
1355   if (!mat->ops->choleskyfactorsymbolic) SETERRQ(PETSC_ERR_SUP,0,"");
1356 
1357   PLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
1358   ierr = (*mat->ops->choleskyfactorsymbolic)(mat,perm,f,fact); CHKERRQ(ierr);
1359   PLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
1360   PetscFunctionReturn(0);
1361 }
1362 
1363 #undef __FUNC__
1364 #define __FUNC__ "MatCholeskyFactorNumeric"
1365 /*@
1366    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
1367    of a symmetric matrix. Call this routine after first calling
1368    MatCholeskyFactorSymbolic().
1369 
1370    Collective on Mat
1371 
1372    Input Parameter:
1373 .  mat - the initial matrix
1374 
1375    Output Parameter:
1376 .  fact - the factored matrix
1377 
1378 .keywords: matrix, factor, numeric, Cholesky
1379 
1380 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
1381 @*/
1382 int MatCholeskyFactorNumeric(Mat mat,Mat *fact)
1383 {
1384   int ierr;
1385 
1386   PetscFunctionBegin;
1387   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1388   PetscValidPointer(fact);
1389   if (!mat->ops->choleskyfactornumeric) SETERRQ(PETSC_ERR_SUP,0,"");
1390   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1391   if (mat->M != (*fact)->M || mat->N != (*fact)->N) {
1392     SETERRQ4(PETSC_ERR_ARG_SIZ,0,"Mat mat,Mat *fact: global dim %d should = %d %d should = %d",
1393             mat->M,(*fact)->M,mat->N,(*fact)->N);
1394   }
1395 
1396   PLogEventBegin(MAT_CholeskyFactorNumeric,mat,*fact,0,0);
1397   ierr = (*mat->ops->choleskyfactornumeric)(mat,fact); CHKERRQ(ierr);
1398   PLogEventEnd(MAT_CholeskyFactorNumeric,mat,*fact,0,0);
1399   PetscFunctionReturn(0);
1400 }
1401 
1402 /* ----------------------------------------------------------------*/
1403 #undef __FUNC__
1404 #define __FUNC__ "MatSolve"
1405 /*@
1406    MatSolve - Solves A x = b, given a factored matrix.
1407 
1408    Collective on Mat and Vec
1409 
1410    Input Parameters:
1411 +  mat - the factored matrix
1412 -  b - the right-hand-side vector
1413 
1414    Output Parameter:
1415 .  x - the result vector
1416 
1417    Notes:
1418    The vectors b and x cannot be the same.  I.e., one cannot
1419    call MatSolve(A,x,x).
1420 
1421 .keywords: matrix, linear system, solve, LU, Cholesky, triangular solve
1422 
1423 .seealso: MatSolveAdd(), MatSolveTrans(), MatSolveTransAdd()
1424 @*/
1425 int MatSolve(Mat mat,Vec b,Vec x)
1426 {
1427   int ierr;
1428 
1429   PetscFunctionBegin;
1430   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1431   PetscValidHeaderSpecific(b,VEC_COOKIE); PetscValidHeaderSpecific(x,VEC_COOKIE);
1432   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,0,"x and b must be different vectors");
1433   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Unfactored matrix");
1434   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1435   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
1436   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
1437   if (mat->M == 0 && mat->N == 0) PetscFunctionReturn(0);
1438 
1439   if (!mat->ops->solve) SETERRQ(PETSC_ERR_SUP,0,"");
1440   PLogEventBegin(MAT_Solve,mat,b,x,0);
1441   ierr = (*mat->ops->solve)(mat,b,x); CHKERRQ(ierr);
1442   PLogEventEnd(MAT_Solve,mat,b,x,0);
1443   PetscFunctionReturn(0);
1444 }
1445 
1446 #undef __FUNC__
1447 #define __FUNC__ "MatForwardSolve"
1448 /* @
1449    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU.
1450 
1451    Collective on Mat and Vec
1452 
1453    Input Parameters:
1454 +  mat - the factored matrix
1455 -  b - the right-hand-side vector
1456 
1457    Output Parameter:
1458 .  x - the result vector
1459 
1460    Notes:
1461    MatSolve() should be used for most applications, as it performs
1462    a forward solve followed by a backward solve.
1463 
1464    The vectors b and x cannot be the same.  I.e., one cannot
1465    call MatForwardSolve(A,x,x).
1466 
1467 .keywords: matrix, forward, LU, Cholesky, triangular solve
1468 
1469 .seealso: MatSolve(), MatBackwardSolve()
1470 @ */
1471 int MatForwardSolve(Mat mat,Vec b,Vec x)
1472 {
1473   int ierr;
1474 
1475   PetscFunctionBegin;
1476   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1477   PetscValidHeaderSpecific(b,VEC_COOKIE);  PetscValidHeaderSpecific(x,VEC_COOKIE);
1478   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,0,"x and b must be different vectors");
1479   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Unfactored matrix");
1480   if (!mat->ops->forwardsolve) SETERRQ(PETSC_ERR_SUP,0,"");
1481   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1482   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
1483   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
1484 
1485   PLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
1486   ierr = (*mat->ops->forwardsolve)(mat,b,x); CHKERRQ(ierr);
1487   PLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
1488   PetscFunctionReturn(0);
1489 }
1490 
1491 #undef __FUNC__
1492 #define __FUNC__ "MatBackwardSolve"
1493 /* @
1494    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
1495 
1496    Collective on Mat and Vec
1497 
1498    Input Parameters:
1499 +  mat - the factored matrix
1500 -  b - the right-hand-side vector
1501 
1502    Output Parameter:
1503 .  x - the result vector
1504 
1505    Notes:
1506    MatSolve() should be used for most applications, as it performs
1507    a forward solve followed by a backward solve.
1508 
1509    The vectors b and x cannot be the same.  I.e., one cannot
1510    call MatBackwardSolve(A,x,x).
1511 
1512 .keywords: matrix, backward, LU, Cholesky, triangular solve
1513 
1514 .seealso: MatSolve(), MatForwardSolve()
1515 @ */
1516 int MatBackwardSolve(Mat mat,Vec b,Vec x)
1517 {
1518   int ierr;
1519 
1520   PetscFunctionBegin;
1521   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1522   PetscValidHeaderSpecific(b,VEC_COOKIE);  PetscValidHeaderSpecific(x,VEC_COOKIE);
1523   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,0,"x and b must be different vectors");
1524   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Unfactored matrix");
1525   if (!mat->ops->backwardsolve) SETERRQ(PETSC_ERR_SUP,0,"");
1526   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1527   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
1528   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
1529 
1530   PLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
1531   ierr = (*mat->ops->backwardsolve)(mat,b,x); CHKERRQ(ierr);
1532   PLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
1533   PetscFunctionReturn(0);
1534 }
1535 
1536 #undef __FUNC__
1537 #define __FUNC__ "MatSolveAdd"
1538 /*@
1539    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
1540 
1541    Collective on Mat and Vec
1542 
1543    Input Parameters:
1544 +  mat - the factored matrix
1545 .  b - the right-hand-side vector
1546 -  y - the vector to be added to
1547 
1548    Output Parameter:
1549 .  x - the result vector
1550 
1551    Notes:
1552    The vectors b and x cannot be the same.  I.e., one cannot
1553    call MatSolveAdd(A,x,y,x).
1554 
1555 .keywords: matrix, linear system, solve, LU, Cholesky, add
1556 
1557 .seealso: MatSolve(), MatSolveTrans(), MatSolveTransAdd()
1558 @*/
1559 int MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
1560 {
1561   Scalar one = 1.0;
1562   Vec    tmp;
1563   int    ierr;
1564 
1565   PetscFunctionBegin;
1566   PetscValidHeaderSpecific(mat,MAT_COOKIE);PetscValidHeaderSpecific(y,VEC_COOKIE);
1567   PetscValidHeaderSpecific(b,VEC_COOKIE);  PetscValidHeaderSpecific(x,VEC_COOKIE);
1568   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,0,"x and b must be different vectors");
1569   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Unfactored matrix");
1570   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1571   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
1572   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
1573   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
1574   if (x->n != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Vec x,Vec y: local dim %d %d",x->n,y->n);
1575 
1576   PLogEventBegin(MAT_SolveAdd,mat,b,x,y);
1577   if (mat->ops->solveadd)  {
1578     ierr = (*mat->ops->solveadd)(mat,b,y,x); CHKERRQ(ierr);
1579   } else {
1580     /* do the solve then the add manually */
1581     if (x != y) {
1582       ierr = MatSolve(mat,b,x); CHKERRQ(ierr);
1583       ierr = VecAXPY(&one,y,x); CHKERRQ(ierr);
1584     } else {
1585       ierr = VecDuplicate(x,&tmp); CHKERRQ(ierr);
1586       PLogObjectParent(mat,tmp);
1587       ierr = VecCopy(x,tmp); CHKERRQ(ierr);
1588       ierr = MatSolve(mat,b,x); CHKERRQ(ierr);
1589       ierr = VecAXPY(&one,tmp,x); CHKERRQ(ierr);
1590       ierr = VecDestroy(tmp); CHKERRQ(ierr);
1591     }
1592   }
1593   PLogEventEnd(MAT_SolveAdd,mat,b,x,y);
1594   PetscFunctionReturn(0);
1595 }
1596 
1597 #undef __FUNC__
1598 #define __FUNC__ "MatSolveTrans"
1599 /*@
1600    MatSolveTrans - Solves A' x = b, given a factored matrix.
1601 
1602    Collective on Mat and Vec
1603 
1604    Input Parameters:
1605 +  mat - the factored matrix
1606 -  b - the right-hand-side vector
1607 
1608    Output Parameter:
1609 .  x - the result vector
1610 
1611    Notes:
1612    The vectors b and x cannot be the same.  I.e., one cannot
1613    call MatSolveTrans(A,x,x).
1614 
1615 .keywords: matrix, linear system, solve, LU, Cholesky, transpose
1616 
1617 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransAdd()
1618 @*/
1619 int MatSolveTrans(Mat mat,Vec b,Vec x)
1620 {
1621   int ierr;
1622 
1623   PetscFunctionBegin;
1624   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1625   PetscValidHeaderSpecific(b,VEC_COOKIE);  PetscValidHeaderSpecific(x,VEC_COOKIE);
1626   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Unfactored matrix");
1627   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,0,"x and b must be different vectors");
1628   if (!mat->ops->solvetrans) SETERRQ(PETSC_ERR_SUP,0,"");
1629   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
1630   if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: global dim %d %d",mat->N,b->N);
1631 
1632   PLogEventBegin(MAT_SolveTrans,mat,b,x,0);
1633   ierr = (*mat->ops->solvetrans)(mat,b,x); CHKERRQ(ierr);
1634   PLogEventEnd(MAT_SolveTrans,mat,b,x,0);
1635   PetscFunctionReturn(0);
1636 }
1637 
1638 #undef __FUNC__
1639 #define __FUNC__ "MatSolveTransAdd"
1640 /*@
1641    MatSolveTransAdd - Computes x = y + inv(trans(A)) b, given a
1642                       factored matrix.
1643 
1644    Collective on Mat and Vec
1645 
1646    Input Parameters:
1647 +  mat - the factored matrix
1648 .  b - the right-hand-side vector
1649 -  y - the vector to be added to
1650 
1651    Output Parameter:
1652 .  x - the result vector
1653 
1654    Notes:
1655    The vectors b and x cannot be the same.  I.e., one cannot
1656    call MatSolveTransAdd(A,x,y,x).
1657 
1658 .keywords: matrix, linear system, solve, LU, Cholesky, transpose, add
1659 
1660 .seealso: MatSolve(), MatSolveAdd(), MatSolveTrans()
1661 @*/
1662 int MatSolveTransAdd(Mat mat,Vec b,Vec y,Vec x)
1663 {
1664   Scalar one = 1.0;
1665   int    ierr;
1666   Vec    tmp;
1667 
1668   PetscFunctionBegin;
1669   PetscValidHeaderSpecific(mat,MAT_COOKIE);PetscValidHeaderSpecific(y,VEC_COOKIE);
1670   PetscValidHeaderSpecific(b,VEC_COOKIE);  PetscValidHeaderSpecific(x,VEC_COOKIE);
1671   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,0,"x and b must be different vectors");
1672   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Unfactored matrix");
1673   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
1674   if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: global dim %d %d",mat->N,b->N);
1675   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec y: global dim %d %d",mat->N,y->N);
1676   if (x->n != y->n)   SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Vec x,Vec y: local dim %d %d",x->n,y->n);
1677 
1678   PLogEventBegin(MAT_SolveTransAdd,mat,b,x,y);
1679   if (mat->ops->solvetransadd) {
1680     ierr = (*mat->ops->solvetransadd)(mat,b,y,x); CHKERRQ(ierr);
1681   } else {
1682     /* do the solve then the add manually */
1683     if (x != y) {
1684       ierr = MatSolveTrans(mat,b,x); CHKERRQ(ierr);
1685       ierr = VecAXPY(&one,y,x); CHKERRQ(ierr);
1686     } else {
1687       ierr = VecDuplicate(x,&tmp); CHKERRQ(ierr);
1688       PLogObjectParent(mat,tmp);
1689       ierr = VecCopy(x,tmp); CHKERRQ(ierr);
1690       ierr = MatSolveTrans(mat,b,x); CHKERRQ(ierr);
1691       ierr = VecAXPY(&one,tmp,x); CHKERRQ(ierr);
1692       ierr = VecDestroy(tmp); CHKERRQ(ierr);
1693     }
1694   }
1695   PLogEventEnd(MAT_SolveTransAdd,mat,b,x,y);
1696   PetscFunctionReturn(0);
1697 }
1698 /* ----------------------------------------------------------------*/
1699 
1700 #undef __FUNC__
1701 #define __FUNC__ "MatRelax"
1702 /*@
1703    MatRelax - Computes one relaxation sweep.
1704 
1705    Collective on Mat and Vec
1706 
1707    Input Parameters:
1708 +  mat - the matrix
1709 .  b - the right hand side
1710 .  omega - the relaxation factor
1711 .  flag - flag indicating the type of SOR (see below)
1712 .  shift -  diagonal shift
1713 -  its - the number of iterations
1714 
1715    Output Parameters:
1716 .  x - the solution (can contain an initial guess)
1717 
1718    SOR Flags:
1719 .     SOR_FORWARD_SWEEP - forward SOR
1720 .     SOR_BACKWARD_SWEEP - backward SOR
1721 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
1722 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
1723 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
1724 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
1725 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
1726          upper/lower triangular part of matrix to
1727          vector (with omega)
1728 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
1729 
1730    Notes:
1731    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
1732    SOR_LOCAL_SYMMETRIC_SWEEP perform seperate independent smoothings
1733    on each processor.
1734 
1735    Application programmers will not generally use MatRelax() directly,
1736    but instead will employ the SLES/PC interface.
1737 
1738    Notes for Advanced Users:
1739    The flags are implemented as bitwise inclusive or operations.
1740    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
1741    to specify a zero initial guess for SSOR.
1742 
1743 .keywords: matrix, relax, relaxation, sweep
1744 @*/
1745 int MatRelax(Mat mat,Vec b,double omega,MatSORType flag,double shift,
1746              int its,Vec x)
1747 {
1748   int ierr;
1749 
1750   PetscFunctionBegin;
1751   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1752   PetscValidHeaderSpecific(b,VEC_COOKIE);  PetscValidHeaderSpecific(x,VEC_COOKIE);
1753   if (!mat->ops->relax) SETERRQ(PETSC_ERR_SUP,0,"");
1754   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1755   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
1756   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1757   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
1758   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
1759 
1760   PLogEventBegin(MAT_Relax,mat,b,x,0);
1761   ierr =(*mat->ops->relax)(mat,b,omega,flag,shift,its,x); CHKERRQ(ierr);
1762   PLogEventEnd(MAT_Relax,mat,b,x,0);
1763   PetscFunctionReturn(0);
1764 }
1765 
1766 #undef __FUNC__
1767 #define __FUNC__ "MatCopy_Basic"
1768 /*
1769       Default matrix copy routine.
1770 */
1771 int MatCopy_Basic(Mat A,Mat B,MatStructure str)
1772 {
1773   int    ierr,i,rstart,rend,nz,*cwork;
1774   Scalar *vwork;
1775 
1776   PetscFunctionBegin;
1777   ierr = MatZeroEntries(B); CHKERRQ(ierr);
1778   ierr = MatGetOwnershipRange(A,&rstart,&rend); CHKERRQ(ierr);
1779   for (i=rstart; i<rend; i++) {
1780     ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
1781     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
1782     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
1783   }
1784   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1785   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1786   PetscFunctionReturn(0);
1787 }
1788 
1789 #undef __FUNC__
1790 #define __FUNC__ "MatCopy"
1791 /*@C
1792    MatCopy - Copys a matrix to another matrix.
1793 
1794    Collective on Mat
1795 
1796    Input Parameters:
1797 +  A - the matrix
1798 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
1799 
1800    Output Parameter:
1801 .  B - where the copy is put
1802 
1803    Notes:
1804    If you use SAME_NONZERO_PATTERN then the zero matrices had better have the
1805    same nonzero pattern or the routine will crash.
1806 
1807    MatCopy() copies the matrix entries of a matrix to another existing
1808    matrix (after first zeroing the second matrix).  A related routine is
1809    MatConvert(), which first creates a new matrix and then copies the data.
1810 
1811 .keywords: matrix, copy, convert
1812 
1813 .seealso: MatConvert()
1814 @*/
1815 int MatCopy(Mat A,Mat B,MatStructure str)
1816 {
1817   int ierr;
1818 
1819   PetscFunctionBegin;
1820   PetscValidHeaderSpecific(A,MAT_COOKIE); PetscValidHeaderSpecific(B,MAT_COOKIE);
1821   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1822   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
1823   if (A->M != B->M || A->N != B->N) SETERRQ4(PETSC_ERR_ARG_SIZ,0,"Mat A,Mat B: global dim %d %d",A->M,B->M,
1824                                              A->N,B->N);
1825 
1826   PLogEventBegin(MAT_Copy,A,B,0,0);
1827   if (A->ops->copy) {
1828     ierr = (*A->ops->copy)(A,B,str); CHKERRQ(ierr);
1829   } else { /* generic conversion */
1830     ierr = MatCopy_Basic(A,B,str); CHKERRQ(ierr);
1831   }
1832   PLogEventEnd(MAT_Copy,A,B,0,0);
1833   PetscFunctionReturn(0);
1834 }
1835 
1836 static int MatConvertersSet = 0;
1837 static int (*MatConverters[MAX_MATRIX_TYPES][MAX_MATRIX_TYPES])(Mat,MatType,Mat*) =
1838            {{0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0},
1839             {0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0},
1840             {0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0},
1841             {0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0},
1842             {0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0},
1843             {0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0}};
1844 
1845 #undef __FUNC__
1846 #define __FUNC__ "MatConvertRegister"
1847 /*@C
1848     MatConvertRegister - Allows one to register a routine that converts between
1849         two matrix types.
1850 
1851     Not Collective
1852 
1853     Input Parameters:
1854 .   intype - the type of matrix (defined in include/mat.h), for example, MATSEQAIJ.
1855 .   outtype - new matrix type, or MATSAME
1856 
1857 .seealso: MatConvertRegisterAll()
1858 @*/
1859 int MatConvertRegister(MatType intype,MatType outtype,int (*converter)(Mat,MatType,Mat*))
1860 {
1861   PetscFunctionBegin;
1862   MatConverters[intype][outtype] = converter;
1863   MatConvertersSet               = 1;
1864   PetscFunctionReturn(0);
1865 }
1866 
1867 #undef __FUNC__
1868 #define __FUNC__ "MatConvert"
1869 /*@C
1870    MatConvert - Converts a matrix to another matrix, either of the same
1871    or different type.
1872 
1873    Collective on Mat
1874 
1875    Input Parameters:
1876 +  mat - the matrix
1877 -  newtype - new matrix type.  Use MATSAME to create a new matrix of the
1878    same type as the original matrix.
1879 
1880    Output Parameter:
1881 .  M - pointer to place new matrix
1882 
1883    Notes:
1884    MatConvert() first creates a new matrix and then copies the data from
1885    the first matrix.  A related routine is MatCopy(), which copies the matrix
1886    entries of one matrix to another already existing matrix context.
1887 
1888 .keywords: matrix, copy, convert
1889 
1890 .seealso: MatCopy(), MatDuplicate()
1891 @*/
1892 int MatConvert(Mat mat,MatType newtype,Mat *M)
1893 {
1894   int ierr;
1895 
1896   PetscFunctionBegin;
1897   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1898   PetscValidPointer(M);
1899   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1900   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
1901 
1902   if (newtype > MAX_MATRIX_TYPES || newtype < -1) {
1903     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,1,"Not a valid matrix type");
1904   }
1905   *M  = 0;
1906 
1907   if (!MatConvertersSet) {
1908     ierr = MatLoadRegisterAll(); CHKERRQ(ierr);
1909   }
1910 
1911   PLogEventBegin(MAT_Convert,mat,0,0,0);
1912   if ((newtype == mat->type || newtype == MATSAME) && mat->ops->duplicate) {
1913     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M); CHKERRQ(ierr);
1914   } else {
1915     if (!MatConvertersSet) {
1916       ierr = MatConvertRegisterAll(); CHKERRQ(ierr);
1917     }
1918     if (!MatConverters[mat->type][newtype]) {
1919       SETERRQ(PETSC_ERR_ARG_WRONG,1,"Invalid matrix type, or matrix converter not registered");
1920     }
1921     ierr = (*MatConverters[mat->type][newtype])(mat,newtype,M); CHKERRQ(ierr);
1922   }
1923   PLogEventEnd(MAT_Convert,mat,0,0,0);
1924   PetscFunctionReturn(0);
1925 }
1926 
1927 #undef __FUNC__
1928 #define __FUNC__ "MatDuplicate"
1929 /*@C
1930    MatDuplicate - Duplicates a matrix including the non-zero structure.
1931 
1932    Collective on Mat
1933 
1934    Input Parameters:
1935 +  mat - the matrix
1936 -  op - either MAT_DO_NO_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
1937         values as well or not
1938 
1939    Output Parameter:
1940 .  M - pointer to place new matrix
1941 
1942 .keywords: matrix, copy, convert, duplicate
1943 
1944 .seealso: MatCopy(), MatConvert()
1945 @*/
1946 int MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
1947 {
1948   int ierr;
1949 
1950   PetscFunctionBegin;
1951   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1952   PetscValidPointer(M);
1953   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1954   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
1955 
1956   *M  = 0;
1957   PLogEventBegin(MAT_Convert,mat,0,0,0);
1958   if (!mat->ops->duplicate) {
1959     SETERRQ(PETSC_ERR_SUP,1,"Not written for this matrix type");
1960   }
1961   ierr = (*mat->ops->duplicate)(mat,op,M); CHKERRQ(ierr);
1962   PLogEventEnd(MAT_Convert,mat,0,0,0);
1963   PetscFunctionReturn(0);
1964 }
1965 
1966 #undef __FUNC__
1967 #define __FUNC__ "MatGetDiagonal"
1968 /*@
1969    MatGetDiagonal - Gets the diagonal of a matrix.
1970 
1971    Collective on Mat and Vec
1972 
1973    Input Parameters:
1974 +  mat - the matrix
1975 -  v - the vector for storing the diagonal
1976 
1977    Output Parameter:
1978 .  v - the diagonal of the matrix
1979 
1980    Notes:
1981    For the SeqAIJ matrix format, this routine may also be called
1982    on a LU factored matrix; in that case it routines the reciprocal of
1983    the diagonal entries in U. It returns the entries permuted by the
1984    row and column permutation used during the symbolic factorization.
1985 
1986 .keywords: matrix, get, diagonal
1987 @*/
1988 int MatGetDiagonal(Mat mat,Vec v)
1989 {
1990   int ierr;
1991 
1992   PetscFunctionBegin;
1993   PetscValidHeaderSpecific(mat,MAT_COOKIE);PetscValidHeaderSpecific(v,VEC_COOKIE);
1994   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1995   if (!mat->ops->getdiagonal) SETERRQ(PETSC_ERR_SUP,0,"");
1996   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
1997   PetscFunctionReturn(0);
1998 }
1999 
2000 #undef __FUNC__
2001 #define __FUNC__ "MatTranspose"
2002 /*@C
2003    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
2004 
2005    Collective on Mat
2006 
2007    Input Parameter:
2008 .  mat - the matrix to transpose
2009 
2010    Output Parameters:
2011 .  B - the transpose (or pass in PETSC_NULL for an in-place transpose)
2012 
2013 .keywords: matrix, transpose
2014 
2015 .seealso: MatMultTrans(), MatMultTransAdd()
2016 @*/
2017 int MatTranspose(Mat mat,Mat *B)
2018 {
2019   int ierr;
2020 
2021   PetscFunctionBegin;
2022   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2023   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2024   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2025   if (!mat->ops->transpose) SETERRQ(PETSC_ERR_SUP,0,"");
2026   ierr = (*mat->ops->transpose)(mat,B);CHKERRQ(ierr);
2027   PetscFunctionReturn(0);
2028 }
2029 
2030 #undef __FUNC__
2031 #define __FUNC__ "MatPermute"
2032 /*@C
2033    MatPermute - Creates a new matrix with rows and columns permuted from the
2034    original.
2035 
2036    Collective on Mat
2037 
2038    Input Parameters:
2039 +  mat - the matrix to permute
2040 .  row - row permutation
2041 -  col - column permutation
2042 
2043    Output Parameters:
2044 .  B - the permuted matrix
2045 
2046 .keywords: matrix, transpose
2047 
2048 .seealso: MatGetReordering()
2049 @*/
2050 int MatPermute(Mat mat,IS row,IS col,Mat *B)
2051 {
2052   int ierr;
2053 
2054   PetscFunctionBegin;
2055   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2056   PetscValidHeaderSpecific(row,IS_COOKIE);
2057   PetscValidHeaderSpecific(col,IS_COOKIE);
2058   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2059   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2060   if (!mat->ops->permute) SETERRQ(PETSC_ERR_SUP,0,"");
2061   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
2062   PetscFunctionReturn(0);
2063 }
2064 
2065 #undef __FUNC__
2066 #define __FUNC__ "MatEqual"
2067 /*@
2068    MatEqual - Compares two matrices.
2069 
2070    Collective on Mat
2071 
2072    Input Parameters:
2073 +  A - the first matrix
2074 -  B - the second matrix
2075 
2076    Output Parameter:
2077 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
2078 
2079 .keywords: matrix, equal, equivalent
2080 @*/
2081 int MatEqual(Mat A,Mat B,PetscTruth *flg)
2082 {
2083   int ierr;
2084 
2085   PetscFunctionBegin;
2086   PetscValidHeaderSpecific(A,MAT_COOKIE); PetscValidHeaderSpecific(B,MAT_COOKIE);
2087   PetscValidIntPointer(flg);
2088   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2089   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2090   if (A->M != B->M || A->N != B->N) SETERRQ4(PETSC_ERR_ARG_SIZ,0,"Mat A,Mat B: global dim %d %d %d %d",
2091                                              A->M,B->M,A->N,B->N);
2092   if (!A->ops->equal) SETERRQ(PETSC_ERR_SUP,0,"");
2093   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
2094   PetscFunctionReturn(0);
2095 }
2096 
2097 #undef __FUNC__
2098 #define __FUNC__ "MatDiagonalScale"
2099 /*@
2100    MatDiagonalScale - Scales a matrix on the left and right by diagonal
2101    matrices that are stored as vectors.  Either of the two scaling
2102    matrices can be PETSC_NULL.
2103 
2104    Collective on Mat
2105 
2106    Input Parameters:
2107 +  mat - the matrix to be scaled
2108 .  l - the left scaling vector (or PETSC_NULL)
2109 -  r - the right scaling vector (or PETSC_NULL)
2110 
2111    Notes:
2112    MatDiagonalScale() computes A = LAR, where
2113    L = a diagonal matrix, R = a diagonal matrix
2114 
2115 .keywords: matrix, diagonal, scale
2116 
2117 .seealso: MatDiagonalScale()
2118 @*/
2119 int MatDiagonalScale(Mat mat,Vec l,Vec r)
2120 {
2121   int ierr;
2122 
2123   PetscFunctionBegin;
2124   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2125   if (!mat->ops->diagonalscale) SETERRQ(PETSC_ERR_SUP,0,"");
2126   if (l) PetscValidHeaderSpecific(l,VEC_COOKIE);
2127   if (r) PetscValidHeaderSpecific(r,VEC_COOKIE);
2128   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2129   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2130 
2131   PLogEventBegin(MAT_Scale,mat,0,0,0);
2132   ierr = (*mat->ops->diagonalscale)(mat,l,r); CHKERRQ(ierr);
2133   PLogEventEnd(MAT_Scale,mat,0,0,0);
2134   PetscFunctionReturn(0);
2135 }
2136 
2137 #undef __FUNC__
2138 #define __FUNC__ "MatScale"
2139 /*@
2140     MatScale - Scales all elements of a matrix by a given number.
2141 
2142     Collective on Mat
2143 
2144     Input Parameters:
2145 +   mat - the matrix to be scaled
2146 -   a  - the scaling value
2147 
2148     Output Parameter:
2149 .   mat - the scaled matrix
2150 
2151 .keywords: matrix, scale
2152 
2153 .seealso: MatDiagonalScale()
2154 @*/
2155 int MatScale(Scalar *a,Mat mat)
2156 {
2157   int ierr;
2158 
2159   PetscFunctionBegin;
2160   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2161   PetscValidScalarPointer(a);
2162   if (!mat->ops->scale) SETERRQ(PETSC_ERR_SUP,0,"");
2163   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2164   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2165 
2166   PLogEventBegin(MAT_Scale,mat,0,0,0);
2167   ierr = (*mat->ops->scale)(a,mat); CHKERRQ(ierr);
2168   PLogEventEnd(MAT_Scale,mat,0,0,0);
2169   PetscFunctionReturn(0);
2170 }
2171 
2172 #undef __FUNC__
2173 #define __FUNC__ "MatNorm"
2174 /*@
2175    MatNorm - Calculates various norms of a matrix.
2176 
2177    Collective on Mat
2178 
2179    Input Parameters:
2180 +  mat - the matrix
2181 -  type - the type of norm, NORM_1, NORM_2, NORM_FROBENIUS, NORM_INFINITY
2182 
2183    Output Parameters:
2184 .  norm - the resulting norm
2185 
2186 .keywords: matrix, norm, Frobenius
2187 @*/
2188 int MatNorm(Mat mat,NormType type,double *norm)
2189 {
2190   int ierr;
2191 
2192   PetscFunctionBegin;
2193   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2194   PetscValidScalarPointer(norm);
2195 
2196   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2197   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2198   if (!mat->ops->norm) SETERRQ(PETSC_ERR_SUP,0,"Not for this matrix type");
2199   ierr = (*mat->ops->norm)(mat,type,norm);CHKERRQ(ierr);
2200   PetscFunctionReturn(0);
2201 }
2202 
2203 /*
2204      This variable is used to prevent counting of MatAssemblyBegin() that
2205    are called from within a MatAssemblyEnd().
2206 */
2207 static int MatAssemblyEnd_InUse = 0;
2208 #undef __FUNC__
2209 #define __FUNC__ "MatAssemblyBegin"
2210 /*@
2211    MatAssemblyBegin - Begins assembling the matrix.  This routine should
2212    be called after completing all calls to MatSetValues().
2213 
2214    Collective on Mat
2215 
2216    Input Parameters:
2217 +  mat - the matrix
2218 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
2219 
2220    Notes:
2221    MatSetValues() generally caches the values.  The matrix is ready to
2222    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
2223    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
2224    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
2225    using the matrix.
2226 
2227    Level: beginner
2228 
2229 .keywords: matrix, assembly, assemble, begin
2230 
2231 .seealso: MatAssemblyEnd(), MatSetValues()
2232 @*/
2233 int MatAssemblyBegin(Mat mat,MatAssemblyType type)
2234 {
2235   int ierr;
2236 
2237   PetscFunctionBegin;
2238   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2239   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix.\n did you forget to call MatSetUnfactored()?");
2240   if (mat->assembled) {
2241     mat->was_assembled = PETSC_TRUE;
2242     mat->assembled     = PETSC_FALSE;
2243   }
2244   if (!MatAssemblyEnd_InUse) {
2245     PLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
2246     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
2247     PLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
2248   } else {
2249     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
2250   }
2251   PetscFunctionReturn(0);
2252 }
2253 
2254 
2255 #undef __FUNC__
2256 #define __FUNC__ "MatView_Private"
2257 /*
2258     Processes command line options to determine if/how a matrix
2259   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
2260 */
2261 int MatView_Private(Mat mat)
2262 {
2263   int ierr,flg;
2264 
2265   PetscFunctionBegin;
2266   ierr = OptionsHasName(PETSC_NULL,"-mat_view_info",&flg); CHKERRQ(ierr);
2267   if (flg) {
2268     ierr = ViewerPushFormat(VIEWER_STDOUT_(mat->comm),VIEWER_FORMAT_ASCII_INFO,0);CHKERRQ(ierr);
2269     ierr = MatView(mat,VIEWER_STDOUT_(mat->comm)); CHKERRQ(ierr);
2270     ierr = ViewerPopFormat(VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
2271   }
2272   ierr = OptionsHasName(PETSC_NULL,"-mat_view_info_detailed",&flg);CHKERRQ(ierr);
2273   if (flg) {
2274     ierr = ViewerPushFormat(VIEWER_STDOUT_(mat->comm),VIEWER_FORMAT_ASCII_INFO_LONG,0);CHKERRQ(ierr);
2275     ierr = MatView(mat,VIEWER_STDOUT_(mat->comm)); CHKERRQ(ierr);
2276     ierr = ViewerPopFormat(VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
2277   }
2278   ierr = OptionsHasName(PETSC_NULL,"-mat_view",&flg); CHKERRQ(ierr);
2279   if (flg) {
2280     ierr = MatView(mat,VIEWER_STDOUT_(mat->comm)); CHKERRQ(ierr);
2281   }
2282   ierr = OptionsHasName(PETSC_NULL,"-mat_view_matlab",&flg); CHKERRQ(ierr);
2283   if (flg) {
2284     ierr = ViewerPushFormat(VIEWER_STDOUT_(mat->comm),VIEWER_FORMAT_ASCII_MATLAB,"M");CHKERRQ(ierr);
2285     ierr = MatView(mat,VIEWER_STDOUT_(mat->comm)); CHKERRQ(ierr);
2286     ierr = ViewerPopFormat(VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
2287   }
2288   ierr = OptionsHasName(PETSC_NULL,"-mat_view_draw",&flg); CHKERRQ(ierr);
2289   if (flg) {
2290     ierr = OptionsHasName(0,"-mat_view_contour",&flg); CHKERRQ(ierr);
2291     if (flg) {
2292       ViewerPushFormat(VIEWER_DRAW_(mat->comm),VIEWER_FORMAT_DRAW_CONTOUR,0);CHKERRQ(ierr);
2293     }
2294     ierr = MatView(mat,VIEWER_DRAW_(mat->comm)); CHKERRQ(ierr);
2295     ierr = ViewerFlush(VIEWER_DRAW_(mat->comm)); CHKERRQ(ierr);
2296     if (flg) {
2297       ViewerPopFormat(VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
2298     }
2299   }
2300   ierr = OptionsHasName(PETSC_NULL,"-mat_view_socket",&flg); CHKERRQ(ierr);
2301   if (flg) {
2302     ierr = MatView(mat,VIEWER_SOCKET_(mat->comm)); CHKERRQ(ierr);
2303     ierr = ViewerFlush(VIEWER_SOCKET_(mat->comm)); CHKERRQ(ierr);
2304   }
2305   PetscFunctionReturn(0);
2306 }
2307 
2308 #undef __FUNC__
2309 #define __FUNC__ "MatAssemblyEnd"
2310 /*@
2311    MatAssemblyEnd - Completes assembling the matrix.  This routine should
2312    be called after MatAssemblyBegin().
2313 
2314    Collective on Mat
2315 
2316    Input Parameters:
2317 +  mat - the matrix
2318 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
2319 
2320    Options Database Keys:
2321 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
2322 .  -mat_view_info_detailed - Prints more detailed info
2323 .  -mat_view - Prints matrix in ASCII format
2324 .  -mat_view_matlab - Prints matrix in Matlab format
2325 .  -mat_view_draw - Draws nonzero structure of matrix, using MatView() and DrawOpenX().
2326 .  -display <name> - Sets display name (default is host)
2327 -  -draw_pause <sec> - Sets number of seconds to pause after display
2328 
2329    Notes:
2330    MatSetValues() generally caches the values.  The matrix is ready to
2331    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
2332    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
2333    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
2334    using the matrix.
2335 
2336    Level: beginner
2337 
2338 .keywords: matrix, assembly, assemble, end
2339 
2340 .seealso: MatAssemblyBegin(), MatSetValues(), DrawOpenX(), MatView()
2341 @*/
2342 int MatAssemblyEnd(Mat mat,MatAssemblyType type)
2343 {
2344   int        ierr;
2345   static int inassm = 0;
2346 
2347   PetscFunctionBegin;
2348   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2349 
2350   inassm++;
2351   MatAssemblyEnd_InUse++;
2352   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
2353     PLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
2354     if (mat->ops->assemblyend) {
2355       ierr = (*mat->ops->assemblyend)(mat,type); CHKERRQ(ierr);
2356     }
2357     PLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
2358   } else {
2359     if (mat->ops->assemblyend) {
2360       ierr = (*mat->ops->assemblyend)(mat,type); CHKERRQ(ierr);
2361     }
2362   }
2363 
2364   /* Flush assembly is not a true assembly */
2365   if (type != MAT_FLUSH_ASSEMBLY) {
2366     mat->assembled  = PETSC_TRUE; mat->num_ass++;
2367   }
2368   mat->insertmode = NOT_SET_VALUES;
2369   MatAssemblyEnd_InUse--;
2370 
2371   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
2372     ierr = MatView_Private(mat); CHKERRQ(ierr);
2373   }
2374   inassm--;
2375   PetscFunctionReturn(0);
2376 }
2377 
2378 
2379 #undef __FUNC__
2380 #define __FUNC__ "MatCompress"
2381 /*@
2382    MatCompress - Tries to store the matrix in as little space as
2383    possible.  May fail if memory is already fully used, since it
2384    tries to allocate new space.
2385 
2386    Collective on Mat
2387 
2388    Input Parameters:
2389 .  mat - the matrix
2390 
2391 .keywords: matrix, compress
2392 @*/
2393 int MatCompress(Mat mat)
2394 {
2395   int ierr;
2396 
2397   PetscFunctionBegin;
2398   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2399   if (mat->ops->compress) {ierr = (*mat->ops->compress)(mat);CHKERRQ(ierr);}
2400   PetscFunctionReturn(0);
2401 }
2402 
2403 #undef __FUNC__
2404 #define __FUNC__ "MatSetOption"
2405 /*@
2406    MatSetOption - Sets a parameter option for a matrix. Some options
2407    may be specific to certain storage formats.  Some options
2408    determine how values will be inserted (or added). Sorted,
2409    row-oriented input will generally assemble the fastest. The default
2410    is row-oriented, nonsorted input.
2411 
2412    Collective on Mat
2413 
2414    Input Parameters:
2415 +  mat - the matrix
2416 -  option - the option, one of those listed below (and possibly others),
2417              e.g., MAT_ROWS_SORTED, MAT_NEW_NONZERO_LOCATION_ERR
2418 
2419    Options Describing Matrix Structure:
2420 +    MAT_SYMMETRIC - symmetric in terms of both structure and value
2421 -    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
2422 
2423    Options For Use with MatSetValues():
2424    Insert a logically dense subblock, which can be
2425 +    MAT_ROW_ORIENTED - row-oriented
2426 .    MAT_COLUMN_ORIENTED - column-oriented
2427 .    MAT_ROWS_SORTED - sorted by row
2428 .    MAT_ROWS_UNSORTED - not sorted by row
2429 .    MAT_COLUMNS_SORTED - sorted by column
2430 -    MAT_COLUMNS_UNSORTED - not sorted by column
2431 
2432    Not these options reflect the data you pass in with MatSetValues(); it has
2433    nothing to do with how the data is stored internally in the matrix
2434    data structure.
2435 
2436    When (re)assembling a matrix, we can restrict the input for
2437    efficiency/debugging purposes.  These options include
2438 +    MAT_NO_NEW_NONZERO_LOCATIONS - additional insertions will not be
2439         allowed if they generate a new nonzero
2440 .    MAT_YES_NEW_NONZERO_LOCATIONS - additional insertions will be allowed
2441 .    MAT_NO_NEW_DIAGONALS - additional insertions will not be allowed if
2442          they generate a nonzero in a new diagonal (for block diagonal format only)
2443 .    MAT_YES_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
2444 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
2445 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
2446 -    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
2447 
2448    Notes:
2449    Some options are relevant only for particular matrix types and
2450    are thus ignored by others.  Other options are not supported by
2451    certain matrix types and will generate an error message if set.
2452 
2453    If using a Fortran 77 module to compute a matrix, one may need to
2454    use the column-oriented option (or convert to the row-oriented
2455    format).
2456 
2457    MAT_NO_NEW_NONZERO_LOCATIONS indicates that any add or insertion
2458    that would generate a new entry in the nonzero structure is instead
2459    ignored.  Thus, if memory has not alredy been allocated for this particular
2460    data, then the insertion is ignored. For dense matrices, in which
2461    the entire array is allocated, no entries are ever ignored.
2462 
2463    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
2464    that would generate a new entry in the nonzero structure instead produces
2465    an error. (Currently supported for AIJ and BAIJ formats only.)
2466    This is a useful flag when using SAME_NONZERO_PATTERN in calling
2467    SLESSetOperators() to ensure that the nonzero pattern truely does
2468    remain unchanged.
2469 
2470    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
2471    that would generate a new entry that has not been preallocated will
2472    instead produce an error. (Currently supported for AIJ and BAIJ formats
2473    only.) This is a useful flag when debugging matrix memory preallocation.
2474 
2475    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
2476    other processors should be dropped, rather than stashed.
2477    This is useful if you know that the "owning" processor is also
2478    always generating the correct matrix entries, so that PETSc need
2479    not transfer duplicate entries generated on another processor.
2480 
2481    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
2482    searches during matrix assembly. When this flag is set, the hash table
2483    is created during the first Matrix Assembly. This hash table is
2484    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
2485    to improve the searching of indices. MAT_NO_NEW_NONZERO_LOCATIONS flag
2486    should be used with MAT_USE_HASH_TABLE flag. This option is currently
2487    supported by MATMPIBAIJ format only.
2488 
2489 .keywords: matrix, option, row-oriented, column-oriented, sorted, nonzero
2490 @*/
2491 int MatSetOption(Mat mat,MatOption op)
2492 {
2493   int ierr;
2494 
2495   PetscFunctionBegin;
2496   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2497   if (mat->ops->setoption) {ierr = (*mat->ops->setoption)(mat,op);CHKERRQ(ierr);}
2498   PetscFunctionReturn(0);
2499 }
2500 
2501 #undef __FUNC__
2502 #define __FUNC__ "MatZeroEntries"
2503 /*@
2504    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
2505    this routine retains the old nonzero structure.
2506 
2507    Collective on Mat
2508 
2509    Input Parameters:
2510 .  mat - the matrix
2511 
2512 .keywords: matrix, zero, entries
2513 
2514 .seealso: MatZeroRows()
2515 @*/
2516 int MatZeroEntries(Mat mat)
2517 {
2518   int ierr;
2519 
2520   PetscFunctionBegin;
2521   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2522   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2523   if (!mat->ops->zeroentries) SETERRQ(PETSC_ERR_SUP,0,"");
2524 
2525   PLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
2526   ierr = (*mat->ops->zeroentries)(mat); CHKERRQ(ierr);
2527   PLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
2528   PetscFunctionReturn(0);
2529 }
2530 
2531 #undef __FUNC__
2532 #define __FUNC__ "MatZeroRows"
2533 /*@
2534    MatZeroRows - Zeros all entries (except possibly the main diagonal)
2535    of a set of rows of a matrix.
2536 
2537    Collective on Mat
2538 
2539    Input Parameters:
2540 +  mat - the matrix
2541 .  is - index set of rows to remove
2542 -  diag - pointer to value put in all diagonals of eliminated rows.
2543           Note that diag is not a pointer to an array, but merely a
2544           pointer to a single value.
2545 
2546    Notes:
2547    For the AIJ matrix formats this removes the old nonzero structure,
2548    but does not release memory.  For the dense and block diagonal
2549    formats this does not alter the nonzero structure.
2550 
2551    The user can set a value in the diagonal entry (or for the AIJ and
2552    row formats can optionally remove the main diagonal entry from the
2553    nonzero structure as well, by passing a null pointer as the final
2554    argument).
2555 
2556    For the parallel case, all processes that share the matrix (i.e.,
2557    those in the communicator used for matrix creation) MUST call this
2558    routine, regardless of whether any rows being zeroed are owned by
2559    them.
2560 
2561 .keywords: matrix, zero, rows, boundary conditions
2562 
2563 .seealso: MatZeroEntries(),
2564 @*/
2565 int MatZeroRows(Mat mat,IS is, Scalar *diag)
2566 {
2567   int ierr;
2568 
2569   PetscFunctionBegin;
2570   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2571   PetscValidHeaderSpecific(is,IS_COOKIE);
2572   if (diag) PetscValidScalarPointer(diag);
2573   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2574   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2575   if (!mat->ops->zerorows) SETERRQ(PETSC_ERR_SUP,0,"");
2576 
2577   ierr = (*mat->ops->zerorows)(mat,is,diag); CHKERRQ(ierr);
2578   ierr = MatView_Private(mat); CHKERRQ(ierr);
2579   PetscFunctionReturn(0);
2580 }
2581 
2582 #undef __FUNC__
2583 #define __FUNC__ "MatZeroRowsLocal"
2584 /*@
2585    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
2586    of a set of rows of a matrix; using local numbering of rows.
2587 
2588    Collective on Mat
2589 
2590    Input Parameters:
2591 +  mat - the matrix
2592 .  is - index set of rows to remove
2593 -  diag - pointer to value put in all diagonals of eliminated rows.
2594           Note that diag is not a pointer to an array, but merely a
2595           pointer to a single value.
2596 
2597    Notes:
2598    For the AIJ matrix formats this removes the old nonzero structure,
2599    but does not release memory.  For the dense and block diagonal
2600    formats this does not alter the nonzero structure.
2601 
2602    The user can set a value in the diagonal entry (or for the AIJ and
2603    row formats can optionally remove the main diagonal entry from the
2604    nonzero structure as well, by passing a null pointer as the final
2605    argument).
2606 
2607 .keywords: matrix, zero, rows, boundary conditions
2608 
2609 .seealso: MatZeroEntries(),
2610 @*/
2611 int MatZeroRowsLocal(Mat mat,IS is, Scalar *diag)
2612 {
2613   int ierr;
2614   IS  newis;
2615 
2616   PetscFunctionBegin;
2617   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2618   PetscValidHeaderSpecific(is,IS_COOKIE);
2619   if (diag) PetscValidScalarPointer(diag);
2620   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2621   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2622   if (!mat->ops->zerorows) SETERRQ(PETSC_ERR_SUP,0,"");
2623 
2624   ierr = ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis); CHKERRQ(ierr);
2625   ierr =  (*mat->ops->zerorows)(mat,newis,diag); CHKERRQ(ierr);
2626   ierr = ISDestroy(newis);
2627   PetscFunctionReturn(0);
2628 }
2629 
2630 #undef __FUNC__
2631 #define __FUNC__ "MatGetSize"
2632 /*@
2633    MatGetSize - Returns the numbers of rows and columns in a matrix.
2634 
2635    Not Collective
2636 
2637    Input Parameter:
2638 .  mat - the matrix
2639 
2640    Output Parameters:
2641 +  m - the number of global rows
2642 -  n - the number of global columns
2643 
2644 .keywords: matrix, dimension, size, rows, columns, global, get
2645 
2646 .seealso: MatGetLocalSize()
2647 @*/
2648 int MatGetSize(Mat mat,int *m,int* n)
2649 {
2650   int ierr;
2651 
2652   PetscFunctionBegin;
2653   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2654   ierr = (*mat->ops->getsize)(mat,m,n);CHKERRQ(ierr);
2655   PetscFunctionReturn(0);
2656 }
2657 
2658 #undef __FUNC__
2659 #define __FUNC__ "MatGetLocalSize"
2660 /*@
2661    MatGetLocalSize - Returns the number of rows and columns in a matrix
2662    stored locally.  This information may be implementation dependent, so
2663    use with care.
2664 
2665    Not Collective
2666 
2667    Input Parameters:
2668 .  mat - the matrix
2669 
2670    Output Parameters:
2671 +  m - the number of local rows
2672 -  n - the number of local columns
2673 
2674 .keywords: matrix, dimension, size, local, rows, columns, get
2675 
2676 .seealso: MatGetSize()
2677 @*/
2678 int MatGetLocalSize(Mat mat,int *m,int* n)
2679 {
2680   int ierr;
2681 
2682   PetscFunctionBegin;
2683   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2684   ierr = (*mat->ops->getlocalsize)(mat,m,n);CHKERRQ(ierr);
2685   PetscFunctionReturn(0);
2686 }
2687 
2688 #undef __FUNC__
2689 #define __FUNC__ "MatGetOwnershipRange"
2690 /*@
2691    MatGetOwnershipRange - Returns the range of matrix rows owned by
2692    this processor, assuming that the matrix is laid out with the first
2693    n1 rows on the first processor, the next n2 rows on the second, etc.
2694    For certain parallel layouts this range may not be well defined.
2695 
2696    Not Collective
2697 
2698    Input Parameters:
2699 .  mat - the matrix
2700 
2701    Output Parameters:
2702 +  m - the global index of the first local row
2703 -  n - one more than the global index of the last local row
2704 
2705 .keywords: matrix, get, range, ownership
2706 @*/
2707 int MatGetOwnershipRange(Mat mat,int *m,int* n)
2708 {
2709   int ierr;
2710 
2711   PetscFunctionBegin;
2712   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2713   PetscValidIntPointer(m);
2714   PetscValidIntPointer(n);
2715   if (!mat->ops->getownershiprange) SETERRQ(PETSC_ERR_SUP,0,"");
2716   ierr = (*mat->ops->getownershiprange)(mat,m,n);CHKERRQ(ierr);
2717   PetscFunctionReturn(0);
2718 }
2719 
2720 #undef __FUNC__
2721 #define __FUNC__ "MatILUFactorSymbolic"
2722 /*@
2723    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
2724    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
2725    to complete the factorization.
2726 
2727    Collective on Mat
2728 
2729    Input Parameters:
2730 +  mat - the matrix
2731 .  row - row permutation
2732 .  column - column permutation
2733 -  info - structure containing
2734 $      levels - number of levels of fill.
2735 $      expected fill - as ratio of original fill.
2736 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2737                 missing diagonal entries)
2738 
2739    Output Parameters:
2740 .  fact - new matrix that has been symbolically factored
2741 
2742    Notes:
2743    See the file ${PETSC_DIR}/Performace for additional information about
2744    choosing the fill factor for better efficiency.
2745 
2746 .keywords: matrix, factor, incomplete, ILU, symbolic, fill
2747 
2748 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric()
2749 @*/
2750 int MatILUFactorSymbolic(Mat mat,IS row,IS col,MatILUInfo *info,Mat *fact)
2751 {
2752   int ierr;
2753 
2754   PetscFunctionBegin;
2755   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2756   PetscValidPointer(fact);
2757   if (info && info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Levels of fill negative %d",info->levels);
2758   if (info && info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Expected fill less than 1.0 %g",info->fill);
2759   if (!mat->ops->ilufactorsymbolic) SETERRQ(PETSC_ERR_SUP,0,"Only MatCreateMPIRowbs() matrices support parallel ILU");
2760   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2761   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2762 
2763   PLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
2764   ierr = (*mat->ops->ilufactorsymbolic)(mat,row,col,info,fact); CHKERRQ(ierr);
2765   PLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
2766   PetscFunctionReturn(0);
2767 }
2768 
2769 #undef __FUNC__
2770 #define __FUNC__ "MatIncompleteCholeskyFactorSymbolic"
2771 /*@
2772    MatIncompleteCholeskyFactorSymbolic - Performs symbolic incomplete
2773    Cholesky factorization for a symmetric matrix.  Use
2774    MatCholeskyFactorNumeric() to complete the factorization.
2775 
2776    Collective on Mat
2777 
2778    Input Parameters:
2779 +  mat - the matrix
2780 .  perm - row and column permutation
2781 .  fill - levels of fill
2782 -  f - expected fill as ratio of original fill
2783 
2784    Output Parameter:
2785 .  fact - the factored matrix
2786 
2787    Note:  Currently only no-fill factorization is supported.
2788 
2789 .keywords: matrix, factor, incomplete, ICC, Cholesky, symbolic, fill
2790 
2791 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor()
2792 @*/
2793 int MatIncompleteCholeskyFactorSymbolic(Mat mat,IS perm,double f,int fill,Mat *fact)
2794 {
2795   int ierr;
2796 
2797   PetscFunctionBegin;
2798   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2799   PetscValidPointer(fact);
2800   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2801   if (fill < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Fill negative %d",fill);
2802   if (f < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Expected fill less than 1.0 %g",f);
2803   if (!mat->ops->incompletecholeskyfactorsymbolic) SETERRQ(PETSC_ERR_SUP,0,"Currently only MatCreateMPIRowbs() matrices support ICC in parallel");
2804   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2805 
2806   PLogEventBegin(MAT_IncompleteCholeskyFactorSymbolic,mat,perm,0,0);
2807   ierr = (*mat->ops->incompletecholeskyfactorsymbolic)(mat,perm,f,fill,fact);CHKERRQ(ierr);
2808   PLogEventEnd(MAT_IncompleteCholeskyFactorSymbolic,mat,perm,0,0);
2809   PetscFunctionReturn(0);
2810 }
2811 
2812 #undef __FUNC__
2813 #define __FUNC__ "MatGetArray"
2814 /*@C
2815    MatGetArray - Returns a pointer to the element values in the matrix.
2816    The result of this routine is dependent on the underlying matrix data
2817    structure, and may not even work for certain matrix types.  You MUST
2818    call MatRestoreArray() when you no longer need to access the array.
2819 
2820    Not Collective
2821 
2822    Input Parameter:
2823 .  mat - the matrix
2824 
2825    Output Parameter:
2826 .  v - the location of the values
2827 
2828    Currently returns an array only for the dense formats, giving access to
2829    the local portion of the matrix in the usual Fortran column-oriented format.
2830 
2831    Fortran Note:
2832    This routine is used differently from Fortran
2833 $    Mat         mat
2834 $    Scalar      mat_array(1)
2835 $    PetscOffset i_mat
2836 $    int         ierr
2837 $       call MatGetArray(mat,mat_array,i_mat,ierr)
2838 $
2839 $   Access first local entry in matrix with
2840 $      value = mat_array(i_mat + 1)
2841 $   (note here array is treated as one dimensional)
2842 $      ...... other code
2843 $       call MatRestoreArray(mat,mat_array,i_mat,ierr)
2844 
2845    See the Fortran chapter of the users manual and
2846    petsc/src/mat/examples/tests for details.
2847 
2848 .keywords: matrix, array, elements, values
2849 
2850 .seealso: MatRestoreArray()
2851 @*/
2852 int MatGetArray(Mat mat,Scalar **v)
2853 {
2854   int ierr;
2855 
2856   PetscFunctionBegin;
2857   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2858   PetscValidPointer(v);
2859   if (!mat->ops->getarray) SETERRQ(PETSC_ERR_SUP,0,"");
2860   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
2861   PetscFunctionReturn(0);
2862 }
2863 
2864 #undef __FUNC__
2865 #define __FUNC__ "MatRestoreArray"
2866 /*@C
2867    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
2868 
2869    Not Collective
2870 
2871    Input Parameter:
2872 +  mat - the matrix
2873 -  v - the location of the values
2874 
2875    Fortran Note:
2876    This routine is used differently from Fortran
2877 $    Mat         mat
2878 $    Scalar      mat_array(1)
2879 $    PetscOffset i_mat
2880 $    int         ierr
2881 $       call MatGetArray(mat,mat_array,i_mat,ierr)
2882 $
2883 $   Access first local entry in matrix with
2884 $      value = mat_array(i_mat + 1)
2885 $   (note here the array is treated as one dimensional)
2886 $
2887 $      ...... other code
2888 $       call MatRestoreArray(mat,mat_array,i_mat,ierr)
2889 
2890    See the Fortran chapter of the users manual and
2891    petsc/src/mat/examples/tests for details
2892 
2893 .keywords: matrix, array, elements, values, restore
2894 
2895 .seealso: MatGetArray()
2896 @*/
2897 int MatRestoreArray(Mat mat,Scalar **v)
2898 {
2899   int ierr;
2900 
2901   PetscFunctionBegin;
2902   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2903   PetscValidPointer(v);
2904   if (!mat->ops->restorearray) SETERRQ(PETSC_ERR_SUP,0,"");
2905   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
2906   PetscFunctionReturn(0);
2907 }
2908 
2909 #undef __FUNC__
2910 #define __FUNC__ "MatGetSubMatrices"
2911 /*@C
2912    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
2913    points to an array of valid matrices, they may be reused to store the new
2914    submatrices.
2915 
2916    Collective on Mat
2917 
2918    Input Parameters:
2919 +  mat - the matrix
2920 .  n   - the number of submatrixes to be extracted
2921 .  irow, icol - index sets of rows and columns to extract
2922 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
2923 
2924    Output Parameter:
2925 .  submat - the array of submatrices
2926 
2927    Notes:
2928    MatGetSubMatrices() can extract only sequential submatrices
2929    (from both sequential and parallel matrices). Use MatGetSubMatrix()
2930    to extract a parallel submatrix.
2931 
2932    When extracting submatrices from a parallel matrix, each processor can
2933    form a different submatrix by setting the rows and columns of its
2934    individual index sets according to the local submatrix desired.
2935 
2936    When finished using the submatrices, the user should destroy
2937    them with MatDestroySubMatrices().
2938 
2939    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
2940    original matrix has not changed from that last call to MatGetSubMatrices()
2941 
2942    Fortran Note:
2943    The Fortran interface is slightly different from that given below, it
2944    requires one to pass in  as submat a Mat (integer) array of size at least m.
2945 
2946 .keywords: matrix, get, submatrix, submatrices
2947 
2948 .seealso: MatDestroyMatrices(), MatGetSubMatrix()
2949 @*/
2950 int MatGetSubMatrices(Mat mat,int n,IS *irow,IS *icol,MatReuse scall,Mat **submat)
2951 {
2952   int ierr;
2953 
2954   PetscFunctionBegin;
2955   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2956   if (!mat->ops->getsubmatrices) SETERRQ(PETSC_ERR_SUP,0,"");
2957   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2958 
2959   PLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
2960   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat); CHKERRQ(ierr);
2961   PLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
2962 
2963   PetscFunctionReturn(0);
2964 }
2965 
2966 #undef __FUNC__
2967 #define __FUNC__ "MatDestroyMatrices"
2968 /*@C
2969    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
2970 
2971    Collective on Mat
2972 
2973    Input Parameters:
2974 +  n - the number of local matrices
2975 -  mat - the matrices
2976 
2977 .keywords: matrix, destroy, submatrix, submatrices
2978 
2979 .seealso: MatGetSubMatrices()
2980 @*/
2981 int MatDestroyMatrices(int n,Mat **mat)
2982 {
2983   int ierr,i;
2984 
2985   PetscFunctionBegin;
2986   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,1,"Trying to destroy negative number of matrices %d",n);
2987   PetscValidPointer(mat);
2988   for ( i=0; i<n; i++ ) {
2989     ierr = MatDestroy((*mat)[i]); CHKERRQ(ierr);
2990   }
2991   if (n) PetscFree(*mat);
2992   PetscFunctionReturn(0);
2993 }
2994 
2995 #undef __FUNC__
2996 #define __FUNC__ "MatIncreaseOverlap"
2997 /*@
2998    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
2999    replaces the index sets by larger ones that represent submatrices with
3000    additional overlap.
3001 
3002    Collective on Mat
3003 
3004    Input Parameters:
3005 +  mat - the matrix
3006 .  n   - the number of index sets
3007 .  is  - the array of pointers to index sets
3008 -  ov  - the additional overlap requested
3009 
3010 .keywords: matrix, overlap, Schwarz
3011 
3012 .seealso: MatGetSubMatrices()
3013 @*/
3014 int MatIncreaseOverlap(Mat mat,int n, IS *is,int ov)
3015 {
3016   int ierr;
3017 
3018   PetscFunctionBegin;
3019   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3020   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
3021   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
3022 
3023   if (ov == 0) PetscFunctionReturn(0);
3024   if (!mat->ops->increaseoverlap) SETERRQ(PETSC_ERR_SUP,0,"");
3025   PLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
3026   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov); CHKERRQ(ierr);
3027   PLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
3028   PetscFunctionReturn(0);
3029 }
3030 
3031 #undef __FUNC__
3032 #define __FUNC__ "MatPrintHelp"
3033 /*@
3034    MatPrintHelp - Prints all the options for the matrix.
3035 
3036    Collective on Mat
3037 
3038    Input Parameter:
3039 .  mat - the matrix
3040 
3041    Options Database Keys:
3042 +  -help - Prints matrix options
3043 -  -h - Prints matrix options
3044 
3045 .keywords: mat, help
3046 
3047 .seealso: MatCreate(), MatCreateXXX()
3048 @*/
3049 int MatPrintHelp(Mat mat)
3050 {
3051   static int called = 0;
3052   int        ierr;
3053   MPI_Comm   comm;
3054 
3055   PetscFunctionBegin;
3056   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3057 
3058   comm = mat->comm;
3059   if (!called) {
3060     (*PetscHelpPrintf)(comm,"General matrix options:\n");
3061     (*PetscHelpPrintf)(comm,"  -mat_view_info: view basic matrix info during MatAssemblyEnd()\n");
3062     (*PetscHelpPrintf)(comm,"  -mat_view_info_detailed: view detailed matrix info during MatAssemblyEnd()\n");
3063     (*PetscHelpPrintf)(comm,"  -mat_view_draw: draw nonzero matrix structure during MatAssemblyEnd()\n");
3064     (*PetscHelpPrintf)(comm,"      -draw_pause <sec>: set seconds of display pause\n");
3065     (*PetscHelpPrintf)(comm,"      -display <name>: set alternate display\n");
3066     called = 1;
3067   }
3068   if (mat->ops->printhelp) {
3069     ierr = (*mat->ops->printhelp)(mat); CHKERRQ(ierr);
3070   }
3071   PetscFunctionReturn(0);
3072 }
3073 
3074 #undef __FUNC__
3075 #define __FUNC__ "MatGetBlockSize"
3076 /*@
3077    MatGetBlockSize - Returns the matrix block size; useful especially for the
3078    block row and block diagonal formats.
3079 
3080    Not Collective
3081 
3082    Input Parameter:
3083 .  mat - the matrix
3084 
3085    Output Parameter:
3086 .  bs - block size
3087 
3088    Notes:
3089    Block diagonal formats are MATSEQBDIAG, MATMPIBDIAG.
3090    Block row formats are MATSEQBAIJ, MATMPIBAIJ
3091 
3092 .keywords: matrix, get, block, size
3093 
3094 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatCreateSeqBDiag(), MatCreateMPIBDiag()
3095 @*/
3096 int MatGetBlockSize(Mat mat,int *bs)
3097 {
3098   int ierr;
3099 
3100   PetscFunctionBegin;
3101   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3102   PetscValidIntPointer(bs);
3103   if (!mat->ops->getblocksize) SETERRQ(PETSC_ERR_SUP,0,"");
3104   ierr = (*mat->ops->getblocksize)(mat,bs);CHKERRQ(ierr);
3105   PetscFunctionReturn(0);
3106 }
3107 
3108 #undef __FUNC__
3109 #define __FUNC__ "MatGetRowIJ"
3110 /*@C
3111     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
3112     EXPERTS ONLY.
3113 
3114    Collective on Mat
3115 
3116     Input Parameters:
3117 +   mat - the matrix
3118 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
3119 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
3120                 symmetrized
3121 
3122     Output Parameters:
3123 +   n - number of rows in the (possibly compressed) matrix
3124 .   ia - the row pointers
3125 .   ja - the column indices
3126 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
3127 
3128 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
3129 @*/
3130 int MatGetRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
3131 {
3132   int ierr;
3133 
3134   PetscFunctionBegin;
3135   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3136   if (ia) PetscValidIntPointer(ia);
3137   if (ja) PetscValidIntPointer(ja);
3138   PetscValidIntPointer(done);
3139   if (!mat->ops->getrowij) *done = PETSC_FALSE;
3140   else {
3141     *done = PETSC_TRUE;
3142     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,n,ia,ja,done); CHKERRQ(ierr);
3143   }
3144   PetscFunctionReturn(0);
3145 }
3146 
3147 #undef __FUNC__
3148 #define __FUNC__ "MatGetColumnIJ"
3149 /*@C
3150     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
3151     EXPERTS ONLY.
3152 
3153     Collective on Mat
3154 
3155     Input Parameters:
3156 +   mat - the matrix
3157 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
3158 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
3159                 symmetrized
3160 
3161     Output Parameters:
3162 +   n - number of columns in the (possibly compressed) matrix
3163 .   ia - the column pointers
3164 .   ja - the row indices
3165 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
3166 
3167 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
3168 @*/
3169 int MatGetColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
3170 {
3171   int ierr;
3172 
3173   PetscFunctionBegin;
3174   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3175   if (ia) PetscValidIntPointer(ia);
3176   if (ja) PetscValidIntPointer(ja);
3177   PetscValidIntPointer(done);
3178 
3179   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
3180   else {
3181     *done = PETSC_TRUE;
3182     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,n,ia,ja,done); CHKERRQ(ierr);
3183   }
3184   PetscFunctionReturn(0);
3185 }
3186 
3187 #undef __FUNC__
3188 #define __FUNC__ "MatRestoreRowIJ"
3189 /*@C
3190     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
3191     MatGetRowIJ(). EXPERTS ONLY.
3192 
3193     Collective on Mat
3194 
3195     Input Parameters:
3196 +   mat - the matrix
3197 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
3198 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
3199                 symmetrized
3200 
3201     Output Parameters:
3202 +   n - size of (possibly compressed) matrix
3203 .   ia - the row pointers
3204 .   ja - the column indices
3205 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
3206 
3207 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
3208 @*/
3209 int MatRestoreRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
3210 {
3211   int ierr;
3212 
3213   PetscFunctionBegin;
3214   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3215   if (ia) PetscValidIntPointer(ia);
3216   if (ja) PetscValidIntPointer(ja);
3217   PetscValidIntPointer(done);
3218 
3219   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
3220   else {
3221     *done = PETSC_TRUE;
3222     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,n,ia,ja,done); CHKERRQ(ierr);
3223   }
3224   PetscFunctionReturn(0);
3225 }
3226 
3227 #undef __FUNC__
3228 #define __FUNC__ "MatRestoreColumnIJ"
3229 /*@C
3230     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
3231     MatGetColumnIJ(). EXPERTS ONLY.
3232 
3233     Collective on Mat
3234 
3235     Input Parameters:
3236 +   mat - the matrix
3237 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
3238 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
3239                 symmetrized
3240 
3241     Output Parameters:
3242 +   n - size of (possibly compressed) matrix
3243 .   ia - the column pointers
3244 .   ja - the row indices
3245 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
3246 
3247 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
3248 @*/
3249 int MatRestoreColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
3250 {
3251   int ierr;
3252 
3253   PetscFunctionBegin;
3254   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3255   if (ia) PetscValidIntPointer(ia);
3256   if (ja) PetscValidIntPointer(ja);
3257   PetscValidIntPointer(done);
3258 
3259   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
3260   else {
3261     *done = PETSC_TRUE;
3262     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,n,ia,ja,done); CHKERRQ(ierr);
3263   }
3264   PetscFunctionReturn(0);
3265 }
3266 
3267 #undef __FUNC__
3268 #define __FUNC__ "MatColoringPatch"
3269 /*@C
3270     MatColoringPatch - EXPERTS ONLY, used inside matrix coloring routines that
3271     use MatGetRowIJ() and/or MatGetColumnIJ().
3272 
3273     Collective on Mat
3274 
3275     Input Parameters:
3276 +   mat - the matrix
3277 .   n   - number of colors
3278 -   colorarray - array indicating color for each column
3279 
3280     Output Parameters:
3281 .   iscoloring - coloring generated using colorarray information
3282 
3283 .seealso: MatGetRowIJ(), MatGetColumnIJ()
3284 
3285 .keywords: mat, coloring, patch
3286 @*/
3287 int MatColoringPatch(Mat mat,int n,int *colorarray,ISColoring *iscoloring)
3288 {
3289   int ierr;
3290 
3291   PetscFunctionBegin;
3292   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3293   PetscValidIntPointer(colorarray);
3294 
3295   if (!mat->ops->coloringpatch) {SETERRQ(PETSC_ERR_SUP,0,"");}
3296   else {
3297     ierr  = (*mat->ops->coloringpatch)(mat,n,colorarray,iscoloring); CHKERRQ(ierr);
3298   }
3299   PetscFunctionReturn(0);
3300 }
3301 
3302 
3303 #undef __FUNC__
3304 #define __FUNC__ "MatSetUnfactored"
3305 /*@
3306    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
3307 
3308    Collective on Mat
3309 
3310    Input Parameter:
3311 .  mat - the factored matrix to be reset
3312 
3313    Notes:
3314    This routine should be used only with factored matrices formed by in-place
3315    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
3316    format).  This option can save memory, for example, when solving nonlinear
3317    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
3318    ILU(0) preconditioner.
3319 
3320   Note that one can specify in-place ILU(0) factorization by calling
3321 $     PCType(pc,PCILU);
3322 $     PCILUSeUseInPlace(pc);
3323   or by using the options -pc_type ilu -pc_ilu_in_place
3324 
3325   In-place factorization ILU(0) can also be used as a local
3326   solver for the blocks within the block Jacobi or additive Schwarz
3327   methods (runtime option: -sub_pc_ilu_in_place).  See the discussion
3328   of these preconditioners in the users manual for details on setting
3329   local solver options.
3330 
3331 .seealso: PCILUSetUseInPlace(), PCLUSetUseInPlace()
3332 
3333 .keywords: matrix-free, in-place ILU, in-place LU
3334 @*/
3335 int MatSetUnfactored(Mat mat)
3336 {
3337   int ierr;
3338 
3339   PetscFunctionBegin;
3340   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3341   mat->factor = 0;
3342   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
3343   ierr = (*mat->ops->setunfactored)(mat); CHKERRQ(ierr);
3344   PetscFunctionReturn(0);
3345 }
3346 
3347 #undef __FUNC__
3348 #define __FUNC__ "MatGetType"
3349 /*@C
3350    MatGetType - Gets the matrix type and name (as a string) from the matrix.
3351 
3352    Not Collective
3353 
3354    Input Parameter:
3355 .  mat - the matrix
3356 
3357    Output Parameter:
3358 +  type - the matrix type (or use PETSC_NULL)
3359 -  name - name of matrix type (or use PETSC_NULL)
3360 
3361 .keywords: matrix, get, type, name
3362 @*/
3363 int MatGetType(Mat mat,MatType *type,char **name)
3364 {
3365   int  itype = (int)mat->type;
3366   char *matname[10];
3367 
3368   PetscFunctionBegin;
3369   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3370 
3371   if (type) *type = (MatType) mat->type;
3372   if (name) {
3373     /* Note:  Be sure that this list corresponds to the enum in mat.h */
3374     matname[0] = "MATSEQDENSE";
3375     matname[1] = "MATSEQAIJ";
3376     matname[2] = "MATMPIAIJ";
3377     matname[3] = "MATSHELL";
3378     matname[4] = "MATMPIROWBS";
3379     matname[5] = "MATSEQBDIAG";
3380     matname[6] = "MATMPIBDIAG";
3381     matname[7] = "MATMPIDENSE";
3382     matname[8] = "MATSEQBAIJ";
3383     matname[9] = "MATMPIBAIJ";
3384 
3385     if (itype < 0 || itype > 9) *name = "Unknown matrix type";
3386     else                        *name = matname[itype];
3387   }
3388   PetscFunctionReturn(0);
3389 }
3390 
3391 /*MC
3392     MatGetArrayF90 - Accesses a matrix array from Fortran90.
3393 
3394     Synopsis:
3395     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
3396 
3397     Not collective
3398 
3399     Input Parameter:
3400 .   x - matrix
3401 
3402     Output Parameters:
3403 +   xx_v - the Fortran90 pointer to the array
3404 -   ierr - error code
3405 
3406     Example of Usage:
3407 .vb
3408       Scalar, pointer xx_v(:)
3409       ....
3410       call MatGetArrayF90(x,xx_v,ierr)
3411       a = xx_v(3)
3412       call MatRestoreArrayF90(x,xx_v,ierr)
3413 .ve
3414 
3415     Notes:
3416      Not yet supported for all F90 compilers
3417 
3418 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
3419 
3420 .keywords:  matrix, array, f90
3421 M*/
3422 
3423 /*MC
3424     MatRestoreArrayF90 - Restores a matrix array that has been
3425     accessed with MatGetArrayF90().
3426 
3427     Synopsis:
3428     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
3429 
3430     Not collective
3431 
3432     Input Parameters:
3433 +   x - matrix
3434 -   xx_v - the Fortran90 pointer to the array
3435 
3436     Output Parameter:
3437 .   ierr - error code
3438 
3439     Example of Usage:
3440 .vb
3441        Scalar, pointer xx_v(:)
3442        ....
3443        call MatGetArrayF90(x,xx_v,ierr)
3444        a = xx_v(3)
3445        call MatRestoreArrayF90(x,xx_v,ierr)
3446 .ve
3447 
3448     Notes:
3449      Not yet supported for all F90 compilers
3450 
3451 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
3452 
3453 .keywords:  matrix, array, f90
3454 M*/
3455 
3456 
3457 #undef __FUNC__
3458 #define __FUNC__ "MatGetSubMatrix"
3459 /*@
3460     MatGetSubMatrix - Gets a single submatrix on the same number of processors
3461                       as the original matrix.
3462 
3463    Collective on Mat
3464 
3465     Input Parameters:
3466 +   mat - the original matrix
3467 .   isrow - rows this processor should obtain
3468 .   iscol - columns for all processors you wish to keep
3469 .   csize - number of columns "local" to this processor (does nothing for sequential
3470             matrices). This should match the result from VecGetLocalSize(x,...) if you
3471             plan to use the matrix in a A*x or use PETSC_DECIDE
3472 -  cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
3473 
3474     Output Parameter:
3475 .   newmat - the new submatrix, of the same type as the old
3476 
3477 .seealso: MatGetSubMatrices()
3478 
3479 @*/
3480 int MatGetSubMatrix(Mat mat,IS isrow,IS iscol,int csize,MatReuse cll,Mat *newmat)
3481 {
3482   int     ierr, size;
3483   Mat     *local;
3484 
3485   PetscFunctionBegin;
3486   MPI_Comm_size(mat->comm,&size);
3487 
3488   /* if original matrix is on just one processor then use submatrix generated */
3489   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
3490     ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
3491     PetscFunctionReturn(0);
3492   } else if (!mat->ops->getsubmatrix && size == 1) {
3493     ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
3494     *newmat = *local;
3495     PetscFree(local);
3496     PetscFunctionReturn(0);
3497   }
3498 
3499   if (!mat->ops->getsubmatrix) SETERRQ(PETSC_ERR_SUP,0,"Not currently implemented");
3500   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscol,csize,cll,newmat);CHKERRQ(ierr);
3501   PetscFunctionReturn(0);
3502 }
3503 
3504 #undef __FUNC__
3505 #define __FUNC__ "MatGetMaps"
3506 /*@C
3507    MatGetMaps - Returns the maps associated with the matrix.
3508 
3509    Not Collective
3510 
3511    Input Parameter:
3512 .  mat - the matrix
3513 
3514    Output Parameters:
3515 +  rmap - the row (right) map
3516 -  cmap - the column (left) map
3517 
3518 .keywords: matrix, get, map
3519 @*/
3520 int MatGetMaps(Mat mat,Map *rmap,Map *cmap)
3521 {
3522   int ierr;
3523 
3524   PetscFunctionBegin;
3525   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3526   ierr = (*mat->ops->getmaps)(mat,rmap,cmap);CHKERRQ(ierr);
3527   PetscFunctionReturn(0);
3528 }
3529 
3530 /*
3531       Version that works for all PETSc matrices
3532 */
3533 #undef __FUNC__
3534 #define __FUNC__ "MatGetMaps_Petsc"
3535 int MatGetMaps_Petsc(Mat mat,Map *rmap,Map *cmap)
3536 {
3537   PetscFunctionBegin;
3538   if (rmap) *rmap = mat->rmap;
3539   if (cmap) *cmap = mat->cmap;
3540   PetscFunctionReturn(0);
3541 }
3542