xref: /petsc/src/mat/interface/matrix.c (revision 84cb2905a512499b542fd30cf471a05f503d96d2)
1 
2 #ifndef lint
3 static char vcid[] = "$Id: matrix.c,v 1.221 1997/01/27 18:16:18 bsmith Exp bsmith $";
4 #endif
5 
6 /*
7    This is where the abstract matrix operations are defined
8 */
9 
10 #include "petsc.h"
11 #include "src/mat/matimpl.h"        /*I "mat.h" I*/
12 #include "src/vec/vecimpl.h"
13 #include "pinclude/pviewer.h"
14 #include "draw.h"
15 
16 
17 #undef __FUNC__
18 #define __FUNC__ "MatGetRow"
19 /*@C
20    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
21    for each row that you get to ensure that your application does
22    not bleed memory.
23 
24    Input Parameters:
25 .  mat - the matrix
26 .  row - the row to get
27 
28    Output Parameters:
29 .  ncols -  the number of nonzeros in the row
30 .  cols - if nonzero, the column numbers
31 .  vals - if nonzero, the values
32 
33    Notes:
34    This routine is provided for people who need to have direct access
35    to the structure of a matrix.  We hope that we provide enough
36    high-level matrix routines that few users will need it.
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    Caution:
46    Do not try to change the contents of the output arrays (cols and vals).
47    In some cases, this may corrupt the matrix.
48 
49 .keywords: matrix, row, get, extract
50 
51 .seealso: MatRestoreRow(), MatSetValues()
52 @*/
53 int MatGetRow(Mat mat,int row,int *ncols,int **cols,Scalar **vals)
54 {
55   int   ierr;
56   PetscValidHeaderSpecific(mat,MAT_COOKIE);
57   PetscValidIntPointer(ncols);
58   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
59   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
60   if (!mat->ops.getrow) SETERRQ(PETSC_ERR_SUP,0,"");
61   PLogEventBegin(MAT_GetRow,mat,0,0,0);
62   ierr = (*mat->ops.getrow)(mat,row,ncols,cols,vals); CHKERRQ(ierr);
63   PLogEventEnd(MAT_GetRow,mat,0,0,0);
64   return 0;
65 }
66 
67 #undef __FUNC__
68 #define __FUNC__ "MatRestoreRow"
69 /*@C
70    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
71 
72    Input Parameters:
73 .  mat - the matrix
74 .  row - the row to get
75 .  ncols, cols - the number of nonzeros and their columns
76 .  vals - if nonzero the column values
77 
78 .keywords: matrix, row, restore
79 
80 .seealso:  MatGetRow()
81 @*/
82 int MatRestoreRow(Mat mat,int row,int *ncols,int **cols,Scalar **vals)
83 {
84   PetscValidHeaderSpecific(mat,MAT_COOKIE);
85   PetscValidIntPointer(ncols);
86   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
87   if (!mat->ops.restorerow) return 0;
88   return (*mat->ops.restorerow)(mat,row,ncols,cols,vals);
89 }
90 
91 #undef __FUNC__
92 #define __FUNC__ "MatView"
93 /*@C
94    MatView - Visualizes a matrix object.
95 
96    Input Parameters:
97 .  mat - the matrix
98 .  ptr - visualization context
99 
100    Notes:
101    The available visualization contexts include
102 $     VIEWER_STDOUT_SELF - standard output (default)
103 $     VIEWER_STDOUT_WORLD - synchronized standard
104 $       output where only the first processor opens
105 $       the file.  All other processors send their
106 $       data to the first processor to print.
107 $     VIEWER_DRAWX_WORLD - graphical display of nonzero structure
108 
109    The user can open alternative vistualization contexts with
110 $    ViewerFileOpenASCII() - output to a specified file
111 $    ViewerFileOpenBinary() - output in binary to a
112 $         specified file; corresponding input uses MatLoad()
113 $    ViewerDrawOpenX() - output nonzero matrix structure to
114 $         an X window display
115 $    ViewerMatlabOpen() - output matrix to Matlab viewer.
116 $         Currently only the sequential dense and AIJ
117 $         matrix types support the Matlab viewer.
118 
119    The user can call ViewerSetFormat() to specify the output
120    format of ASCII printed objects (when using VIEWER_STDOUT_SELF,
121    VIEWER_STDOUT_WORLD and ViewerFileOpenASCII).  Available formats include
122 $    VIEWER_FORMAT_ASCII_DEFAULT - default, prints matrix contents
123 $    VIEWER_FORMAT_ASCII_MATLAB - Matlab format
124 $    VIEWER_FORMAT_ASCII_IMPL - implementation-specific format
125 $      (which is in many cases the same as the default)
126 $    VIEWER_FORMAT_ASCII_INFO - basic information about the matrix
127 $      size and structure (not the matrix entries)
128 $    VIEWER_FORMAT_ASCII_INFO_LONG - more detailed information about the
129 $      matrix structure
130 
131 .keywords: matrix, view, visualize, output, print, write, draw
132 
133 .seealso: ViewerSetFormat(), ViewerFileOpenASCII(), ViewerDrawOpenX(),
134           ViewerMatlabOpen(), ViewerFileOpenBinary(), MatLoad()
135 @*/
136 int MatView(Mat mat,Viewer viewer)
137 {
138   int          format, ierr, rows, cols;
139   FILE         *fd;
140   char         *cstr;
141   ViewerType   vtype;
142   MPI_Comm     comm = mat->comm;
143 
144   PetscValidHeaderSpecific(mat,MAT_COOKIE);
145   if (viewer) PetscValidHeaderSpecific(viewer,VIEWER_COOKIE);
146   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
147 
148   if (!viewer) {
149     viewer = VIEWER_STDOUT_SELF;
150   }
151 
152   ierr = ViewerGetType(viewer,&vtype);
153   if (vtype == ASCII_FILE_VIEWER || vtype == ASCII_FILES_VIEWER) {
154     ierr = ViewerGetFormat(viewer,&format); CHKERRQ(ierr);
155     ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr);
156     if (format == VIEWER_FORMAT_ASCII_INFO || format == VIEWER_FORMAT_ASCII_INFO_LONG) {
157       PetscFPrintf(comm,fd,"Matrix Object:\n");
158       ierr = MatGetType(mat,PETSC_NULL,&cstr); CHKERRQ(ierr);
159       ierr = MatGetSize(mat,&rows,&cols); CHKERRQ(ierr);
160       PetscFPrintf(comm,fd,"  type=%s, rows=%d, cols=%d\n",cstr,rows,cols);
161       if (mat->ops.getinfo) {
162         MatInfo info;
163         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info); CHKERRQ(ierr);
164         PetscFPrintf(comm,fd,"  total: nonzeros=%d, allocated nonzeros=%d\n",
165                      (int)info.nz_used,(int)info.nz_allocated);
166       }
167     }
168   }
169   if (mat->view) {ierr = (*mat->view)((PetscObject)mat,viewer); CHKERRQ(ierr);}
170   return 0;
171 }
172 
173 #undef __FUNC__
174 #define __FUNC__ "MatDestroy"
175 /*@C
176    MatDestroy - Frees space taken by a matrix.
177 
178    Input Parameter:
179 .  mat - the matrix
180 
181 .keywords: matrix, destroy
182 @*/
183 int MatDestroy(Mat mat)
184 {
185   int ierr;
186   PetscValidHeaderSpecific(mat,MAT_COOKIE);
187   ierr = (*mat->destroy)((PetscObject)mat); CHKERRQ(ierr);
188   return 0;
189 }
190 
191 #undef __FUNC__
192 #define __FUNC__ "MatValid"
193 /*@
194    MatValid - Checks whether a matrix object is valid.
195 
196    Input Parameter:
197 .  m - the matrix to check
198 
199    Output Parameter:
200    flg - flag indicating matrix status, either
201 $     PETSC_TRUE if matrix is valid;
202 $     PETSC_FALSE otherwise.
203 
204 .keywords: matrix, valid
205 @*/
206 int MatValid(Mat m,PetscTruth *flg)
207 {
208   PetscValidIntPointer(flg);
209   if (!m)                           *flg = PETSC_FALSE;
210   else if (m->cookie != MAT_COOKIE) *flg = PETSC_FALSE;
211   else                              *flg = PETSC_TRUE;
212   return 0;
213 }
214 
215 #undef __FUNC__
216 #define __FUNC__ "MatSetValues"
217 /*@
218    MatSetValues - Inserts or adds a block of values into a matrix.
219    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
220    MUST be called after all calls to MatSetValues() have been completed.
221 
222    Input Parameters:
223 .  mat - the matrix
224 .  v - a logically two-dimensional array of values
225 .  m, indexm - the number of rows and their global indices
226 .  n, indexn - the number of columns and their global indices
227 .  addv - either ADD_VALUES or INSERT_VALUES, where
228 $     ADD_VALUES - adds values to any existing entries
229 $     INSERT_VALUES - replaces existing entries with new values
230 
231    Notes:
232    By default the values, v, are row-oriented and unsorted.
233    See MatSetOptions() for other options.
234 
235    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
236    options cannot be mixed without intervening calls to the assembly
237    routines.
238 
239    MatSetValues() uses 0-based row and column numbers in Fortran
240    as well as in C.
241 
242 .keywords: matrix, insert, add, set, values
243 
244 .seealso: MatSetOptions(), MatAssemblyBegin(), MatAssemblyEnd()
245 @*/
246 int MatSetValues(Mat mat,int m,int *idxm,int n,int *idxn,Scalar *v,InsertMode addv)
247 {
248   int ierr;
249   PetscValidHeaderSpecific(mat,MAT_COOKIE);
250   if (!m || !n) return 0; /* no values to insert */
251   PetscValidIntPointer(idxm);
252   PetscValidIntPointer(idxn);
253   PetscValidScalarPointer(v);
254   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
255 
256   if (mat->assembled) {
257     mat->was_assembled = PETSC_TRUE;
258     mat->assembled     = PETSC_FALSE;
259   }
260   PLogEventBegin(MAT_SetValues,mat,0,0,0);
261   ierr = (*mat->ops.setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
262   PLogEventEnd(MAT_SetValues,mat,0,0,0);
263   return 0;
264 }
265 
266 #undef __FUNC__
267 #define __FUNC__ "MatSetValuesBlocked"
268 /*@
269    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
270 
271    Input Parameters:
272 .  mat - the matrix
273 .  v - a logically two-dimensional array of values
274 .  m, indexm - the number of rows and their global indices
275 .  n, indexn - the number of columns and their global indices
276 .  addv - either ADD_VALUES or INSERT_VALUES, where
277 $     ADD_VALUES - adds values to any existing entries
278 $     INSERT_VALUES - replaces existing entries with new values
279 
280    Notes:
281    By default the values, v, are row-oriented and unsorted.
282    See MatSetOptions() for other options.
283 
284    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
285    options cannot be mixed without intervening calls to the assembly
286    routines.
287 
288    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
289    as well as in C.
290 
291 .keywords: matrix, insert, add, set, values
292 
293 .seealso: MatSetOptions(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues()
294 @*/
295 int MatSetValuesBlocked(Mat mat,int m,int *idxm,int n,int *idxn,Scalar *v,InsertMode addv)
296 {
297   int ierr;
298   PetscValidHeaderSpecific(mat,MAT_COOKIE);
299   if (!m || !n) return 0; /* no values to insert */
300   PetscValidIntPointer(idxm);
301   PetscValidIntPointer(idxn);
302   PetscValidScalarPointer(v);
303   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
304 
305   if (mat->assembled) {
306     mat->was_assembled = PETSC_TRUE;
307     mat->assembled     = PETSC_FALSE;
308   }
309   PLogEventBegin(MAT_SetValues,mat,0,0,0);
310   ierr = (*mat->ops.setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
311   PLogEventEnd(MAT_SetValues,mat,0,0,0);
312   return 0;
313 }
314 
315 /*MC
316    MatSetValue - Set a single entry into a matrix.
317 
318    Input Parameters:
319 .  m - the matrix
320 .  row - the row location of the entry
321 .  col - the column location of the entry
322 .  value - the value to insert
323 .  mode - either INSERT_VALUES or ADD_VALUES
324 
325    Synopsis:
326    void MatSetValue(Mat m,int row,int col,Scalar value,InsertMode mode);
327 
328    Notes: For efficiency one should use MatSetValues() and set
329 several or many values simultaneously.
330 
331 .seealso: MatSetValues()
332 M*/
333 
334 #undef __FUNC__
335 #define __FUNC__ "MatGetValues"
336 /*@
337    MatGetValues - Gets a block of values from a matrix.
338 
339    Input Parameters:
340 .  mat - the matrix
341 .  v - a logically two-dimensional array for storing the values
342 .  m, indexm - the number of rows and their global indices
343 .  n, indexn - the number of columns and their global indices
344 
345    Notes:
346    The user must allocate space (m*n Scalars) for the values, v.
347    The values, v, are then returned in a row-oriented format,
348    analogous to that used by default in MatSetValues().
349 
350    MatGetValues() uses 0-based row and column numbers in
351    Fortran as well as in C.
352 
353 .keywords: matrix, get, values
354 
355 .seealso: MatGetRow(), MatGetSubmatrices(), MatSetValues()
356 @*/
357 int MatGetValues(Mat mat,int m,int *idxm,int n,int *idxn,Scalar *v)
358 {
359   int ierr;
360 
361   PetscValidHeaderSpecific(mat,MAT_COOKIE);
362   PetscValidIntPointer(idxm);
363   PetscValidIntPointer(idxn);
364   PetscValidScalarPointer(v);
365   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
366   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
367   if (!mat->ops.getvalues) SETERRQ(PETSC_ERR_SUP,0,"");
368 
369   PLogEventBegin(MAT_GetValues,mat,0,0,0);
370   ierr = (*mat->ops.getvalues)(mat,m,idxm,n,idxn,v); CHKERRQ(ierr);
371   PLogEventEnd(MAT_GetValues,mat,0,0,0);
372   return 0;
373 }
374 
375 #undef __FUNC__
376 #define __FUNC__ "MatSetLocalToGlobalMapping"
377 /*@
378    MatSetLocalToGlobalMapping - Sets a local numbering to global numbering used
379      by the routine MatSetValuesLocal() to allow users to insert matrices entries
380      using a local (per-processor) numbering.
381 
382    Input Parameters:
383 .  x - the matrix
384 .  n - number of local indices
385 .  indices - global index for each local index
386 
387 .keywords: matrix, set, values, local ordering
388 
389 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
390 @*/
391 int MatSetLocalToGlobalMapping(Mat x, int n,int *indices)
392 {
393   int ierr;
394   PetscValidHeaderSpecific(x,MAT_COOKIE);
395   PetscValidIntPointer(indices);
396 
397   if (x->mapping) {
398     SETERRQ(1,0,"Mapping already set for matrix");
399   }
400 
401   ierr = ISLocalToGlobalMappingCreate(n,indices,&x->mapping);CHKERRQ(ierr);
402   return 0;
403 }
404 
405 #undef __FUNC__
406 #define __FUNC__ "MatSetValuesLocal"
407 /*@
408    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
409         using a local ordering of the nodes.
410 
411    Input Parameters:
412 .  x - matrix to insert in
413 .  nrow - number of row elements to add
414 .  irow - row indices where to add
415 .  ncol - number of column elements to add
416 .  icol - column indices where to add
417 .  y - array of values
418 .  iora - either INSERT_VALUES or ADD_VALUES
419 
420    Notes:
421    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
422    options cannot be mixed without intervening calls to the assembly
423    routines.
424    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
425    MUST be called after all calls to MatSetValuesLocal() have been completed.
426 
427 .keywords: matrix, set, values, local ordering
428 
429 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping()
430 @*/
431 int MatSetValuesLocal(Mat x,int nrow,int *irow,int ncol, int *icol,Scalar *y,InsertMode iora)
432 {
433   int ierr,irowm[128],icolm[128];
434 
435   PetscValidHeaderSpecific(x,MAT_COOKIE);
436   PetscValidIntPointer(irow);
437   PetscValidIntPointer(icol);
438   PetscValidScalarPointer(y);
439   if (!x->mapping) {
440     SETERRQ(1,0,"Local to global never set with MatSetLocalToGlobalMapping");
441   }
442   if (nrow > 128 || ncol > 128) {
443     SETERRQ(1,0,"Number indices must be <= 128");
444   }
445   if (x->factor) SETERRQ(1,0,"Not for factored matrix");
446 
447   if (x->assembled) {
448     x->was_assembled = PETSC_TRUE;
449     x->assembled     = PETSC_FALSE;
450   }
451   PLogEventBegin(MAT_SetValues,x,0,0,0);
452   ISLocalToGlobalMappingApply(x->mapping,nrow,irow,irowm);
453   ISLocalToGlobalMappingApply(x->mapping,ncol,icol,icolm);
454   ierr = (*x->ops.setvalues)(x,nrow,irowm,ncol,icolm,y,iora);CHKERRQ(ierr);
455   PLogEventEnd(MAT_SetValues,x,0,0,0);
456   return 0;
457 }
458 
459 /* --------------------------------------------------------*/
460 #undef __FUNC__
461 #define __FUNC__ "MatMult"
462 /*@
463    MatMult - Computes the matrix-vector product, y = Ax.
464 
465    Input Parameters:
466 .  mat - the matrix
467 .  x   - the vector to be multilplied
468 
469    Output Parameters:
470 .  y - the result
471 
472    Notes:
473    The vectors x and y cannot be the same.  I.e., one cannot
474    call MatMult(A,y,y).
475 
476 .keywords: matrix, multiply, matrix-vector product
477 
478 .seealso: MatMultTrans(), MatMultAdd(), MatMultTransAdd()
479 @*/
480 int MatMult(Mat mat,Vec x,Vec y)
481 {
482   int ierr;
483   PetscValidHeaderSpecific(mat,MAT_COOKIE);
484   PetscValidHeaderSpecific(x,VEC_COOKIE);PetscValidHeaderSpecific(y,VEC_COOKIE);
485   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
486   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
487   if (x == y) SETERRQ(1,0,"x and y must be different vectors");
488   if (mat->N != x->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim");
489   if (mat->M != y->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec y: global dim");
490   if (mat->m != y->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec y: local dim");
491 
492   PLogEventBegin(MAT_Mult,mat,x,y,0);
493   ierr = (*mat->ops.mult)(mat,x,y); CHKERRQ(ierr);
494   PLogEventEnd(MAT_Mult,mat,x,y,0);
495 
496   return 0;
497 }
498 
499 #undef __FUNC__
500 #define __FUNC__ "MatMultTrans"
501 /*@
502    MatMultTrans - Computes matrix transpose times a vector.
503 
504    Input Parameters:
505 .  mat - the matrix
506 .  x   - the vector to be multilplied
507 
508    Output Parameters:
509 .  y - the result
510 
511    Notes:
512    The vectors x and y cannot be the same.  I.e., one cannot
513    call MatMultTrans(A,y,y).
514 
515 .keywords: matrix, multiply, matrix-vector product, transpose
516 
517 .seealso: MatMult(), MatMultAdd(), MatMultTransAdd()
518 @*/
519 int MatMultTrans(Mat mat,Vec x,Vec y)
520 {
521   int ierr;
522   PetscValidHeaderSpecific(mat,MAT_COOKIE);
523   PetscValidHeaderSpecific(x,VEC_COOKIE); PetscValidHeaderSpecific(y,VEC_COOKIE);
524   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
525   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
526   if (x == y) SETERRQ(1,0,"x and y must be different vectors");
527   if (mat->M != x->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim");
528   if (mat->N != y->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec y: global dim");
529   PLogEventBegin(MAT_MultTrans,mat,x,y,0);
530   ierr = (*mat->ops.multtrans)(mat,x,y); CHKERRQ(ierr);
531   PLogEventEnd(MAT_MultTrans,mat,x,y,0);
532   return 0;
533 }
534 
535 #undef __FUNC__
536 #define __FUNC__ "MatMultAdd"
537 /*@
538     MatMultAdd -  Computes v3 = v2 + A * v1.
539 
540     Input Parameters:
541 .   mat - the matrix
542 .   v1, v2 - the vectors
543 
544     Output Parameters:
545 .   v3 - the result
546 
547    Notes:
548    The vectors v1 and v3 cannot be the same.  I.e., one cannot
549    call MatMultAdd(A,v1,v2,v1).
550 
551 .keywords: matrix, multiply, matrix-vector product, add
552 
553 .seealso: MatMultTrans(), MatMult(), MatMultTransAdd()
554 @*/
555 int MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
556 {
557   int ierr;
558   PetscValidHeaderSpecific(mat,MAT_COOKIE);PetscValidHeaderSpecific(v1,VEC_COOKIE);
559   PetscValidHeaderSpecific(v2,VEC_COOKIE); PetscValidHeaderSpecific(v3,VEC_COOKIE);
560   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
561   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
562   if (mat->N != v1->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v1: global dim");
563   if (mat->M != v2->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v2: global dim");
564   if (mat->M != v3->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v3: global dim");
565   if (mat->m != v3->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v3: local dim");
566   if (mat->m != v2->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v2: local dim");
567   if (v1 == v3) SETERRQ(1,0,"v1 and v3 must be different vectors");
568 
569   PLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
570   ierr = (*mat->ops.multadd)(mat,v1,v2,v3); CHKERRQ(ierr);
571   PLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
572   return 0;
573 }
574 
575 #undef __FUNC__
576 #define __FUNC__ "MatMultTransAdd"
577 /*@
578    MatMultTransAdd - Computes v3 = v2 + A' * v1.
579 
580    Input Parameters:
581 .  mat - the matrix
582 .  v1, v2 - the vectors
583 
584    Output Parameters:
585 .  v3 - the result
586 
587    Notes:
588    The vectors v1 and v3 cannot be the same.  I.e., one cannot
589    call MatMultTransAdd(A,v1,v2,v1).
590 
591 .keywords: matrix, multiply, matrix-vector product, transpose, add
592 
593 .seealso: MatMultTrans(), MatMultAdd(), MatMult()
594 @*/
595 int MatMultTransAdd(Mat mat,Vec v1,Vec v2,Vec v3)
596 {
597   int ierr;
598   PetscValidHeaderSpecific(mat,MAT_COOKIE);PetscValidHeaderSpecific(v1,VEC_COOKIE);
599   PetscValidHeaderSpecific(v2,VEC_COOKIE);PetscValidHeaderSpecific(v3,VEC_COOKIE);
600   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
601   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
602   if (!mat->ops.multtransadd) SETERRQ(PETSC_ERR_SUP,0,"");
603   if (v1 == v3) SETERRQ(1,0,"v1 and v3 must be different vectors");
604   if (mat->M != v1->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v1: global dim");
605   if (mat->N != v2->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v2: global dim");
606   if (mat->N != v3->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v3: global dim");
607 
608   PLogEventBegin(MAT_MultTransAdd,mat,v1,v2,v3);
609   ierr = (*mat->ops.multtransadd)(mat,v1,v2,v3); CHKERRQ(ierr);
610   PLogEventEnd(MAT_MultTransAdd,mat,v1,v2,v3);
611   return 0;
612 }
613 /* ------------------------------------------------------------*/
614 #undef __FUNC__
615 #define __FUNC__ "MatGetInfo"
616 /*@C
617    MatGetInfo - Returns information about matrix storage (number of
618    nonzeros, memory, etc.).
619 
620    Input Parameters:
621 .  mat - the matrix
622 
623    Output Parameters:
624 .  flag - flag indicating the type of parameters to be returned
625 $    flag = MAT_LOCAL: local matrix
626 $    flag = MAT_GLOBAL_MAX: maximum over all processors
627 $    flag = MAT_GLOBAL_SUM: sum over all processors
628 .  info - matrix information context
629 
630    Notes:
631    The MatInfo context contains a variety of matrix data, including
632    number of nonzeros allocated and used, number of mallocs during
633    matrix assembly, etc.  Additional information for factored matrices
634    is provided (such as the fill ratio, number of mallocs during
635    factorization, etc.).  Much of this info is printed to STDOUT
636    when using the runtime options
637 $       -log_info -mat_view_info
638 
639    Example for C/C++ Users:
640    See the file $(PETSC_DIR)/include/mat.h for a complete list of
641    data within the MatInfo context.  For example,
642 $
643 $      MatInfo *info;
644 $      Mat     A;
645 $      double  mal, nz_a, nz_u;
646 $
647 $      MatGetInfo(A,MAT_LOCAL,&info);
648 $      mal  = info->mallocs;
649 $      nz_a = info->nz_allocated;
650 $
651 
652    Example for Fortran Users:
653    Fortran users should declare info as a double precision
654    array of dimension MAT_INFO_SIZE, and then extract the parameters
655    of interest.  See the file $(PETSC_DIR)/include/FINCLUDE/mat.h
656    a complete list of parameter names.
657 $
658 $      double  precision info(MAT_INFO_SIZE)
659 $      double  precision mal, nz_a
660 $      Mat     A
661 $      integer ierr
662 $
663 $      call MatGetInfo(A,MAT_LOCAL,info,ierr)
664 $      mal = info(MAT_INFO_MALLOCS)
665 $      nz_a = info(MAT_INFO_NZ_ALLOCATED)
666 $
667 
668 .keywords: matrix, get, info, storage, nonzeros, memory, fill
669 @*/
670 int MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
671 {
672   PetscValidHeaderSpecific(mat,MAT_COOKIE);
673   PetscValidPointer(info);
674   if (!mat->ops.getinfo) SETERRQ(PETSC_ERR_SUP,0,"");
675   return  (*mat->ops.getinfo)(mat,flag,info);
676 }
677 
678 /* ----------------------------------------------------------*/
679 #undef __FUNC__
680 #define __FUNC__ "MatILUDTFactor"
681 /*@
682    MatILUDTFactor - Performs a drop tolerance ILU factorization.
683 
684    Input Parameters:
685 .  mat - the matrix
686 .  dt  - the drop tolerance
687 .  maxnz - the maximum number of nonzeros per row allowed?
688 .  row - row permutation
689 .  col - column permutation
690 
691    Output Parameters:
692 .  fact - the factored matrix
693 
694 .keywords: matrix, factor, LU, in-place
695 
696 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
697 @*/
698 int MatILUDTFactor(Mat mat,double dt,int maxnz,IS row,IS col,Mat *fact)
699 {
700   int ierr;
701   PetscValidHeaderSpecific(mat,MAT_COOKIE);
702   PetscValidPointer(fact);
703   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
704   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
705   if (!mat->ops.iludtfactor) SETERRQ(PETSC_ERR_SUP,0,"");
706 
707   PLogEventBegin(MAT_ILUFactor,mat,row,col,0);
708   ierr = (*mat->ops.iludtfactor)(mat,dt,maxnz,row,col,fact); CHKERRQ(ierr);
709   PLogEventEnd(MAT_ILUFactor,mat,row,col,0);
710 
711   return 0;
712 }
713 
714 #undef __FUNC__
715 #define __FUNC__ "MatLUFactor"
716 /*@
717    MatLUFactor - Performs in-place LU factorization of matrix.
718 
719    Input Parameters:
720 .  mat - the matrix
721 .  row - row permutation
722 .  col - column permutation
723 .  f - expected fill as ratio of original fill.
724 
725 .keywords: matrix, factor, LU, in-place
726 
727 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
728 @*/
729 int MatLUFactor(Mat mat,IS row,IS col,double f)
730 {
731   int ierr;
732   PetscValidHeaderSpecific(mat,MAT_COOKIE);
733   if (mat->M != mat->N) SETERRQ(1,0,"matrix must be square");
734   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
735   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
736   if (!mat->ops.lufactor) SETERRQ(PETSC_ERR_SUP,0,"");
737 
738   PLogEventBegin(MAT_LUFactor,mat,row,col,0);
739   ierr = (*mat->ops.lufactor)(mat,row,col,f); CHKERRQ(ierr);
740   PLogEventEnd(MAT_LUFactor,mat,row,col,0);
741   return 0;
742 }
743 
744 #undef __FUNC__
745 #define __FUNC__ "MatLUFactorSymbolic"
746 /*@
747    MatILUFactor - Performs in-place ILU factorization of matrix.
748 
749    Input Parameters:
750 .  mat - the matrix
751 .  row - row permutation
752 .  col - column permutation
753 .  f - expected fill as ratio of original fill.
754 .  level - number of levels of fill.
755 
756    Note: probably really only in-place when level is zero.
757 .keywords: matrix, factor, ILU, in-place
758 
759 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
760 @*/
761 int MatILUFactor(Mat mat,IS row,IS col,double f,int level)
762 {
763   int ierr;
764   PetscValidHeaderSpecific(mat,MAT_COOKIE);
765   if (mat->M != mat->N) SETERRQ(1,0,"matrix must be square");
766   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
767   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
768   if (!mat->ops.ilufactor) SETERRQ(PETSC_ERR_SUP,0,"");
769 
770   PLogEventBegin(MAT_ILUFactor,mat,row,col,0);
771   ierr = (*mat->ops.ilufactor)(mat,row,col,f,level); CHKERRQ(ierr);
772   PLogEventEnd(MAT_ILUFactor,mat,row,col,0);
773   return 0;
774 }
775 
776 #undef __FUNC__
777 #define __FUNC__ "MatLUFactorSymbolic"
778 /*@
779    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
780    Call this routine before calling MatLUFactorNumeric().
781 
782    Input Parameters:
783 .  mat - the matrix
784 .  row, col - row and column permutations
785 .  f - expected fill as ratio of the original number of nonzeros,
786        for example 3.0; choosing this parameter well can result in
787        more efficient use of time and space.
788 
789    Output Parameter:
790 .  fact - new matrix that has been symbolically factored
791 
792    Options Database Key:
793 $     -mat_lu_fill <f>, where f is the fill ratio
794 
795    Notes:
796    See the file $(PETSC_DIR)/Performace for additional information about
797    choosing the fill factor for better efficiency.
798 
799 .keywords: matrix, factor, LU, symbolic, fill
800 
801 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor()
802 @*/
803 int MatLUFactorSymbolic(Mat mat,IS row,IS col,double f,Mat *fact)
804 {
805   int ierr,flg;
806   PetscValidHeaderSpecific(mat,MAT_COOKIE);
807   if (mat->M != mat->N) SETERRQ(1,0,"matrix must be square");
808   if (!fact) SETERRQ(1,0,"Missing factor matrix argument");
809   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
810   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
811   if (!mat->ops.lufactorsymbolic) SETERRQ(PETSC_ERR_SUP,0,"");
812 
813   ierr = OptionsGetDouble(PETSC_NULL,"-mat_lu_fill",&f,&flg); CHKERRQ(ierr);
814   PLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
815   ierr = (*mat->ops.lufactorsymbolic)(mat,row,col,f,fact); CHKERRQ(ierr);
816   PLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
817   return 0;
818 }
819 
820 #undef __FUNC__
821 #define __FUNC__ "MatLUFactorNumeric"
822 /*@
823    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
824    Call this routine after first calling MatLUFactorSymbolic().
825 
826    Input Parameters:
827 .  mat - the matrix
828 .  row, col - row and  column permutations
829 
830    Output Parameters:
831 .  fact - symbolically factored matrix that must have been generated
832           by MatLUFactorSymbolic()
833 
834    Notes:
835    See MatLUFactor() for in-place factorization.  See
836    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
837 
838 .keywords: matrix, factor, LU, numeric
839 
840 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
841 @*/
842 int MatLUFactorNumeric(Mat mat,Mat *fact)
843 {
844   int ierr,flg;
845 
846   PetscValidHeaderSpecific(mat,MAT_COOKIE);
847   if (!fact) SETERRQ(1,0,"Missing factor matrix argument");
848   PetscValidHeaderSpecific(*fact,MAT_COOKIE);
849   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
850   if (mat->M != (*fact)->M || mat->N != (*fact)->N)
851     SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Mat *fact: global dim");
852   if (!mat->ops.lufactornumeric) SETERRQ(PETSC_ERR_SUP,0,"");
853 
854   PLogEventBegin(MAT_LUFactorNumeric,mat,*fact,0,0);
855   ierr = (*mat->ops.lufactornumeric)(mat,fact); CHKERRQ(ierr);
856   PLogEventEnd(MAT_LUFactorNumeric,mat,*fact,0,0);
857   ierr = OptionsHasName(PETSC_NULL,"-mat_view_draw",&flg); CHKERRQ(ierr);
858   if (flg) {
859     ierr = OptionsHasName(0,"-mat_view_contour",&flg); CHKERRQ(ierr);
860     if (flg) {
861       ViewerPushFormat(VIEWER_DRAWX_(mat->comm),VIEWER_FORMAT_DRAW_CONTOUR,0);CHKERRQ(ierr);
862     }
863     ierr = MatView(*fact,VIEWER_DRAWX_(mat->comm)); CHKERRQ(ierr);
864     ierr = ViewerFlush(VIEWER_DRAWX_(mat->comm)); CHKERRQ(ierr);
865     if (flg) {
866       ViewerPopFormat(VIEWER_DRAWX_(mat->comm));CHKERRQ(ierr);
867     }
868   }
869   return 0;
870 }
871 
872 #undef __FUNC__
873 #define __FUNC__ "MatCholeskyFactor"
874 /*@
875    MatCholeskyFactor - Performs in-place Cholesky factorization of a
876    symmetric matrix.
877 
878    Input Parameters:
879 .  mat - the matrix
880 .  perm - row and column permutations
881 .  f - expected fill as ratio of original fill
882 
883    Notes:
884    See MatLUFactor() for the nonsymmetric case.  See also
885    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
886 
887 .keywords: matrix, factor, in-place, Cholesky
888 
889 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
890 @*/
891 int MatCholeskyFactor(Mat mat,IS perm,double f)
892 {
893   int ierr;
894   PetscValidHeaderSpecific(mat,MAT_COOKIE);
895   if (mat->M != mat->N) SETERRQ(1,0,"matrix must be square");
896   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
897   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
898   if (!mat->ops.choleskyfactor) SETERRQ(PETSC_ERR_SUP,0,"");
899 
900   PLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
901   ierr = (*mat->ops.choleskyfactor)(mat,perm,f); CHKERRQ(ierr);
902   PLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
903   return 0;
904 }
905 
906 #undef __FUNC__
907 #define __FUNC__ "MatCholeskyFactorSymbolic"
908 /*@
909    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
910    of a symmetric matrix.
911 
912    Input Parameters:
913 .  mat - the matrix
914 .  perm - row and column permutations
915 .  f - expected fill as ratio of original
916 
917    Output Parameter:
918 .  fact - the factored matrix
919 
920    Notes:
921    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
922    MatCholeskyFactor() and MatCholeskyFactorNumeric().
923 
924 .keywords: matrix, factor, factorization, symbolic, Cholesky
925 
926 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
927 @*/
928 int MatCholeskyFactorSymbolic(Mat mat,IS perm,double f,Mat *fact)
929 {
930   int ierr;
931   PetscValidHeaderSpecific(mat,MAT_COOKIE);
932   PetscValidPointer(fact);
933   if (mat->M != mat->N) SETERRQ(1,0,"matrix must be square");
934   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
935   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
936   if (!mat->ops.choleskyfactorsymbolic) SETERRQ(PETSC_ERR_SUP,0,"");
937 
938   PLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
939   ierr = (*mat->ops.choleskyfactorsymbolic)(mat,perm,f,fact); CHKERRQ(ierr);
940   PLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
941   return 0;
942 }
943 
944 #undef __FUNC__
945 #define __FUNC__ "MatCholeskyFactorNumeric"
946 /*@
947    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
948    of a symmetric matrix. Call this routine after first calling
949    MatCholeskyFactorSymbolic().
950 
951    Input Parameter:
952 .  mat - the initial matrix
953 
954    Output Parameter:
955 .  fact - the factored matrix
956 
957 .keywords: matrix, factor, numeric, Cholesky
958 
959 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
960 @*/
961 int MatCholeskyFactorNumeric(Mat mat,Mat *fact)
962 {
963   int ierr;
964   PetscValidHeaderSpecific(mat,MAT_COOKIE);
965   if (!fact) SETERRQ(1,0,"Missing factor matrix argument");
966   if (!mat->ops.choleskyfactornumeric) SETERRQ(PETSC_ERR_SUP,0,"");
967   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
968   if (mat->M != (*fact)->M || mat->N != (*fact)->N)
969     SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Mat *fact: global dim");
970 
971   PLogEventBegin(MAT_CholeskyFactorNumeric,mat,*fact,0,0);
972   ierr = (*mat->ops.choleskyfactornumeric)(mat,fact); CHKERRQ(ierr);
973   PLogEventEnd(MAT_CholeskyFactorNumeric,mat,*fact,0,0);
974   return 0;
975 }
976 
977 /* ----------------------------------------------------------------*/
978 #undef __FUNC__
979 #define __FUNC__ "MatSolve"
980 /*@
981    MatSolve - Solves A x = b, given a factored matrix.
982 
983    Input Parameters:
984 .  mat - the factored matrix
985 .  b - the right-hand-side vector
986 
987    Output Parameter:
988 .  x - the result vector
989 
990    Notes:
991    The vectors b and x cannot be the same.  I.e., one cannot
992    call MatSolve(A,x,x).
993 
994 .keywords: matrix, linear system, solve, LU, Cholesky, triangular solve
995 
996 .seealso: MatSolveAdd(), MatSolveTrans(), MatSolveTransAdd()
997 @*/
998 int MatSolve(Mat mat,Vec b,Vec x)
999 {
1000   int ierr;
1001   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1002   PetscValidHeaderSpecific(b,VEC_COOKIE); PetscValidHeaderSpecific(x,VEC_COOKIE);
1003   if (x == b) SETERRQ(1,0,"x and b must be different vectors");
1004   if (!mat->factor) SETERRQ(1,0,"Unfactored matrix");
1005   if (mat->N != x->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim");
1006   if (mat->M != b->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: global dim");
1007   if (mat->m != b->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: local dim");
1008 
1009   if (!mat->ops.solve) SETERRQ(PETSC_ERR_SUP,0,"");
1010   PLogEventBegin(MAT_Solve,mat,b,x,0);
1011   ierr = (*mat->ops.solve)(mat,b,x); CHKERRQ(ierr);
1012   PLogEventEnd(MAT_Solve,mat,b,x,0);
1013   return 0;
1014 }
1015 
1016 #undef __FUNC__
1017 #define __FUNC__ "MatForwardSolve"
1018 /* @
1019    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU.
1020 
1021    Input Parameters:
1022 .  mat - the factored matrix
1023 .  b - the right-hand-side vector
1024 
1025    Output Parameter:
1026 .  x - the result vector
1027 
1028    Notes:
1029    MatSolve() should be used for most applications, as it performs
1030    a forward solve followed by a backward solve.
1031 
1032    The vectors b and x cannot be the same.  I.e., one cannot
1033    call MatForwardSolve(A,x,x).
1034 
1035 .keywords: matrix, forward, LU, Cholesky, triangular solve
1036 
1037 .seealso: MatSolve(), MatBackwardSolve()
1038 @ */
1039 int MatForwardSolve(Mat mat,Vec b,Vec x)
1040 {
1041   int ierr;
1042   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1043   PetscValidHeaderSpecific(b,VEC_COOKIE);  PetscValidHeaderSpecific(x,VEC_COOKIE);
1044   if (x == b) SETERRQ(1,0,"x and b must be different vectors");
1045   if (!mat->factor) SETERRQ(1,0,"Unfactored matrix");
1046   if (!mat->ops.forwardsolve) SETERRQ(PETSC_ERR_SUP,0,"");
1047   if (mat->N != x->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim");
1048   if (mat->M != b->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: global dim");
1049   if (mat->m != b->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: local dim");
1050 
1051   PLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
1052   ierr = (*mat->ops.forwardsolve)(mat,b,x); CHKERRQ(ierr);
1053   PLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
1054   return 0;
1055 }
1056 
1057 #undef __FUNC__
1058 #define __FUNC__ "MatBackwardSolve"
1059 /* @
1060    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
1061 
1062    Input Parameters:
1063 .  mat - the factored matrix
1064 .  b - the right-hand-side vector
1065 
1066    Output Parameter:
1067 .  x - the result vector
1068 
1069    Notes:
1070    MatSolve() should be used for most applications, as it performs
1071    a forward solve followed by a backward solve.
1072 
1073    The vectors b and x cannot be the same.  I.e., one cannot
1074    call MatBackwardSolve(A,x,x).
1075 
1076 .keywords: matrix, backward, LU, Cholesky, triangular solve
1077 
1078 .seealso: MatSolve(), MatForwardSolve()
1079 @ */
1080 int MatBackwardSolve(Mat mat,Vec b,Vec x)
1081 {
1082   int ierr;
1083   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1084   PetscValidHeaderSpecific(b,VEC_COOKIE);  PetscValidHeaderSpecific(x,VEC_COOKIE);
1085   if (x == b) SETERRQ(1,0,"x and b must be different vectors");
1086   if (!mat->factor) SETERRQ(1,0,"Unfactored matrix");
1087   if (!mat->ops.backwardsolve) SETERRQ(PETSC_ERR_SUP,0,"");
1088   if (mat->N != x->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim");
1089   if (mat->M != b->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: global dim");
1090   if (mat->m != b->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: local dim");
1091 
1092   PLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
1093   ierr = (*mat->ops.backwardsolve)(mat,b,x); CHKERRQ(ierr);
1094   PLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
1095   return 0;
1096 }
1097 
1098 #undef __FUNC__
1099 #define __FUNC__ "MatSolveAdd"
1100 /*@
1101    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
1102 
1103    Input Parameters:
1104 .  mat - the factored matrix
1105 .  b - the right-hand-side vector
1106 .  y - the vector to be added to
1107 
1108    Output Parameter:
1109 .  x - the result vector
1110 
1111    Notes:
1112    The vectors b and x cannot be the same.  I.e., one cannot
1113    call MatSolveAdd(A,x,y,x).
1114 
1115 .keywords: matrix, linear system, solve, LU, Cholesky, add
1116 
1117 .seealso: MatSolve(), MatSolveTrans(), MatSolveTransAdd()
1118 @*/
1119 int MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
1120 {
1121   Scalar one = 1.0;
1122   Vec    tmp;
1123   int    ierr;
1124   PetscValidHeaderSpecific(mat,MAT_COOKIE);PetscValidHeaderSpecific(y,VEC_COOKIE);
1125   PetscValidHeaderSpecific(b,VEC_COOKIE);  PetscValidHeaderSpecific(x,VEC_COOKIE);
1126   if (x == b) SETERRQ(1,0,"x and b must be different vectors");
1127   if (!mat->factor) SETERRQ(1,0,"Unfactored matrix");
1128   if (mat->N != x->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim");
1129   if (mat->M != b->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: global dim");
1130   if (mat->M != y->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec y: global dim");
1131   if (mat->m != b->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: local dim");
1132   if (x->n != y->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Vec x,Vec y: local dim");
1133 
1134   PLogEventBegin(MAT_SolveAdd,mat,b,x,y);
1135   if (mat->ops.solveadd)  {
1136     ierr = (*mat->ops.solveadd)(mat,b,y,x); CHKERRQ(ierr);
1137   }
1138   else {
1139     /* do the solve then the add manually */
1140     if (x != y) {
1141       ierr = MatSolve(mat,b,x); CHKERRQ(ierr);
1142       ierr = VecAXPY(&one,y,x); CHKERRQ(ierr);
1143     }
1144     else {
1145       ierr = VecDuplicate(x,&tmp); CHKERRQ(ierr);
1146       PLogObjectParent(mat,tmp);
1147       ierr = VecCopy(x,tmp); CHKERRQ(ierr);
1148       ierr = MatSolve(mat,b,x); CHKERRQ(ierr);
1149       ierr = VecAXPY(&one,tmp,x); CHKERRQ(ierr);
1150       ierr = VecDestroy(tmp); CHKERRQ(ierr);
1151     }
1152   }
1153   PLogEventEnd(MAT_SolveAdd,mat,b,x,y);
1154   return 0;
1155 }
1156 
1157 #undef __FUNC__
1158 #define __FUNC__ "MatSolveTrans"
1159 /*@
1160    MatSolveTrans - Solves A' x = b, given a factored matrix.
1161 
1162    Input Parameters:
1163 .  mat - the factored matrix
1164 .  b - the right-hand-side vector
1165 
1166    Output Parameter:
1167 .  x - the result vector
1168 
1169    Notes:
1170    The vectors b and x cannot be the same.  I.e., one cannot
1171    call MatSolveTrans(A,x,x).
1172 
1173 .keywords: matrix, linear system, solve, LU, Cholesky, transpose
1174 
1175 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransAdd()
1176 @*/
1177 int MatSolveTrans(Mat mat,Vec b,Vec x)
1178 {
1179   int ierr;
1180   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1181   PetscValidHeaderSpecific(b,VEC_COOKIE);  PetscValidHeaderSpecific(x,VEC_COOKIE);
1182   if (!mat->factor) SETERRQ(1,0,"Unfactored matrix");
1183   if (x == b) SETERRQ(1,0,"x and b must be different vectors");
1184   if (!mat->ops.solvetrans) SETERRQ(PETSC_ERR_SUP,0,"");
1185   if (mat->M != x->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim");
1186   if (mat->N != b->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: global dim");
1187 
1188   PLogEventBegin(MAT_SolveTrans,mat,b,x,0);
1189   ierr = (*mat->ops.solvetrans)(mat,b,x); CHKERRQ(ierr);
1190   PLogEventEnd(MAT_SolveTrans,mat,b,x,0);
1191   return 0;
1192 }
1193 
1194 #undef __FUNC__
1195 #define __FUNC__ "MatSolveTransAdd"
1196 /*@
1197    MatSolveTransAdd - Computes x = y + inv(trans(A)) b, given a
1198                       factored matrix.
1199 
1200    Input Parameters:
1201 .  mat - the factored matrix
1202 .  b - the right-hand-side vector
1203 .  y - the vector to be added to
1204 
1205    Output Parameter:
1206 .  x - the result vector
1207 
1208    Notes:
1209    The vectors b and x cannot be the same.  I.e., one cannot
1210    call MatSolveTransAdd(A,x,y,x).
1211 
1212 .keywords: matrix, linear system, solve, LU, Cholesky, transpose, add
1213 
1214 .seealso: MatSolve(), MatSolveAdd(), MatSolveTrans()
1215 @*/
1216 int MatSolveTransAdd(Mat mat,Vec b,Vec y,Vec x)
1217 {
1218   Scalar one = 1.0;
1219   int    ierr;
1220   Vec    tmp;
1221   PetscValidHeaderSpecific(mat,MAT_COOKIE);PetscValidHeaderSpecific(y,VEC_COOKIE);
1222   PetscValidHeaderSpecific(b,VEC_COOKIE);  PetscValidHeaderSpecific(x,VEC_COOKIE);
1223   if (x == b) SETERRQ(1,0,"x and b must be different vectors");
1224   if (!mat->factor) SETERRQ(1,0,"Unfactored matrix");
1225   if (mat->M != x->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim");
1226   if (mat->N != b->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: global dim");
1227   if (mat->N != y->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec y: global dim");
1228   if (x->n != y->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Vec x,Vec y: local dim");
1229 
1230   PLogEventBegin(MAT_SolveTransAdd,mat,b,x,y);
1231   if (mat->ops.solvetransadd) {
1232     ierr = (*mat->ops.solvetransadd)(mat,b,y,x); CHKERRQ(ierr);
1233   }
1234   else {
1235     /* do the solve then the add manually */
1236     if (x != y) {
1237       ierr = MatSolveTrans(mat,b,x); CHKERRQ(ierr);
1238       ierr = VecAXPY(&one,y,x); CHKERRQ(ierr);
1239     }
1240     else {
1241       ierr = VecDuplicate(x,&tmp); CHKERRQ(ierr);
1242       PLogObjectParent(mat,tmp);
1243       ierr = VecCopy(x,tmp); CHKERRQ(ierr);
1244       ierr = MatSolveTrans(mat,b,x); CHKERRQ(ierr);
1245       ierr = VecAXPY(&one,tmp,x); CHKERRQ(ierr);
1246       ierr = VecDestroy(tmp); CHKERRQ(ierr);
1247     }
1248   }
1249   PLogEventEnd(MAT_SolveTransAdd,mat,b,x,y);
1250   return 0;
1251 }
1252 /* ----------------------------------------------------------------*/
1253 
1254 #undef __FUNC__
1255 #define __FUNC__ "MatRelax"
1256 /*@
1257    MatRelax - Computes one relaxation sweep.
1258 
1259    Input Parameters:
1260 .  mat - the matrix
1261 .  b - the right hand side
1262 .  omega - the relaxation factor
1263 .  flag - flag indicating the type of SOR, one of
1264 $     SOR_FORWARD_SWEEP
1265 $     SOR_BACKWARD_SWEEP
1266 $     SOR_SYMMETRIC_SWEEP (SSOR method)
1267 $     SOR_LOCAL_FORWARD_SWEEP
1268 $     SOR_LOCAL_BACKWARD_SWEEP
1269 $     SOR_LOCAL_SYMMETRIC_SWEEP (local SSOR)
1270 $     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
1271 $       upper/lower triangular part of matrix to
1272 $       vector (with omega)
1273 $     SOR_ZERO_INITIAL_GUESS - zero initial guess
1274 .  shift -  diagonal shift
1275 .  its - the number of iterations
1276 
1277    Output Parameters:
1278 .  x - the solution (can contain an initial guess)
1279 
1280    Notes:
1281    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
1282    SOR_LOCAL_SYMMETRIC_SWEEP perform seperate independent smoothings
1283    on each processor.
1284 
1285    Application programmers will not generally use MatRelax() directly,
1286    but instead will employ the SLES/PC interface.
1287 
1288    Notes for Advanced Users:
1289    The flags are implemented as bitwise inclusive or operations.
1290    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
1291    to specify a zero initial guess for SSOR.
1292 
1293 .keywords: matrix, relax, relaxation, sweep
1294 @*/
1295 int MatRelax(Mat mat,Vec b,double omega,MatSORType flag,double shift,
1296              int its,Vec x)
1297 {
1298   int ierr;
1299   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1300   PetscValidHeaderSpecific(b,VEC_COOKIE);  PetscValidHeaderSpecific(x,VEC_COOKIE);
1301   if (!mat->ops.relax) SETERRQ(PETSC_ERR_SUP,0,"");
1302   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
1303   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
1304   if (mat->N != x->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim");
1305   if (mat->M != b->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: global dim");
1306   if (mat->m != b->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: local dim");
1307 
1308   PLogEventBegin(MAT_Relax,mat,b,x,0);
1309   ierr =(*mat->ops.relax)(mat,b,omega,flag,shift,its,x); CHKERRQ(ierr);
1310   PLogEventEnd(MAT_Relax,mat,b,x,0);
1311   return 0;
1312 }
1313 
1314 #undef __FUNC__
1315 #define __FUNC__ "MatCopy_Basic"
1316 /*
1317       Default matrix copy routine.
1318 */
1319 int MatCopy_Basic(Mat A,Mat B)
1320 {
1321   int    ierr,i,rstart,rend,nz,*cwork;
1322   Scalar *vwork;
1323 
1324   ierr = MatZeroEntries(B); CHKERRQ(ierr);
1325   ierr = MatGetOwnershipRange(A,&rstart,&rend); CHKERRQ(ierr);
1326   for (i=rstart; i<rend; i++) {
1327     ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
1328     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
1329     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
1330   }
1331   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1332   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1333   return 0;
1334 }
1335 
1336 #undef __FUNC__
1337 #define __FUNC__ "MatCopy"
1338 /*@C
1339    MatCopy - Copys a matrix to another matrix.
1340 
1341    Input Parameters:
1342 .  A - the matrix
1343 
1344    Output Parameter:
1345 .  B - where the copy is put
1346 
1347    Notes:
1348    MatCopy() copies the matrix entries of a matrix to another existing
1349    matrix (after first zeroing the second matrix).  A related routine is
1350    MatConvert(), which first creates a new matrix and then copies the data.
1351 
1352 .keywords: matrix, copy, convert
1353 
1354 .seealso: MatConvert()
1355 @*/
1356 int MatCopy(Mat A,Mat B)
1357 {
1358   int ierr;
1359   PetscValidHeaderSpecific(A,MAT_COOKIE); PetscValidHeaderSpecific(B,MAT_COOKIE);
1360   if (!A->assembled) SETERRQ(1,0,"Not for unassembled matrix");
1361   if (A->factor) SETERRQ(1,0,"Not for factored matrix");
1362   if (A->M != B->M || A->N != B->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat A,Mat B: global dim");
1363 
1364   PLogEventBegin(MAT_Copy,A,B,0,0);
1365   if (A->ops.copy) {
1366     ierr = (*A->ops.copy)(A,B); CHKERRQ(ierr);
1367   }
1368   else { /* generic conversion */
1369     ierr = MatCopy_Basic(A,B); CHKERRQ(ierr);
1370   }
1371   PLogEventEnd(MAT_Copy,A,B,0,0);
1372   return 0;
1373 }
1374 
1375 static int MatConvertersSet = 0;
1376 static int (*MatConverters[MAX_MATRIX_TYPES][MAX_MATRIX_TYPES])(Mat,MatType,Mat*) =
1377            {{0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0},
1378             {0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0},
1379             {0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0},
1380             {0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0},
1381             {0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0},
1382             {0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0}};
1383 
1384 #undef __FUNC__
1385 #define __FUNC__ "MatConvertRegister"
1386 /*@C
1387     MatConvertRegister - Allows one to register a routine that converts between
1388         two matrix types.
1389 
1390   Input Parameters:
1391 .   intype - the type of matrix (defined in include/mat.h), for example, MATSEQAIJ.
1392 .   outtype - new matrix type, or MATSAME
1393 
1394 .seealso: MatConvertRegisterAll()
1395 
1396 @*/
1397 int MatConvertRegister(MatType intype,MatType outtype,int (*converter)(Mat,MatType,Mat*))
1398 {
1399   MatConverters[intype][outtype] = converter;
1400   MatConvertersSet               = 1;
1401   return 0;
1402 }
1403 
1404 #undef __FUNC__
1405 #define __FUNC__ "MatConvert"
1406 /*@C
1407    MatConvert - Converts a matrix to another matrix, either of the same
1408    or different type.
1409 
1410    Input Parameters:
1411 .  mat - the matrix
1412 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
1413    same type as the original matrix.
1414 
1415    Output Parameter:
1416 .  M - pointer to place new matrix
1417 
1418    Notes:
1419    MatConvert() first creates a new matrix and then copies the data from
1420    the first matrix.  A related routine is MatCopy(), which copies the matrix
1421    entries of one matrix to another already existing matrix context.
1422 
1423 .keywords: matrix, copy, convert
1424 
1425 .seealso: MatCopy()
1426 @*/
1427 int MatConvert(Mat mat,MatType newtype,Mat *M)
1428 {
1429   int ierr;
1430   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1431   if (!M) SETERRQ(1,0,"Bad new matrix address");
1432   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
1433   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
1434 
1435   if (newtype > MAX_MATRIX_TYPES || newtype < -1) {
1436     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,1,"Not a valid matrix type");
1437   }
1438   *M  = 0;
1439 
1440   if (!MatConvertersSet) {
1441     ierr = MatLoadRegisterAll(); CHKERRQ(ierr);
1442   }
1443 
1444   PLogEventBegin(MAT_Convert,mat,0,0,0);
1445   if ((newtype == mat->type || newtype == MATSAME) && mat->ops.convertsametype) {
1446     ierr = (*mat->ops.convertsametype)(mat,M,COPY_VALUES); CHKERRQ(ierr);
1447   } else {
1448     if (!MatConvertersSet) {
1449       ierr = MatConvertRegisterAll(); CHKERRQ(ierr);
1450     }
1451     if (!MatConverters[mat->type][newtype]) {
1452       SETERRQ(PETSC_ERR_ARG_WRONG,1,"Invalid matrix type, or matrix converter not registered");
1453     }
1454     ierr = (*MatConverters[mat->type][newtype])(mat,newtype,M); CHKERRQ(ierr);
1455   }
1456   PLogEventEnd(MAT_Convert,mat,0,0,0);
1457   return 0;
1458 }
1459 
1460 #undef __FUNC__
1461 #define __FUNC__ "MatGetDiagonal"
1462 /*@
1463    MatGetDiagonal - Gets the diagonal of a matrix.
1464 
1465    Input Parameters:
1466 .  mat - the matrix
1467 .  v - the vector for storing the diagonal
1468 
1469    Output Parameter:
1470 .  v - the diagonal of the matrix
1471 
1472    Notes: For the SeqAIJ matrix format, this routine may also be called
1473     on a LU factored matrix; in that case it routines the reciprocal of
1474     the diagonal entries in U. It returns the entries permuted by the
1475     row and column permutation used during the symbolic factorization.
1476 
1477 .keywords: matrix, get, diagonal
1478 @*/
1479 int MatGetDiagonal(Mat mat,Vec v)
1480 {
1481   PetscValidHeaderSpecific(mat,MAT_COOKIE);PetscValidHeaderSpecific(v,VEC_COOKIE);
1482   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
1483   /*
1484      The error checking for a factored matrix is handled inside
1485     each matrix type, since MatGetDiagonal() is supported by
1486     factored AIJ matrices
1487   */
1488   /* if (mat->factor) SETERRQ(1,0,"Not for factored matrix");  */
1489   if (!mat->ops.getdiagonal) SETERRQ(PETSC_ERR_SUP,0,"");
1490   return (*mat->ops.getdiagonal)(mat,v);
1491 }
1492 
1493 #undef __FUNC__
1494 #define __FUNC__ "MatTranspose"
1495 /*@C
1496    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
1497 
1498    Input Parameter:
1499 .  mat - the matrix to transpose
1500 
1501    Output Parameters:
1502 .  B - the transpose (or pass in PETSC_NULL for an in-place transpose)
1503 
1504 .keywords: matrix, transpose
1505 
1506 .seealso: MatMultTrans(), MatMultTransAdd()
1507 @*/
1508 int MatTranspose(Mat mat,Mat *B)
1509 {
1510   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1511   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
1512   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
1513   if (!mat->ops.transpose) SETERRQ(PETSC_ERR_SUP,0,"");
1514   return (*mat->ops.transpose)(mat,B);
1515 }
1516 
1517 #undef __FUNC__
1518 #define __FUNC__ "MatPermute"
1519 /*@C
1520    MatPermute - Creates a new matrix with rows and columns permuted from the
1521        original.
1522 
1523    Input Parameter:
1524 .  mat - the matrix to permute
1525 .  row - row permutation
1526 .  col - column permutation
1527 
1528    Output Parameters:
1529 .  B - the permuted matrix
1530 
1531 .keywords: matrix, transpose
1532 
1533 .seealso: MatGetReordering()
1534 @*/
1535 int MatPermute(Mat mat,IS row,IS col,Mat *B)
1536 {
1537   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1538   PetscValidHeaderSpecific(row,IS_COOKIE);
1539   PetscValidHeaderSpecific(col,IS_COOKIE);
1540   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
1541   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
1542   if (!mat->ops.permute) SETERRQ(PETSC_ERR_SUP,0,"");
1543   return (*mat->ops.permute)(mat,row,col,B);
1544 }
1545 
1546 #undef __FUNC__
1547 #define __FUNC__ "MatEqual"
1548 /*@
1549    MatEqual - Compares two matrices.
1550 
1551    Input Parameters:
1552 .  A - the first matrix
1553 .  B - the second matrix
1554 
1555    Output Parameter:
1556 .  flg : PETSC_TRUE if the matrices are equal;
1557          PETSC_FALSE otherwise.
1558 
1559 .keywords: matrix, equal, equivalent
1560 @*/
1561 int MatEqual(Mat A,Mat B,PetscTruth *flg)
1562 {
1563   PetscValidHeaderSpecific(A,MAT_COOKIE); PetscValidHeaderSpecific(B,MAT_COOKIE);
1564   PetscValidIntPointer(flg);
1565   if (!A->assembled) SETERRQ(1,0,"Not for unassembled matrix");
1566   if (!B->assembled) SETERRQ(1,0,"Not for unassembled matrix");
1567   if (A->M != B->M || A->N != B->N) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Mat A,Mat B: global dim");
1568   if (!A->ops.equal) SETERRQ(PETSC_ERR_SUP,0,"");
1569   return (*A->ops.equal)(A,B,flg);
1570 }
1571 
1572 #undef __FUNC__
1573 #define __FUNC__ "MatDiagonalScale"
1574 /*@
1575    MatDiagonalScale - Scales a matrix on the left and right by diagonal
1576    matrices that are stored as vectors.  Either of the two scaling
1577    matrices can be PETSC_NULL.
1578 
1579    Input Parameters:
1580 .  mat - the matrix to be scaled
1581 .  l - the left scaling vector (or PETSC_NULL)
1582 .  r - the right scaling vector (or PETSC_NULL)
1583 
1584    Notes:
1585    MatDiagonalScale() computes A <- LAR, where
1586 $      L = a diagonal matrix
1587 $      R = a diagonal matrix
1588 
1589 .keywords: matrix, diagonal, scale
1590 
1591 .seealso: MatDiagonalScale()
1592 @*/
1593 int MatDiagonalScale(Mat mat,Vec l,Vec r)
1594 {
1595   int ierr;
1596   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1597   if (!mat->ops.diagonalscale) SETERRQ(PETSC_ERR_SUP,0,"");
1598   if (l) PetscValidHeaderSpecific(l,VEC_COOKIE);
1599   if (r) PetscValidHeaderSpecific(r,VEC_COOKIE);
1600   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
1601   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
1602 
1603   PLogEventBegin(MAT_Scale,mat,0,0,0);
1604   ierr = (*mat->ops.diagonalscale)(mat,l,r); CHKERRQ(ierr);
1605   PLogEventEnd(MAT_Scale,mat,0,0,0);
1606   return 0;
1607 }
1608 
1609 #undef __FUNC__
1610 #define __FUNC__ "MatScale"
1611 /*@
1612     MatScale - Scales all elements of a matrix by a given number.
1613 
1614     Input Parameters:
1615 .   mat - the matrix to be scaled
1616 .   a  - the scaling value
1617 
1618     Output Parameter:
1619 .   mat - the scaled matrix
1620 
1621 .keywords: matrix, scale
1622 
1623 .seealso: MatDiagonalScale()
1624 @*/
1625 int MatScale(Scalar *a,Mat mat)
1626 {
1627   int ierr;
1628   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1629   PetscValidScalarPointer(a);
1630   if (!mat->ops.scale) SETERRQ(PETSC_ERR_SUP,0,"");
1631   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
1632   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
1633 
1634   PLogEventBegin(MAT_Scale,mat,0,0,0);
1635   ierr = (*mat->ops.scale)(a,mat); CHKERRQ(ierr);
1636   PLogEventEnd(MAT_Scale,mat,0,0,0);
1637   return 0;
1638 }
1639 
1640 #undef __FUNC__
1641 #define __FUNC__ "MatNorm"
1642 /*@
1643    MatNorm - Calculates various norms of a matrix.
1644 
1645    Input Parameters:
1646 .  mat - the matrix
1647 .  type - the type of norm, NORM_1, NORM_2, NORM_FROBENIUS, NORM_INFINITY
1648 
1649    Output Parameters:
1650 .  norm - the resulting norm
1651 
1652 .keywords: matrix, norm, Frobenius
1653 @*/
1654 int MatNorm(Mat mat,NormType type,double *norm)
1655 {
1656   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1657   PetscValidScalarPointer(norm);
1658 
1659   if (!norm) SETERRQ(1,0,"bad addess for value");
1660   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
1661   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
1662   if (!mat->ops.norm) SETERRQ(PETSC_ERR_SUP,0,"Not for this matrix type");
1663   return (*mat->ops.norm)(mat,type,norm);
1664 }
1665 
1666 /*
1667      This variable is used to prevent counting of MatAssemblyBegin() that
1668    are called from within a MatAssemblyEnd().
1669 */
1670 static int MatAssemblyEnd_InUse = 0;
1671 #undef __FUNC__
1672 #define __FUNC__ "MatAssemblyBegin"
1673 /*@
1674    MatAssemblyBegin - Begins assembling the matrix.  This routine should
1675    be called after completing all calls to MatSetValues().
1676 
1677    Input Parameters:
1678 .  mat - the matrix
1679 .  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
1680 
1681    Notes:
1682    MatSetValues() generally caches the values.  The matrix is ready to
1683    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
1684    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
1685    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
1686    using the matrix.
1687 
1688 .keywords: matrix, assembly, assemble, begin
1689 
1690 .seealso: MatAssemblyEnd(), MatSetValues()
1691 @*/
1692 int MatAssemblyBegin(Mat mat,MatAssemblyType type)
1693 {
1694   int ierr;
1695   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1696   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
1697   if (mat->assembled) {
1698     mat->was_assembled = PETSC_TRUE;
1699     mat->assembled     = PETSC_FALSE;
1700   }
1701   if (!MatAssemblyEnd_InUse) {
1702     PLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
1703     if (mat->ops.assemblybegin){ierr = (*mat->ops.assemblybegin)(mat,type);CHKERRQ(ierr);}
1704     PLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
1705   } else {
1706     if (mat->ops.assemblybegin){ierr = (*mat->ops.assemblybegin)(mat,type);CHKERRQ(ierr);}
1707   }
1708   return 0;
1709 }
1710 
1711 #undef __FUNC__
1712 #define __FUNC__ "MatAssemblyEnd"
1713 /*@
1714    MatAssemblyEnd - Completes assembling the matrix.  This routine should
1715    be called after MatAssemblyBegin().
1716 
1717    Input Parameters:
1718 .  mat - the matrix
1719 .  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
1720 
1721    Options Database Keys:
1722 $  -mat_view_info : Prints info on matrix at
1723 $      conclusion of MatEndAssembly()
1724 $  -mat_view_info_detailed: Prints more detailed info.
1725 $  -mat_view : Prints matrix in ASCII format.
1726 $  -mat_view_matlab : Prints matrix in Matlab format.
1727 $  -mat_view_draw : Draws nonzero structure of matrix,
1728 $      using MatView() and DrawOpenX().
1729 $  -display <name> : Set display name (default is host)
1730 $  -draw_pause <sec> : Set number of seconds to pause after display
1731 
1732    Notes:
1733    MatSetValues() generally caches the values.  The matrix is ready to
1734    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
1735    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
1736    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
1737    using the matrix.
1738 
1739 .keywords: matrix, assembly, assemble, end
1740 
1741 .seealso: MatAssemblyBegin(), MatSetValues(), DrawOpenX(), MatView()
1742 @*/
1743 int MatAssemblyEnd(Mat mat,MatAssemblyType type)
1744 {
1745   int        ierr,flg;
1746   static int inassm = 0;
1747 
1748   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1749   inassm++;
1750   MatAssemblyEnd_InUse++;
1751   PLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
1752   if (mat->ops.assemblyend) {
1753     ierr = (*mat->ops.assemblyend)(mat,type); CHKERRQ(ierr);
1754   }
1755   mat->assembled = PETSC_TRUE; mat->num_ass++;
1756   PLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
1757   MatAssemblyEnd_InUse--;
1758 
1759   if (inassm == 1) {
1760     ierr = OptionsHasName(PETSC_NULL,"-mat_view_info",&flg); CHKERRQ(ierr);
1761     if (flg) {
1762       Viewer viewer;
1763       ierr = ViewerFileOpenASCII(mat->comm,"stdout",&viewer);CHKERRQ(ierr);
1764       ierr = ViewerSetFormat(viewer,VIEWER_FORMAT_ASCII_INFO,0);CHKERRQ(ierr);
1765       ierr = MatView(mat,viewer); CHKERRQ(ierr);
1766       ierr = ViewerDestroy(viewer); CHKERRQ(ierr);
1767     }
1768     ierr = OptionsHasName(PETSC_NULL,"-mat_view_info_detailed",&flg);CHKERRQ(ierr);
1769     if (flg) {
1770       Viewer viewer;
1771       ierr = ViewerFileOpenASCII(mat->comm,"stdout",&viewer);CHKERRQ(ierr);
1772       ierr = ViewerSetFormat(viewer,VIEWER_FORMAT_ASCII_INFO_LONG,0);CHKERRQ(ierr);
1773       ierr = MatView(mat,viewer); CHKERRQ(ierr);
1774       ierr = ViewerDestroy(viewer); CHKERRQ(ierr);
1775     }
1776     ierr = OptionsHasName(PETSC_NULL,"-mat_view",&flg); CHKERRQ(ierr);
1777     if (flg) {
1778       Viewer viewer;
1779       ierr = ViewerFileOpenASCII(mat->comm,"stdout",&viewer);CHKERRQ(ierr);
1780       ierr = MatView(mat,viewer); CHKERRQ(ierr);
1781       ierr = ViewerDestroy(viewer); CHKERRQ(ierr);
1782     }
1783     ierr = OptionsHasName(PETSC_NULL,"-mat_view_matlab",&flg); CHKERRQ(ierr);
1784     if (flg) {
1785       Viewer viewer;
1786       ierr = ViewerFileOpenASCII(mat->comm,"stdout",&viewer);CHKERRQ(ierr);
1787       ierr = ViewerSetFormat(viewer,VIEWER_FORMAT_ASCII_MATLAB,"M");CHKERRQ(ierr);
1788       ierr = MatView(mat,viewer); CHKERRQ(ierr);
1789       ierr = ViewerDestroy(viewer); CHKERRQ(ierr);
1790     }
1791     ierr = OptionsHasName(PETSC_NULL,"-mat_view_draw",&flg); CHKERRQ(ierr);
1792     if (flg) {
1793       ierr = OptionsHasName(0,"-mat_view_contour",&flg); CHKERRQ(ierr);
1794       if (flg) {
1795         ViewerPushFormat(VIEWER_DRAWX_(mat->comm),VIEWER_FORMAT_DRAW_CONTOUR,0);CHKERRQ(ierr);
1796       }
1797       ierr = MatView(mat,VIEWER_DRAWX_(mat->comm)); CHKERRQ(ierr);
1798       ierr = ViewerFlush(VIEWER_DRAWX_(mat->comm)); CHKERRQ(ierr);
1799       if (flg) {
1800         ViewerPopFormat(VIEWER_DRAWX_(mat->comm));CHKERRQ(ierr);
1801       }
1802     }
1803   }
1804   inassm--;
1805   return 0;
1806 }
1807 
1808 
1809 #undef __FUNC__
1810 #define __FUNC__ "MatCompress"
1811 /*@
1812    MatCompress - Tries to store the matrix in as little space as
1813    possible.  May fail if memory is already fully used, since it
1814    tries to allocate new space.
1815 
1816    Input Parameters:
1817 .  mat - the matrix
1818 
1819 .keywords: matrix, compress
1820 @*/
1821 int MatCompress(Mat mat)
1822 {
1823   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1824   if (mat->ops.compress) return (*mat->ops.compress)(mat);
1825   return 0;
1826 }
1827 
1828 #undef __FUNC__
1829 #define __FUNC__ "MatSetOption"
1830 /*@
1831    MatSetOption - Sets a parameter option for a matrix. Some options
1832    may be specific to certain storage formats.  Some options
1833    determine how values will be inserted (or added). Sorted,
1834    row-oriented input will generally assemble the fastest. The default
1835    is row-oriented, nonsorted input.
1836 
1837    Input Parameters:
1838 .  mat - the matrix
1839 .  option - the option, one of the following:
1840 $    MAT_ROW_ORIENTED
1841 $    MAT_COLUMN_ORIENTED,
1842 $    MAT_ROWS_SORTED,
1843 $    MAT_ROWS_UNSORTED,
1844 $    MAT_COLUMNS_SORTED,
1845 $    MAT_COLUMNS_UNSORTED,
1846 $    MAT_NO_NEW_NONZERO_LOCATIONS,
1847 $    MAT_YES_NEW_NONZERO_LOCATIONS,
1848 $    MAT_SYMMETRIC,
1849 $    MAT_STRUCTURALLY_SYMMETRIC,
1850 $    MAT_NO_NEW_DIAGONALS,
1851 $    MAT_YES_NEW_DIAGONALS,
1852 $    MAT_IGNORE_OFF_PROCESSOR_ENTRIES
1853 $    and possibly others.
1854 
1855    Notes:
1856    Some options are relevant only for particular matrix types and
1857    are thus ignored by others.  Other options are not supported by
1858    certain matrix types and will generate an error message if set.
1859 
1860    If using a Fortran 77 module to compute a matrix, one may need to
1861    use the column-oriented option (or convert to the row-oriented
1862    format).
1863 
1864    MAT_NO_NEW_NONZERO_LOCATIONS indicates that any add or insertion
1865    that will generate a new entry in the nonzero structure is ignored.
1866    Thus, if memory has not alredy been allocated for this particular
1867    data, then the insertion is ignored. For dense matrices, in which
1868    the entire array is allocated, no entries are ever ignored.
1869 
1870    MAT_IGNORE_OFF_PROCESSOR_ENTRIES indicates entries destined for
1871    other processors are dropped, rather than stashed.
1872 
1873 .keywords: matrix, option, row-oriented, column-oriented, sorted, nonzero
1874 @*/
1875 int MatSetOption(Mat mat,MatOption op)
1876 {
1877   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1878   if (mat->ops.setoption) return (*mat->ops.setoption)(mat,op);
1879   return 0;
1880 }
1881 
1882 #undef __FUNC__
1883 #define __FUNC__ "MatZeroEntries"
1884 /*@
1885    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
1886    this routine retains the old nonzero structure.
1887 
1888    Input Parameters:
1889 .  mat - the matrix
1890 
1891 .keywords: matrix, zero, entries
1892 
1893 .seealso: MatZeroRows()
1894 @*/
1895 int MatZeroEntries(Mat mat)
1896 {
1897   int ierr;
1898   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1899   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
1900   if (!mat->ops.zeroentries) SETERRQ(PETSC_ERR_SUP,0,"");
1901 
1902   PLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
1903   ierr = (*mat->ops.zeroentries)(mat); CHKERRQ(ierr);
1904   PLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
1905   return 0;
1906 }
1907 
1908 #undef __FUNC__
1909 #define __FUNC__ "MatZeroRows"
1910 /*@
1911    MatZeroRows - Zeros all entries (except possibly the main diagonal)
1912    of a set of rows of a matrix.
1913 
1914    Input Parameters:
1915 .  mat - the matrix
1916 .  is - index set of rows to remove
1917 .  diag - pointer to value put in all diagonals of eliminated rows.
1918           Note that diag is not a pointer to an array, but merely a
1919           pointer to a single value.
1920 
1921    Notes:
1922    For the AIJ matrix formats this removes the old nonzero structure,
1923    but does not release memory.  For the dense and block diagonal
1924    formats this does not alter the nonzero structure.
1925 
1926    The user can set a value in the diagonal entry (or for the AIJ and
1927    row formats can optionally remove the main diagonal entry from the
1928    nonzero structure as well, by passing a null pointer as the final
1929    argument).
1930 
1931 .keywords: matrix, zero, rows, boundary conditions
1932 
1933 .seealso: MatZeroEntries(),
1934 @*/
1935 int MatZeroRows(Mat mat,IS is, Scalar *diag)
1936 {
1937   int ierr;
1938 
1939   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1940   PetscValidHeaderSpecific(is,IS_COOKIE);
1941   if (diag) PetscValidScalarPointer(diag);
1942   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
1943   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
1944   if (!mat->ops.zerorows) SETERRQ(PETSC_ERR_SUP,0,"");
1945 
1946   ierr = (*mat->ops.zerorows)(mat,is,diag); CHKERRQ(ierr);
1947   return 0;
1948 }
1949 
1950 #undef __FUNC__
1951 #define __FUNC__ "MatZeroRowsLocal"
1952 /*@
1953    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
1954    of a set of rows of a matrix; using local numbering of rows.
1955 
1956    Input Parameters:
1957 .  mat - the matrix
1958 .  is - index set of rows to remove
1959 .  diag - pointer to value put in all diagonals of eliminated rows.
1960           Note that diag is not a pointer to an array, but merely a
1961           pointer to a single value.
1962 
1963    Notes:
1964    For the AIJ matrix formats this removes the old nonzero structure,
1965    but does not release memory.  For the dense and block diagonal
1966    formats this does not alter the nonzero structure.
1967 
1968    The user can set a value in the diagonal entry (or for the AIJ and
1969    row formats can optionally remove the main diagonal entry from the
1970    nonzero structure as well, by passing a null pointer as the final
1971    argument).
1972 
1973 .keywords: matrix, zero, rows, boundary conditions
1974 
1975 .seealso: MatZeroEntries(),
1976 @*/
1977 int MatZeroRowsLocal(Mat mat,IS is, Scalar *diag)
1978 {
1979   int ierr;
1980   IS  newis;
1981 
1982   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1983   PetscValidHeaderSpecific(is,IS_COOKIE);
1984   if (diag) PetscValidScalarPointer(diag);
1985   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
1986   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
1987   if (!mat->ops.zerorows) SETERRQ(PETSC_ERR_SUP,0,"");
1988 
1989   ierr = ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis); CHKERRQ(ierr);
1990   ierr =  (*mat->ops.zerorows)(mat,newis,diag); CHKERRQ(ierr);
1991   ierr = ISDestroy(newis);
1992   return 0;
1993 }
1994 
1995 #undef __FUNC__
1996 #define __FUNC__ "MatGetSize"
1997 /*@
1998    MatGetSize - Returns the numbers of rows and columns in a matrix.
1999 
2000    Input Parameter:
2001 .  mat - the matrix
2002 
2003    Output Parameters:
2004 .  m - the number of global rows
2005 .  n - the number of global columns
2006 
2007 .keywords: matrix, dimension, size, rows, columns, global, get
2008 
2009 .seealso: MatGetLocalSize()
2010 @*/
2011 int MatGetSize(Mat mat,int *m,int* n)
2012 {
2013   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2014   PetscValidIntPointer(m);
2015   PetscValidIntPointer(n);
2016   return (*mat->ops.getsize)(mat,m,n);
2017 }
2018 
2019 #undef __FUNC__
2020 #define __FUNC__ "MatGetLocalSize"
2021 /*@
2022    MatGetLocalSize - Returns the number of rows and columns in a matrix
2023    stored locally.  This information may be implementation dependent, so
2024    use with care.
2025 
2026    Input Parameters:
2027 .  mat - the matrix
2028 
2029    Output Parameters:
2030 .  m - the number of local rows
2031 .  n - the number of local columns
2032 
2033 .keywords: matrix, dimension, size, local, rows, columns, get
2034 
2035 .seealso: MatGetSize()
2036 @*/
2037 int MatGetLocalSize(Mat mat,int *m,int* n)
2038 {
2039   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2040   PetscValidIntPointer(m);
2041   PetscValidIntPointer(n);
2042   return (*mat->ops.getlocalsize)(mat,m,n);
2043 }
2044 
2045 #undef __FUNC__
2046 #define __FUNC__ "MatGetOwnershipRange"
2047 /*@
2048    MatGetOwnershipRange - Returns the range of matrix rows owned by
2049    this processor, assuming that the matrix is laid out with the first
2050    n1 rows on the first processor, the next n2 rows on the second, etc.
2051    For certain parallel layouts this range may not be well defined.
2052 
2053    Input Parameters:
2054 .  mat - the matrix
2055 
2056    Output Parameters:
2057 .  m - the first local row
2058 .  n - one more then the last local row
2059 
2060 .keywords: matrix, get, range, ownership
2061 @*/
2062 int MatGetOwnershipRange(Mat mat,int *m,int* n)
2063 {
2064   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2065   PetscValidIntPointer(m);
2066   PetscValidIntPointer(n);
2067   if (!mat->ops.getownershiprange) SETERRQ(PETSC_ERR_SUP,0,"");
2068   return (*mat->ops.getownershiprange)(mat,m,n);
2069 }
2070 
2071 #undef __FUNC__
2072 #define __FUNC__ "MatILUFactorSymbolic"
2073 /*@
2074    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
2075    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
2076    to complete the factorization.
2077 
2078    Input Parameters:
2079 .  mat - the matrix
2080 .  row - row permutation
2081 .  column - column permutation
2082 .  fill - number of levels of fill
2083 .  f - expected fill as ratio of the original number of nonzeros,
2084        for example 3.0; choosing this parameter well can result in
2085        more efficient use of time and space.
2086 
2087    Output Parameters:
2088 .  fact - new matrix that has been symbolically factored
2089 
2090    Options Database Key:
2091 $   -mat_ilu_fill <f>, where f is the fill ratio
2092 
2093    Notes:
2094    See the file $(PETSC_DIR)/Performace for additional information about
2095    choosing the fill factor for better efficiency.
2096 
2097 .keywords: matrix, factor, incomplete, ILU, symbolic, fill
2098 
2099 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric()
2100 @*/
2101 int MatILUFactorSymbolic(Mat mat,IS row,IS col,double f,int fill,Mat *fact)
2102 {
2103   int ierr,flg;
2104 
2105   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2106   if (fill < 0) SETERRQ(1,0,"Levels of fill negative");
2107   if (!fact) SETERRQ(1,0,"Fact argument is missing");
2108   if (!mat->ops.ilufactorsymbolic) SETERRQ(PETSC_ERR_SUP,0,"");
2109   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
2110   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
2111 
2112   ierr = OptionsGetDouble(PETSC_NULL,"-mat_ilu_fill",&f,&flg); CHKERRQ(ierr);
2113   PLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
2114   ierr = (*mat->ops.ilufactorsymbolic)(mat,row,col,f,fill,fact); CHKERRQ(ierr);
2115   PLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
2116   return 0;
2117 }
2118 
2119 #undef __FUNC__
2120 #define __FUNC__ "MatIncompleteCholeskyFactorSymbolic"
2121 /*@
2122    MatIncompleteCholeskyFactorSymbolic - Performs symbolic incomplete
2123    Cholesky factorization for a symmetric matrix.  Use
2124    MatCholeskyFactorNumeric() to complete the factorization.
2125 
2126    Input Parameters:
2127 .  mat - the matrix
2128 .  perm - row and column permutation
2129 .  fill - levels of fill
2130 .  f - expected fill as ratio of original fill
2131 
2132    Output Parameter:
2133 .  fact - the factored matrix
2134 
2135    Note:  Currently only no-fill factorization is supported.
2136 
2137 .keywords: matrix, factor, incomplete, ICC, Cholesky, symbolic, fill
2138 
2139 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor()
2140 @*/
2141 int MatIncompleteCholeskyFactorSymbolic(Mat mat,IS perm,double f,int fill,
2142                                         Mat *fact)
2143 {
2144   int ierr;
2145   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2146   if (mat->factor) SETERRQ(1,0,"Not for factored matrix");
2147   if (fill < 0) SETERRQ(1,0,"Fill negative");
2148   if (!fact) SETERRQ(1,0,"Missing fact argument");
2149   if (!mat->ops.incompletecholeskyfactorsymbolic)
2150      SETERRQ(PETSC_ERR_SUP,0,"");
2151   if (!mat->assembled)
2152      SETERRQ(1,0,"Not for unassembled matrix");
2153 
2154   PLogEventBegin(MAT_IncompleteCholeskyFactorSymbolic,mat,perm,0,0);
2155   ierr = (*mat->ops.incompletecholeskyfactorsymbolic)(mat,perm,f,fill,fact);CHKERRQ(ierr);
2156   PLogEventEnd(MAT_IncompleteCholeskyFactorSymbolic,mat,perm,0,0);
2157   return 0;
2158 }
2159 
2160 #undef __FUNC__
2161 #define __FUNC__ "MatGetArray"
2162 /*@C
2163    MatGetArray - Returns a pointer to the element values in the matrix.
2164    This routine  is implementation dependent, and may not even work for
2165    certain matrix types. You MUST call MatRestoreArray() when you no
2166    longer need to access the array.
2167 
2168    Input Parameter:
2169 .  mat - the matrix
2170 
2171    Output Parameter:
2172 .  v - the location of the values
2173 
2174    Fortran Note:
2175    The Fortran interface is slightly different from that given below.
2176    See the Fortran chapter of the users manual and
2177    petsc/src/mat/examples for details.
2178 
2179 .keywords: matrix, array, elements, values
2180 
2181 .seealso: MatRestoreArray()
2182 @*/
2183 int MatGetArray(Mat mat,Scalar **v)
2184 {
2185   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2186   if (!v) SETERRQ(1,0,"Bad input, array pointer location");
2187   if (!mat->ops.getarray) SETERRQ(PETSC_ERR_SUP,0,"");
2188   return (*mat->ops.getarray)(mat,v);
2189 }
2190 
2191 #undef __FUNC__
2192 #define __FUNC__ "MatRestoreArray"
2193 /*@C
2194    MatRestoreArray - Restores the matrix after MatGetArray has been called.
2195 
2196    Input Parameter:
2197 .  mat - the matrix
2198 .  v - the location of the values
2199 
2200    Fortran Note:
2201    The Fortran interface is slightly different from that given below.
2202    See the users manual and petsc/src/mat/examples for details.
2203 
2204 .keywords: matrix, array, elements, values, resrore
2205 
2206 .seealso: MatGetArray()
2207 @*/
2208 int MatRestoreArray(Mat mat,Scalar **v)
2209 {
2210   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2211   if (!v) SETERRQ(1,0,"Bad input, array pointer location");
2212   if (!mat->ops.restorearray) SETERRQ(PETSC_ERR_SUP,0,"");
2213   return (*mat->ops.restorearray)(mat,v);
2214 }
2215 
2216 #undef __FUNC__
2217 #define __FUNC__ "MatGetSubMatrices"
2218 /*@C
2219    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
2220    points to an array of valid matrices, it may be reused.
2221 
2222    Input Parameters:
2223 .  mat - the matrix
2224 .  irow, icol - index sets of rows and columns to extract
2225 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
2226 
2227    Output Parameter:
2228 .  submat - the array of submatrices
2229 
2230    Limitations:
2231    Currently, MatGetSubMatrices() can extract only sequential submatrices
2232    (from both sequential and parallel matrices).
2233 
2234    Notes:
2235    When extracting submatrices from a parallel matrix, each processor can
2236    form a different submatrix by setting the rows and columns of its
2237    individual index sets according to the local submatrix desired.
2238 
2239    When finished using the submatrices, the user should destroy
2240    them with MatDestroySubMatrices().
2241 
2242 .keywords: matrix, get, submatrix, submatrices
2243 
2244 .seealso: MatDestroyMatrices()
2245 @*/
2246 int MatGetSubMatrices(Mat mat,int n,IS *irow,IS *icol,MatGetSubMatrixCall scall,
2247                       Mat **submat)
2248 {
2249   int ierr;
2250   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2251   if (!mat->ops.getsubmatrices) SETERRQ(PETSC_ERR_SUP,0,"");
2252   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
2253 
2254   PLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
2255   ierr = (*mat->ops.getsubmatrices)(mat,n,irow,icol,scall,submat); CHKERRQ(ierr);
2256   PLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
2257 
2258   return 0;
2259 }
2260 
2261 #undef __FUNC__
2262 #define __FUNC__ "MatDestroyMatrices"
2263 /*@C
2264    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
2265 
2266    Input Parameters:
2267 .  n - the number of local matrices
2268 .  mat - the matrices
2269 
2270 .keywords: matrix, destroy, submatrix, submatrices
2271 
2272 .seealso: MatGetSubMatrices()
2273 @*/
2274 int MatDestroyMatrices(int n,Mat **mat)
2275 {
2276   int ierr,i;
2277 
2278   if (n < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,1,"Trying to destroy negative number of matrices");
2279   PetscValidPointer(mat);
2280   for ( i=0; i<n; i++ ) {
2281     ierr = MatDestroy((*mat)[i]); CHKERRQ(ierr);
2282   }
2283   if (n) PetscFree(*mat);
2284   return 0;
2285 }
2286 
2287 #undef __FUNC__
2288 #define __FUNC__ "MatIncreaseOverlap"
2289 /*@
2290    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
2291    replaces the index by larger ones that represent submatrices with more
2292    overlap.
2293 
2294    Input Parameters:
2295 .  mat - the matrix
2296 .  n   - the number of index sets
2297 .  is  - the array of pointers to index sets
2298 .  ov  - the additional overlap requested
2299 
2300 .keywords: matrix, overlap, Schwarz
2301 
2302 .seealso: MatGetSubMatrices()
2303 @*/
2304 int MatIncreaseOverlap(Mat mat,int n, IS *is,int ov)
2305 {
2306   int ierr;
2307   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2308   if (!mat->assembled) SETERRQ(1,0,"Not for unassembled matrix");
2309   if (mat->factor)     SETERRQ(1,0,"Not for factored matrix");
2310 
2311   if (ov == 0) return 0;
2312   if (!mat->ops.increaseoverlap) SETERRQ(PETSC_ERR_SUP,0,"");
2313   PLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
2314   ierr = (*mat->ops.increaseoverlap)(mat,n,is,ov); CHKERRQ(ierr);
2315   PLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
2316   return 0;
2317 }
2318 
2319 #undef __FUNC__
2320 #define __FUNC__ "MatPrintHelp"
2321 /*@
2322    MatPrintHelp - Prints all the options for the matrix.
2323 
2324    Input Parameter:
2325 .  mat - the matrix
2326 
2327    Options Database Keys:
2328 $  -help, -h
2329 
2330 .keywords: mat, help
2331 
2332 .seealso: MatCreate(), MatCreateXXX()
2333 @*/
2334 int MatPrintHelp(Mat mat)
2335 {
2336   static int called = 0;
2337   MPI_Comm   comm;
2338   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2339 
2340   comm = mat->comm;
2341   if (!called) {
2342     PetscPrintf(comm,"General matrix options:\n");
2343     PetscPrintf(comm,"  -mat_view_info : view basic matrix info during MatAssemblyEnd()\n");
2344     PetscPrintf(comm,"  -mat_view_info_detailed : view detailed matrix info during MatAssemblyEnd()\n");
2345     PetscPrintf(comm,"  -mat_view_draw : draw nonzero matrix structure during MatAssemblyEnd()\n");
2346     PetscPrintf(comm,"      -draw_pause <sec> : set seconds of display pause\n");
2347     PetscPrintf(comm,"      -display <name> : set alternate display\n");
2348     called = 1;
2349   }
2350   if (mat->ops.printhelp) (*mat->ops.printhelp)(mat);
2351   return 0;
2352 }
2353 
2354 #undef __FUNC__
2355 #define __FUNC__ "MatGetBlockSize"
2356 /*@
2357    MatGetBlockSize - Returns the matrix block size; useful especially for the
2358    block row and block diagonal formats.
2359 
2360    Input Parameter:
2361 .  mat - the matrix
2362 
2363    Output Parameter:
2364 .  bs - block size
2365 
2366    Notes:
2367 $  block diagonal formats: MATSEQBDIAG, MATMPIBDIAG
2368 $  block row formats: MATSEQBAIJ, MATMPIBAIJ
2369 
2370 .keywords: matrix, get, block, size
2371 
2372 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatCreateSeqBDiag(), MatCreateMPIBDiag()
2373 @*/
2374 int MatGetBlockSize(Mat mat,int *bs)
2375 {
2376   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2377   PetscValidIntPointer(bs);
2378   if (!mat->ops.getblocksize) SETERRQ(PETSC_ERR_SUP,0,"");
2379   return (*mat->ops.getblocksize)(mat,bs);
2380 }
2381 
2382 #undef __FUNC__
2383 #define __FUNC__ "MatGetRowIJ"
2384 /*@C
2385       MatGetRowIJ - Returns the compress row storage i and j indices for sequential matrices.
2386                  EXPERTS ONLY.
2387 
2388   Input Parameters:
2389 .   mat - the matrix
2390 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
2391 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
2392                 symmetrized
2393 
2394   Output Parameters:
2395 .   n - number of rows and columns in the (possibly compressed) matrix
2396 .   ia - the row indices
2397 .   ja - the column indices
2398 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
2399 @*/
2400 int MatGetRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
2401 {
2402   int ierr;
2403   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2404   if (ia) PetscValidIntPointer(ia);
2405   if (ja) PetscValidIntPointer(ja);
2406   PetscValidIntPointer(done);
2407   if (!mat->ops.getrowij) *done = PETSC_FALSE;
2408   else {
2409     *done = PETSC_TRUE;
2410     ierr  = (*mat->ops.getrowij)(mat,shift,symmetric,n,ia,ja,done); CHKERRQ(ierr);
2411   }
2412   return 0;
2413 }
2414 
2415 #undef __FUNC__
2416 #define __FUNC__ "MatGetColumnIJ"
2417 /*@C
2418       MatGetColumnIJ - Returns the compress Column storage i and j indices for sequential matrices.
2419                  EXPERTS ONLY.
2420 
2421   Input Parameters:
2422 .   mat - the matrix
2423 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
2424 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
2425                 symmetrized
2426 
2427   Output Parameters:
2428 .   n - number of Columns and columns in the (possibly compressed) matrix
2429 .   ia - the Column indices
2430 .   ja - the column indices
2431 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
2432 @*/
2433 int MatGetColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
2434 {
2435   int ierr;
2436   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2437   if (ia) PetscValidIntPointer(ia);
2438   if (ja) PetscValidIntPointer(ja);
2439   PetscValidIntPointer(done);
2440 
2441   if (!mat->ops.getcolumnij) *done = PETSC_FALSE;
2442   else {
2443     *done = PETSC_TRUE;
2444     ierr  = (*mat->ops.getcolumnij)(mat,shift,symmetric,n,ia,ja,done); CHKERRQ(ierr);
2445   }
2446   return 0;
2447 }
2448 
2449 #undef __FUNC__
2450 #define __FUNC__ "MatRestoreRowIJ"
2451 /*@C
2452       MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
2453                      MatGetRowIJ(). EXPERTS ONLY.
2454 
2455   Input Parameters:
2456 .   mat - the matrix
2457 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
2458 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
2459                 symmetrized
2460 
2461   Output Parameters:
2462 .   n - size of (possibly compressed) matrix
2463 .   ia - the row indices
2464 .   ja - the column indices
2465 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
2466 @*/
2467 int MatRestoreRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
2468 {
2469   int ierr;
2470   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2471   if (ia) PetscValidIntPointer(ia);
2472   if (ja) PetscValidIntPointer(ja);
2473   PetscValidIntPointer(done);
2474 
2475   if (!mat->ops.restorerowij) *done = PETSC_FALSE;
2476   else {
2477     *done = PETSC_TRUE;
2478     ierr  = (*mat->ops.restorerowij)(mat,shift,symmetric,n,ia,ja,done); CHKERRQ(ierr);
2479   }
2480   return 0;
2481 }
2482 
2483 #undef __FUNC__
2484 #define __FUNC__ "MatRestoreColumnIJ"
2485 /*@C
2486       MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
2487                      MatGetColumnIJ(). EXPERTS ONLY.
2488 
2489   Input Parameters:
2490 .   mat - the matrix
2491 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
2492 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
2493                 symmetrized
2494 
2495   Output Parameters:
2496 .   n - size of (possibly compressed) matrix
2497 .   ia - the Column indices
2498 .   ja - the column indices
2499 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
2500 @*/
2501 int MatRestoreColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
2502 {
2503   int ierr;
2504   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2505   if (ia) PetscValidIntPointer(ia);
2506   if (ja) PetscValidIntPointer(ja);
2507   PetscValidIntPointer(done);
2508 
2509   if (!mat->ops.restorecolumnij) *done = PETSC_FALSE;
2510   else {
2511     *done = PETSC_TRUE;
2512     ierr  = (*mat->ops.restorecolumnij)(mat,shift,symmetric,n,ia,ja,done); CHKERRQ(ierr);
2513   }
2514   return 0;
2515 }
2516 
2517 #undef __FUNC__
2518 #define __FUNC__ "MatColoringPatch"
2519 /*@C
2520       MatColoringPatch - EXPERTS ONLY, used inside matrix coloring routines that
2521           use matGetRowIJ() and/or MatGetColumnIJ().
2522 
2523   Input Parameters:
2524 .   mat - the matrix
2525 .   n   - number of colors
2526 .   colorarray - array indicating color for each column
2527 
2528   Output Parameters:
2529 .   iscoloring - coloring generated using colorarray information
2530 
2531 @*/
2532 int MatColoringPatch(Mat mat,int n,int *colorarray,ISColoring *iscoloring)
2533 {
2534   int ierr;
2535   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2536   PetscValidIntPointer(colorarray);
2537 
2538   if (!mat->ops.coloringpatch) {SETERRQ(PETSC_ERR_SUP,0,"");}
2539   else {
2540     ierr  = (*mat->ops.coloringpatch)(mat,n,colorarray,iscoloring); CHKERRQ(ierr);
2541   }
2542   return 0;
2543 }
2544 
2545 
2546 /*@
2547    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
2548 
2549    Input Paramter:
2550 .  mat - the factored matrix to be reset
2551 
2552    Notes:
2553    This routine should be used only with factored matrices formed by in-place
2554    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
2555    format).  This option can save memory, for example, when solving nonlinear
2556    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
2557    ILU(0) preconditioner.
2558 
2559   Note that one can specify in-place ILU(0) factorization by calling
2560 $     PCType(pc,PCILU);
2561 $     PCILUSeUseInPlace(pc);
2562   or by using the options -pc_type ilu -pc_ilu_in_place
2563 
2564   In-place factorization ILU(0) can also be used as a local
2565   solver for the blocks within the block Jacobi or additive Schwarz
2566   methods (runtime option: -sub_pc_ilu_in_place).  See the discussion
2567   of these preconditioners in the users manual for details on setting
2568   local solver options.
2569 
2570 .seealso: PCILUSetUseInPlace(), PCLUSetUseInPlace()
2571 
2572 .keywords: matrix-free, in-place ILU, in-place LU
2573 @*/
2574 int MatSetUnfactored(Mat mat)
2575 {
2576   int ierr;
2577 
2578   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2579   mat->factor = 0;
2580   if (!mat->ops.setunfactored) return 0;
2581   ierr = (*mat->ops.setunfactored)(mat); CHKERRQ(ierr);
2582   return 0;
2583 }
2584 
2585 #undef __FUNC__
2586 #define __FUNC__ "MatGetType"
2587 /*@C
2588    MatGetType - Gets the matrix type and name (as a string) from the matrix.
2589 
2590    Input Parameter:
2591 .  mat - the matrix
2592 
2593    Output Parameter:
2594 .  type - the matrix type (or use PETSC_NULL)
2595 .  name - name of matrix type (or use PETSC_NULL)
2596 
2597 .keywords: matrix, get, type, name
2598 @*/
2599 int MatGetType(Mat mat,MatType *type,char **name)
2600 {
2601   int  itype = (int)mat->type;
2602   char *matname[10];
2603 
2604   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2605 
2606   if (type) *type = (MatType) mat->type;
2607   if (name) {
2608     /* Note:  Be sure that this list corresponds to the enum in mat.h */
2609     matname[0] = "MATSEQDENSE";
2610     matname[1] = "MATSEQAIJ";
2611     matname[2] = "MATMPIAIJ";
2612     matname[3] = "MATSHELL";
2613     matname[4] = "MATMPIROWBS";
2614     matname[5] = "MATSEQBDIAG";
2615     matname[6] = "MATMPIBDIAG";
2616     matname[7] = "MATMPIDENSE";
2617     matname[8] = "MATSEQBAIJ";
2618     matname[9] = "MATMPIBAIJ";
2619 
2620     if (itype < 0 || itype > 9) *name = "Unknown matrix type";
2621     else                        *name = matname[itype];
2622   }
2623   return 0;
2624 }
2625