xref: /petsc/src/mat/interface/matrix.c (revision 8f240d107a0e502c80d5238417cc20ded5788b60)
1 #ifndef lint
2 static char vcid[] = "$Id: matrix.c,v 1.174 1996/06/11 20:52:28 balay Exp curfman $";
3 #endif
4 
5 /*
6    This is where the abstract matrix operations are defined
7 */
8 
9 #include "petsc.h"
10 #include "matimpl.h"        /*I "mat.h" I*/
11 #include "src/vec/vecimpl.h"
12 #include "pinclude/pviewer.h"
13 #include "draw.h"
14 
15 /*@C
16    MatGetReordering - Gets a reordering for a matrix to reduce fill or to
17    improve numerical stability of LU factorization.
18 
19    Input Parameters:
20 .  mat - the matrix
21 .  type - type of reordering, one of the following:
22 $      ORDER_NATURAL - Natural
23 $      ORDER_ND - Nested Dissection
24 $      ORDER_1WD - One-way Dissection
25 $      ORDER_RCM - Reverse Cuthill-McGee
26 $      ORDER_QMD - Quotient Minimum Degree
27 
28    Output Parameters:
29 .  rperm - row permutation indices
30 .  cperm - column permutation indices
31 
32    Options Database Keys:
33    To specify the ordering through the options database, use one of
34    the following
35 $    -mat_order natural, -mat_order nd, -mat_order 1wd,
36 $    -mat_order rcm, -mat_order qmd
37 
38    Notes:
39    If the column permutations and row permutations are the same,
40    then MatGetReordering() returns 0 in cperm.
41 
42    The user can define additional orderings; see MatReorderingRegister().
43 
44 .keywords: matrix, set, ordering, factorization, direct, ILU, LU,
45            fill, reordering, natural, Nested Dissection,
46            One-way Dissection, Cholesky, Reverse Cuthill-McGee,
47            Quotient Minimum Degree
48 
49 .seealso:  MatGetReorderingTypeFromOptions(), MatReorderingRegister()
50 @*/
51 int MatGetReordering(Mat mat,MatOrdering type,IS *rperm,IS *cperm)
52 {
53   int         ierr;
54   PetscValidHeaderSpecific(mat,MAT_COOKIE);
55   if (!mat->assembled) SETERRQ(1,"MatGetReordering:Not for unassembled matrix");
56 
57   if (!mat->ops.getreordering) {*rperm = 0; *cperm = 0; return 0;}
58   PLogEventBegin(MAT_GetReordering,mat,0,0,0);
59   ierr = MatGetReorderingTypeFromOptions(0,&type); CHKERRQ(ierr);
60   ierr = (*mat->ops.getreordering)(mat,type,rperm,cperm); CHKERRQ(ierr);
61   PLogEventEnd(MAT_GetReordering,mat,0,0,0);
62   return 0;
63 }
64 
65 /*@C
66    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
67    for each row that you get to ensure that your application does
68    not bleed memory.
69 
70    Input Parameters:
71 .  mat - the matrix
72 .  row - the row to get
73 
74    Output Parameters:
75 .  ncols -  the number of nonzeros in the row
76 .  cols - if nonzero, the column numbers
77 .  vals - if nonzero, the values
78 
79    Notes:
80    This routine is provided for people who need to have direct access
81    to the structure of a matrix.  We hope that we provide enough
82    high-level matrix routines that few users will need it.
83 
84    For better efficiency, set cols and/or vals to PETSC_NULL if you do
85    not wish to extract these quantities.
86 
87    The user can only examine the values extracted with MatGetRow();
88    the values cannot be altered.  To change the matrix entries, one
89    must use MatSetValues().
90 
91    Caution:
92    Do not try to change the contents of the output arrays (cols and vals).
93    In some cases, this may corrupt the matrix.
94 
95 .keywords: matrix, row, get, extract
96 
97 .seealso: MatRestoreRow(), MatSetValues()
98 @*/
99 int MatGetRow(Mat mat,int row,int *ncols,int **cols,Scalar **vals)
100 {
101   int   ierr;
102   PetscValidHeaderSpecific(mat,MAT_COOKIE);
103   if (!mat->assembled) SETERRQ(1,"MatGetRow:Not for unassembled matrix");
104   PLogEventBegin(MAT_GetRow,mat,0,0,0);
105   ierr = (*mat->ops.getrow)(mat,row,ncols,cols,vals); CHKERRQ(ierr);
106   PLogEventEnd(MAT_GetRow,mat,0,0,0);
107   return 0;
108 }
109 
110 /*@C
111    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
112 
113    Input Parameters:
114 .  mat - the matrix
115 .  row - the row to get
116 .  ncols, cols - the number of nonzeros and their columns
117 .  vals - if nonzero the column values
118 
119 .keywords: matrix, row, restore
120 
121 .seealso:  MatGetRow()
122 @*/
123 int MatRestoreRow(Mat mat,int row,int *ncols,int **cols,Scalar **vals)
124 {
125   PetscValidHeaderSpecific(mat,MAT_COOKIE);
126   if (!mat->assembled) SETERRQ(1,"MatRestoreRow:Not for unassembled matrix");
127   if (!mat->ops.restorerow) return 0;
128   return (*mat->ops.restorerow)(mat,row,ncols,cols,vals);
129 }
130 /*@
131    MatView - Visualizes a matrix object.
132 
133    Input Parameters:
134 .  mat - the matrix
135 .  ptr - visualization context
136 
137    Notes:
138    The available visualization contexts include
139 $     STDOUT_VIEWER_SELF - standard output (default)
140 $     STDOUT_VIEWER_WORLD - synchronized standard
141 $       output where only the first processor opens
142 $       the file.  All other processors send their
143 $       data to the first processor to print.
144 
145    The user can open alternative vistualization contexts with
146 $    ViewerFileOpenASCII() - output to a specified file
147 $    ViewerFileOpenBinary() - output in binary to a
148 $         specified file; corresponding input uses MatLoad()
149 $    ViewerDrawOpenX() - output nonzero matrix structure to
150 $         an X window display
151 $    ViewerMatlabOpen() - output matrix to Matlab viewer.
152 $         Currently only the sequential dense and AIJ
153 $         matrix types support the Matlab viewer.
154 
155    The user can call ViewerSetFormat() to specify the output
156    format of ASCII printed objects (when using STDOUT_VIEWER_SELF,
157    STDOUT_VIEWER_WORLD and ViewerFileOpenASCII).  Available formats include
158 $    ASCII_FORMAT_DEFAULT - default, prints matrix contents
159 $    ASCII_FORMAT_MATLAB - Matlab format
160 $    ASCII_FORMAT_IMPL - implementation-specific format
161 $      (which is in many cases the same as the default)
162 $    ASCII_FORMAT_INFO - basic information about the matrix
163 $      size and structure (not the matrix entries)
164 $    ASCII_FORMAT_INFO_DETAILED - more detailed information about the
165 $      matrix structure
166 
167 .keywords: matrix, view, visualize, output, print, write, draw
168 
169 .seealso: ViewerSetFormat(), ViewerFileOpenASCII(), ViewerDrawOpenX(),
170           ViewerMatlabOpen(), ViewerFileOpenBinary(), MatLoad()
171 @*/
172 int MatView(Mat mat,Viewer viewer)
173 {
174   int          format, ierr, rows, cols,nz, nzalloc, mem;
175   FILE         *fd;
176   char         *cstr;
177   ViewerType   vtype;
178   MPI_Comm     comm = mat->comm;
179 
180   PetscValidHeaderSpecific(mat,MAT_COOKIE);
181   if (!mat->assembled) SETERRQ(1,"MatView:Not for unassembled matrix");
182 
183   if (!viewer) {
184     viewer = STDOUT_VIEWER_SELF;
185   }
186 
187   ierr = ViewerGetType(viewer,&vtype);
188   if (vtype == ASCII_FILE_VIEWER || vtype == ASCII_FILES_VIEWER) {
189     ierr = ViewerGetFormat(viewer,&format); CHKERRQ(ierr);
190     ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr);
191     if (format == ASCII_FORMAT_INFO || format == ASCII_FORMAT_INFO_DETAILED) {
192       PetscFPrintf(comm,fd,"Matrix Object:\n");
193       ierr = MatGetType(mat,PETSC_NULL,&cstr); CHKERRQ(ierr);
194       ierr = MatGetSize(mat,&rows,&cols); CHKERRQ(ierr);
195       PetscFPrintf(comm,fd,"  type=%s, rows=%d, cols=%d\n",cstr,rows,cols);
196       if (mat->ops.getinfo) {
197         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&nz,&nzalloc,&mem); CHKERRQ(ierr);
198         PetscFPrintf(comm,fd,"  total: nonzeros=%d, allocated nonzeros=%d\n",nz,
199                      nzalloc);
200       }
201     }
202   }
203   if (mat->view) {ierr = (*mat->view)((PetscObject)mat,viewer); CHKERRQ(ierr);}
204   return 0;
205 }
206 
207 /*@C
208    MatDestroy - Frees space taken by a matrix.
209 
210    Input Parameter:
211 .  mat - the matrix
212 
213 .keywords: matrix, destroy
214 @*/
215 int MatDestroy(Mat mat)
216 {
217   int ierr;
218   PetscValidHeaderSpecific(mat,MAT_COOKIE);
219   ierr = (*mat->destroy)((PetscObject)mat); CHKERRQ(ierr);
220   return 0;
221 }
222 /*@
223    MatValid - Checks whether a matrix object is valid.
224 
225    Input Parameter:
226 .  m - the matrix to check
227 
228    Output Parameter:
229    flg - flag indicating matrix status, either
230 $     PETSC_TRUE if matrix is valid;
231 $     PETSC_FALSE otherwise.
232 
233 .keywords: matrix, valid
234 @*/
235 int MatValid(Mat m,PetscTruth *flg)
236 {
237   if (!m)                           *flg = PETSC_FALSE;
238   else if (m->cookie != MAT_COOKIE) *flg = PETSC_FALSE;
239   else                              *flg = PETSC_TRUE;
240   return 0;
241 }
242 
243 /*@
244    MatSetValues - Inserts or adds a block of values into a matrix.
245    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
246    MUST be called after all calls to MatSetValues() have been completed.
247 
248    Input Parameters:
249 .  mat - the matrix
250 .  v - a logically two-dimensional array of values
251 .  m, indexm - the number of rows and their global indices
252 .  n, indexn - the number of columns and their global indices
253 .  addv - either ADD_VALUES or INSERT_VALUES, where
254 $     ADD_VALUES - adds values to any existing entries
255 $     INSERT_VALUES - replaces existing entries with new values
256 
257    Notes:
258    By default the values, v, are row-oriented and unsorted.
259    See MatSetOptions() for other options.
260 
261    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
262    options cannot be mixed without intervening calls to the assembly
263    routines.
264 
265 .keywords: matrix, insert, add, set, values
266 
267 .seealso: MatSetOptions(), MatAssemblyBegin(), MatAssemblyEnd()
268 @*/
269 int MatSetValues(Mat mat,int m,int *idxm,int n,int *idxn,Scalar *v,
270                                                         InsertMode addv)
271 {
272   int ierr;
273   PetscValidHeaderSpecific(mat,MAT_COOKIE);
274   if (mat->assembled) {
275     mat->was_assembled = PETSC_TRUE;
276     mat->assembled     = PETSC_FALSE;
277   }
278   PLogEventBegin(MAT_SetValues,mat,0,0,0);
279   ierr = (*mat->ops.setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
280   PLogEventEnd(MAT_SetValues,mat,0,0,0);
281   return 0;
282 }
283 
284 /*@
285    MatGetValues - Gets a block of values from a matrix.
286 
287    Input Parameters:
288 .  mat - the matrix
289 .  v - a logically two-dimensional array for storing the values
290 .  m, indexm - the number of rows and their global indices
291 .  n, indexn - the number of columns and their global indices
292 
293    Notes:
294    The user must allocate space (m*n Scalars) for the values, v.
295    The values, v, are then returned in a row-oriented format,
296    analogous to that used by default in MatSetValues().
297 
298 .keywords: matrix, get, values
299 
300 .seealso: MatGetRow(), MatGetSubmatrix(), MatGetSubmatrices(), MatSetValues()
301 @*/
302 int MatGetValues(Mat mat,int m,int *idxm,int n,int *idxn,Scalar *v)
303 {
304   int ierr;
305 
306   PetscValidHeaderSpecific(mat,MAT_COOKIE);
307   if (!mat->assembled) SETERRQ(1,"MatGetValues:Not for unassembled matrix");
308 
309   PLogEventBegin(MAT_GetValues,mat,0,0,0);
310   ierr = (*mat->ops.getvalues)(mat,m,idxm,n,idxn,v); CHKERRQ(ierr);
311   PLogEventEnd(MAT_GetValues,mat,0,0,0);
312   return 0;
313 }
314 
315 /* --------------------------------------------------------*/
316 /*@
317    MatMult - Computes matrix-vector product.
318 
319    Input Parameters:
320 .  mat - the matrix
321 .  x   - the vector to be multilplied
322 
323    Output Parameters:
324 .  y - the result
325 
326 .keywords: matrix, multiply, matrix-vector product
327 
328 .seealso: MatMultTrans(), MatMultAdd(), MatMultTransAdd()
329 @*/
330 int MatMult(Mat mat,Vec x,Vec y)
331 {
332   int ierr;
333   PetscValidHeaderSpecific(mat,MAT_COOKIE);
334   PetscValidHeaderSpecific(x,VEC_COOKIE);PetscValidHeaderSpecific(y,VEC_COOKIE);
335   if (!mat->assembled) SETERRQ(1,"MatMult:Not for unassembled matrix");
336   /* if (mat->factor) SETERRQ(1,"MatMult:Not for factored matrix"); */
337   if (x == y) SETERRQ(1,"MatMult:x and y must be different vectors");
338   if (mat->N != x->N) SETERRQ(PETSC_ERR_SIZ,"MatMult:Mat mat,Vec x: global dim");
339   if (mat->M != y->N) SETERRQ(PETSC_ERR_SIZ,"MatMult:Mat mat,Vec y: global dim");
340   if (mat->m != y->n) SETERRQ(PETSC_ERR_SIZ,"MatMult:Mat mat,Vec y: local dim");
341 
342   PLogEventBegin(MAT_Mult,mat,x,y,0);
343   ierr = (*mat->ops.mult)(mat,x,y); CHKERRQ(ierr);
344   PLogEventEnd(MAT_Mult,mat,x,y,0);
345   return 0;
346 }
347 /*@
348    MatMultTrans - Computes matrix transpose times a vector.
349 
350    Input Parameters:
351 .  mat - the matrix
352 .  x   - the vector to be multilplied
353 
354    Output Parameters:
355 .  y - the result
356 
357 .keywords: matrix, multiply, matrix-vector product, transpose
358 
359 .seealso: MatMult(), MatMultAdd(), MatMultTransAdd()
360 @*/
361 int MatMultTrans(Mat mat,Vec x,Vec y)
362 {
363   int ierr;
364   PetscValidHeaderSpecific(mat,MAT_COOKIE);
365   PetscValidHeaderSpecific(x,VEC_COOKIE); PetscValidHeaderSpecific(y,VEC_COOKIE);
366   if (!mat->assembled) SETERRQ(1,"MatMultTrans:Not for unassembled matrix");
367   /* if (mat->factor) SETERRQ(1,"MatMult:Not for factored matrix"); */
368   if (x == y) SETERRQ(1,"MatMultTrans:x and y must be different vectors");
369   if (mat->M != x->N) SETERRQ(PETSC_ERR_SIZ,"MatMultTrans:Mat mat,Vec x: global dim");
370   if (mat->N != y->N) SETERRQ(PETSC_ERR_SIZ,"MatMultTrans:Mat mat,Vec y: global dim");
371 
372   PLogEventBegin(MAT_MultTrans,mat,x,y,0);
373   ierr = (*mat->ops.multtrans)(mat,x,y); CHKERRQ(ierr);
374   PLogEventEnd(MAT_MultTrans,mat,x,y,0);
375   return 0;
376 }
377 /*@
378     MatMultAdd -  Computes v3 = v2 + A * v1.
379 
380     Input Parameters:
381 .   mat - the matrix
382 .   v1, v2 - the vectors
383 
384     Output Parameters:
385 .   v3 - the result
386 
387 .keywords: matrix, multiply, matrix-vector product, add
388 
389 .seealso: MatMultTrans(), MatMult(), MatMultTransAdd()
390 @*/
391 int MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
392 {
393   int ierr;
394   PetscValidHeaderSpecific(mat,MAT_COOKIE);PetscValidHeaderSpecific(v1,VEC_COOKIE);
395   PetscValidHeaderSpecific(v2,VEC_COOKIE); PetscValidHeaderSpecific(v3,VEC_COOKIE);
396   if (!mat->assembled) SETERRQ(1,"MatMultAdd:Not for unassembled matrix");
397   /* if (mat->factor) SETERRQ(1,"MatMult:Not for factored matrix"); */
398   if (mat->N != v1->N) SETERRQ(PETSC_ERR_SIZ,"MatMultAdd:Mat mat,Vec v1: global dim");
399   if (mat->M != v2->N) SETERRQ(PETSC_ERR_SIZ,"MatMultAdd:Mat mat,Vec v2: global dim");
400   if (mat->M != v3->N) SETERRQ(PETSC_ERR_SIZ,"MatMultAdd:Mat mat,Vec v3: global dim");
401   if (mat->m != v3->n) SETERRQ(PETSC_ERR_SIZ,"MatMultAdd:Mat mat,Vec v3: local dim");
402   if (mat->m != v2->n) SETERRQ(PETSC_ERR_SIZ,"MatMultAdd:Mat mat,Vec v2: local dim");
403 
404   PLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
405   if (v1 == v3) SETERRQ(1,"MatMultAdd:v1 and v3 must be different vectors");
406   ierr = (*mat->ops.multadd)(mat,v1,v2,v3); CHKERRQ(ierr);
407   PLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
408   return 0;
409 }
410 /*@
411    MatMultTransAdd - Computes v3 = v2 + A' * v1.
412 
413    Input Parameters:
414 .  mat - the matrix
415 .  v1, v2 - the vectors
416 
417    Output Parameters:
418 .  v3 - the result
419 
420 .keywords: matrix, multiply, matrix-vector product, transpose, add
421 
422 .seealso: MatMultTrans(), MatMultAdd(), MatMult()
423 @*/
424 int MatMultTransAdd(Mat mat,Vec v1,Vec v2,Vec v3)
425 {
426   int ierr;
427   PetscValidHeaderSpecific(mat,MAT_COOKIE);PetscValidHeaderSpecific(v1,VEC_COOKIE);
428   PetscValidHeaderSpecific(v2,VEC_COOKIE);PetscValidHeaderSpecific(v3,VEC_COOKIE);
429   if (!mat->assembled) SETERRQ(1,"MatMultTransAdd:Not for unassembled matrix");
430   /* if (mat->factor) SETERRQ(1,"MatMult:Not for factored matrix"); */
431   if (!mat->ops.multtransadd) SETERRQ(PETSC_ERR_SUP,"MatMultTransAdd");
432   if (v1 == v3) SETERRQ(1,"MatMultTransAdd:v1 and v2 must be different vectors");
433   if (mat->M != v1->N) SETERRQ(PETSC_ERR_SIZ,"MatMultTransAdd:Mat mat,Vec v1: global dim");
434   if (mat->N != v2->N) SETERRQ(PETSC_ERR_SIZ,"MatMultTransAdd:Mat mat,Vec v2: global dim");
435   if (mat->N != v3->N) SETERRQ(PETSC_ERR_SIZ,"MatMultTransAdd:Mat mat,Vec v3: global dim");
436 
437   PLogEventBegin(MAT_MultTransAdd,mat,v1,v2,v3);
438   ierr = (*mat->ops.multtransadd)(mat,v1,v2,v3); CHKERRQ(ierr);
439   PLogEventEnd(MAT_MultTransAdd,mat,v1,v2,v3);
440   return 0;
441 }
442 /* ------------------------------------------------------------*/
443 /*@C
444    MatGetInfo - Returns information about matrix storage (number of
445    nonzeros, memory).
446 
447    Input Parameters:
448 .  mat - the matrix
449 
450    Output Parameters:
451 .  flag - flag indicating the type of parameters to be returned
452 $    flag = MAT_LOCAL: local matrix
453 $    flag = MAT_GLOBAL_MAX: maximum over all processors
454 $    flag = MAT_GLOBAL_SUM: sum over all processors
455 .   nz - the number of nonzeros [or PETSC_NULL]
456 .   nzalloc - the number of allocated nonzeros [or PETSC_NULL]
457 .   mem - the memory used (in bytes)  [or PETSC_NULL]
458 
459 .keywords: matrix, get, info, storage, nonzeros, memory
460 @*/
461 int MatGetInfo(Mat mat,MatInfoType flag,int *nz,int *nzalloc,int *mem)
462 {
463   PetscValidHeaderSpecific(mat,MAT_COOKIE);
464   if (!mat->ops.getinfo) SETERRQ(PETSC_ERR_SUP,"MatGetInfo");
465   return  (*mat->ops.getinfo)(mat,flag,nz,nzalloc,mem);
466 }
467 /* ----------------------------------------------------------*/
468 /*@
469    MatLUFactor - Performs in-place LU factorization of matrix.
470 
471    Input Parameters:
472 .  mat - the matrix
473 .  row - row permutation
474 .  col - column permutation
475 .  f - expected fill as ratio of original fill.
476 
477 .keywords: matrix, factor, LU, in-place
478 
479 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
480 @*/
481 int MatLUFactor(Mat mat,IS row,IS col,double f)
482 {
483   int ierr;
484   PetscValidHeaderSpecific(mat,MAT_COOKIE);
485   if (!mat->ops.lufactor) SETERRQ(PETSC_ERR_SUP,"MatLUFactor");
486   if (!mat->assembled) SETERRQ(1,"MatLUFactor:Not for unassembled matrix");
487 
488   PLogEventBegin(MAT_LUFactor,mat,row,col,0);
489   ierr = (*mat->ops.lufactor)(mat,row,col,f); CHKERRQ(ierr);
490   PLogEventEnd(MAT_LUFactor,mat,row,col,0);
491   return 0;
492 }
493 /*@
494    MatILUFactor - Performs in-place ILU factorization of matrix.
495 
496    Input Parameters:
497 .  mat - the matrix
498 .  row - row permutation
499 .  col - column permutation
500 .  f - expected fill as ratio of original fill.
501 .  level - number of levels of fill.
502 
503    Note: probably really only in-place when level is zero.
504 .keywords: matrix, factor, ILU, in-place
505 
506 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
507 @*/
508 int MatILUFactor(Mat mat,IS row,IS col,double f,int level)
509 {
510   int ierr;
511   PetscValidHeaderSpecific(mat,MAT_COOKIE);
512   if (!mat->ops.ilufactor) SETERRQ(PETSC_ERR_SUP,"MatILUFactor");
513   if (!mat->assembled) SETERRQ(1,"MatILUFactor:Not for unassembled matrix");
514 
515   PLogEventBegin(MAT_ILUFactor,mat,row,col,0);
516   ierr = (*mat->ops.ilufactor)(mat,row,col,f,level); CHKERRQ(ierr);
517   PLogEventEnd(MAT_ILUFactor,mat,row,col,0);
518   return 0;
519 }
520 
521 /*@
522    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
523    Call this routine before calling MatLUFactorNumeric().
524 
525    Input Parameters:
526 .  mat - the matrix
527 .  row, col - row and column permutations
528 .  f - expected fill as ratio of the original number of nonzeros,
529        for example 3.0; choosing this parameter well can result in
530        more efficient use of time and space.
531 
532    Output Parameter:
533 .  fact - new matrix that has been symbolically factored
534 
535    Options Database Key:
536 $     -mat_lu_fill <f>, where f is the fill ratio
537 
538    Notes:
539    See the file $(PETSC_DIR)/Performace for additional information about
540    choosing the fill factor for better efficiency.
541 
542 .keywords: matrix, factor, LU, symbolic, fill
543 
544 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor()
545 @*/
546 int MatLUFactorSymbolic(Mat mat,IS row,IS col,double f,Mat *fact)
547 {
548   int ierr,flg;
549   PetscValidHeaderSpecific(mat,MAT_COOKIE);
550   if (!fact) SETERRQ(1,"MatLUFactorSymbolic:Missing factor matrix argument");
551   if (!mat->ops.lufactorsymbolic) SETERRQ(PETSC_ERR_SUP,"MatLUFactorSymbolic");
552   if (!mat->assembled) SETERRQ(1,"MatLUFactorSymbolic:Not for unassembled matrix");
553 
554   ierr = OptionsGetDouble(PETSC_NULL,"-mat_lu_fill",&f,&flg); CHKERRQ(ierr);
555   PLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
556   ierr = (*mat->ops.lufactorsymbolic)(mat,row,col,f,fact); CHKERRQ(ierr);
557   PLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
558   return 0;
559 }
560 /*@
561    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
562    Call this routine after first calling MatLUFactorSymbolic().
563 
564    Input Parameters:
565 .  mat - the matrix
566 .  row, col - row and  column permutations
567 
568    Output Parameters:
569 .  fact - symbolically factored matrix that must have been generated
570           by MatLUFactorSymbolic()
571 
572    Notes:
573    See MatLUFactor() for in-place factorization.  See
574    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
575 
576 .keywords: matrix, factor, LU, numeric
577 
578 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
579 @*/
580 int MatLUFactorNumeric(Mat mat,Mat *fact)
581 {
582   int ierr,flg;
583 
584   PetscValidHeaderSpecific(mat,MAT_COOKIE);
585   if (!fact) SETERRQ(1,"MatLUFactorNumeric:Missing factor matrix argument");
586   if (!mat->ops.lufactornumeric) SETERRQ(PETSC_ERR_SUP,"MatLUFactorNumeric");
587   if (!mat->assembled) SETERRQ(1,"MatLUFactorNumeric:Not for unassembled matrix");
588   if (mat->M != (*fact)->M || mat->N != (*fact)->N)
589     SETERRQ(PETSC_ERR_SIZ,"MatLUFactorNumeric:Mat mat,Mat *fact: global dim");
590 
591   PLogEventBegin(MAT_LUFactorNumeric,mat,*fact,0,0);
592   ierr = (*mat->ops.lufactornumeric)(mat,fact); CHKERRQ(ierr);
593   PLogEventEnd(MAT_LUFactorNumeric,mat,*fact,0,0);
594   ierr = OptionsHasName(PETSC_NULL,"-mat_view_draw",&flg); CHKERRQ(ierr);
595   if (flg) {
596     Viewer  viewer;
597     ierr = ViewerDrawOpenX((*fact)->comm,0,0,0,0,300,300,&viewer);CHKERRQ(ierr);
598     ierr = MatView(*fact,viewer); CHKERRQ(ierr);
599     ierr = ViewerFlush(viewer); CHKERRQ(ierr);
600     ierr = ViewerDestroy(viewer); CHKERRQ(ierr);
601   }
602   return 0;
603 }
604 /*@
605    MatCholeskyFactor - Performs in-place Cholesky factorization of a
606    symmetric matrix.
607 
608    Input Parameters:
609 .  mat - the matrix
610 .  perm - row and column permutations
611 .  f - expected fill as ratio of original fill
612 
613    Notes:
614    See MatLUFactor() for the nonsymmetric case.  See also
615    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
616 
617 .keywords: matrix, factor, in-place, Cholesky
618 
619 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
620 @*/
621 int MatCholeskyFactor(Mat mat,IS perm,double f)
622 {
623   int ierr;
624   PetscValidHeaderSpecific(mat,MAT_COOKIE);
625   if (!mat->ops.choleskyfactor) SETERRQ(PETSC_ERR_SUP,"MatCholeskyFactor");
626   if (!mat->assembled) SETERRQ(1,"MatCholeskyFactor:Not for unassembled matrix");
627 
628   PLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
629   ierr = (*mat->ops.choleskyfactor)(mat,perm,f); CHKERRQ(ierr);
630   PLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
631   return 0;
632 }
633 /*@
634    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
635    of a symmetric matrix.
636 
637    Input Parameters:
638 .  mat - the matrix
639 .  perm - row and column permutations
640 .  f - expected fill as ratio of original
641 
642    Output Parameter:
643 .  fact - the factored matrix
644 
645    Notes:
646    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
647    MatCholeskyFactor() and MatCholeskyFactorNumeric().
648 
649 .keywords: matrix, factor, factorization, symbolic, Cholesky
650 
651 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
652 @*/
653 int MatCholeskyFactorSymbolic(Mat mat,IS perm,double f,Mat *fact)
654 {
655   int ierr;
656   PetscValidHeaderSpecific(mat,MAT_COOKIE);
657   if (!fact) SETERRQ(1,"MatCholeskyFactorSymbolic:Missing factor matrix argument");
658   if (!mat->ops.choleskyfactorsymbolic)SETERRQ(PETSC_ERR_SUP,"MatCholeskyFactorSymbolic");
659   if (!mat->assembled) SETERRQ(1,"MatCholeskyFactorSymbolic:Not for unassembled matrix");
660 
661   PLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
662   ierr = (*mat->ops.choleskyfactorsymbolic)(mat,perm,f,fact); CHKERRQ(ierr);
663   PLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
664   return 0;
665 }
666 /*@
667    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
668    of a symmetric matrix. Call this routine after first calling
669    MatCholeskyFactorSymbolic().
670 
671    Input Parameter:
672 .  mat - the initial matrix
673 
674    Output Parameter:
675 .  fact - the factored matrix
676 
677 .keywords: matrix, factor, numeric, Cholesky
678 
679 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
680 @*/
681 int MatCholeskyFactorNumeric(Mat mat,Mat *fact)
682 {
683   int ierr;
684   PetscValidHeaderSpecific(mat,MAT_COOKIE);
685   if (!fact) SETERRQ(1,"MatCholeskyFactorNumeric:Missing factor matrix argument");
686   if (!mat->ops.choleskyfactornumeric) SETERRQ(PETSC_ERR_SUP,"MatCholeskyFactorNumeric");
687   if (!mat->assembled) SETERRQ(1,"MatCholeskyFactorNumeric:Not for unassembled matrix");
688   if (mat->M != (*fact)->M || mat->N != (*fact)->N)
689     SETERRQ(PETSC_ERR_SIZ,"MatCholeskyFactorNumeric:Mat mat,Mat *fact: global dim");
690 
691   PLogEventBegin(MAT_CholeskyFactorNumeric,mat,*fact,0,0);
692   ierr = (*mat->ops.choleskyfactornumeric)(mat,fact); CHKERRQ(ierr);
693   PLogEventEnd(MAT_CholeskyFactorNumeric,mat,*fact,0,0);
694   return 0;
695 }
696 /* ----------------------------------------------------------------*/
697 /*@
698    MatSolve - Solves A x = b, given a factored matrix.
699 
700    Input Parameters:
701 .  mat - the factored matrix
702 .  b - the right-hand-side vector
703 
704    Output Parameter:
705 .  x - the result vector
706 
707 .keywords: matrix, linear system, solve, LU, Cholesky, triangular solve
708 
709 .seealso: MatSolveAdd(), MatSolveTrans(), MatSolveTransAdd()
710 @*/
711 int MatSolve(Mat mat,Vec b,Vec x)
712 {
713   int ierr;
714   PetscValidHeaderSpecific(mat,MAT_COOKIE);
715   PetscValidHeaderSpecific(b,VEC_COOKIE); PetscValidHeaderSpecific(x,VEC_COOKIE);
716   if (x == b) SETERRQ(1,"MatSolve:x and y must be different vectors");
717   if (!mat->factor) SETERRQ(1,"MatSolve:Unfactored matrix");
718   if (mat->N != x->N) SETERRQ(PETSC_ERR_SIZ,"MatSolve:Mat mat,Vec x: global dim");
719   if (mat->M != b->N) SETERRQ(PETSC_ERR_SIZ,"MatSolve:Mat mat,Vec b: global dim");
720   if (mat->m != b->n) SETERRQ(PETSC_ERR_SIZ,"MatSolve:Mat mat,Vec b: local dim");
721 
722   if (!mat->ops.solve) SETERRQ(PETSC_ERR_SUP,"MatSolve");
723   PLogEventBegin(MAT_Solve,mat,b,x,0);
724   ierr = (*mat->ops.solve)(mat,b,x); CHKERRQ(ierr);
725   PLogEventEnd(MAT_Solve,mat,b,x,0);
726   return 0;
727 }
728 
729 /* @
730    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU.
731 
732    Input Parameters:
733 .  mat - the factored matrix
734 .  b - the right-hand-side vector
735 
736    Output Parameter:
737 .  x - the result vector
738 
739    Notes:
740    MatSolve() should be used for most applications, as it performs
741    a forward solve followed by a backward solve.
742 
743 .keywords: matrix, forward, LU, Cholesky, triangular solve
744 
745 .seealso: MatSolve(), MatBackwardSolve()
746 @ */
747 int MatForwardSolve(Mat mat,Vec b,Vec x)
748 {
749   int ierr;
750   PetscValidHeaderSpecific(mat,MAT_COOKIE);
751   PetscValidHeaderSpecific(b,VEC_COOKIE);  PetscValidHeaderSpecific(x,VEC_COOKIE);
752   if (x == b) SETERRQ(1,"MatForwardSolve:x and y must be different vectors");
753   if (!mat->factor) SETERRQ(1,"MatForwardSolve:Unfactored matrix");
754   if (!mat->ops.forwardsolve) SETERRQ(PETSC_ERR_SUP,"MatForwardSolve");
755   if (mat->N != x->N) SETERRQ(PETSC_ERR_SIZ,"MatForwardSolve:Mat mat,Vec x: global dim");
756   if (mat->M != b->N) SETERRQ(PETSC_ERR_SIZ,"MatForwardSolve:Mat mat,Vec b: global dim");
757   if (mat->m != b->n) SETERRQ(PETSC_ERR_SIZ,"MatForwardSolve:Mat mat,Vec b: local dim");
758 
759   PLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
760   ierr = (*mat->ops.forwardsolve)(mat,b,x); CHKERRQ(ierr);
761   PLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
762   return 0;
763 }
764 
765 /* @
766    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
767 
768    Input Parameters:
769 .  mat - the factored matrix
770 .  b - the right-hand-side vector
771 
772    Output Parameter:
773 .  x - the result vector
774 
775    Notes:
776    MatSolve() should be used for most applications, as it performs
777    a forward solve followed by a backward solve.
778 
779 .keywords: matrix, backward, LU, Cholesky, triangular solve
780 
781 .seealso: MatSolve(), MatForwardSolve()
782 @ */
783 int MatBackwardSolve(Mat mat,Vec b,Vec x)
784 {
785   int ierr;
786   PetscValidHeaderSpecific(mat,MAT_COOKIE);
787   PetscValidHeaderSpecific(b,VEC_COOKIE);  PetscValidHeaderSpecific(x,VEC_COOKIE);
788   if (x == b) SETERRQ(1,"MatBackwardSolve:x and b must be different vectors");
789   if (!mat->factor) SETERRQ(1,"MatBackwardSolve:Unfactored matrix");
790   if (!mat->ops.backwardsolve) SETERRQ(PETSC_ERR_SUP,"MatBackwardSolve");
791   if (mat->N != x->N) SETERRQ(PETSC_ERR_SIZ,"MatBackwardSolve:Mat mat,Vec x: global dim");
792   if (mat->M != b->N) SETERRQ(PETSC_ERR_SIZ,"MatBackwardSolve:Mat mat,Vec b: global dim");
793   if (mat->m != b->n) SETERRQ(PETSC_ERR_SIZ,"MatBackwardSolve:Mat mat,Vec b: local dim");
794 
795   PLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
796   ierr = (*mat->ops.backwardsolve)(mat,b,x); CHKERRQ(ierr);
797   PLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
798   return 0;
799 }
800 
801 /*@
802    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
803 
804    Input Parameters:
805 .  mat - the factored matrix
806 .  b - the right-hand-side vector
807 .  y - the vector to be added to
808 
809    Output Parameter:
810 .  x - the result vector
811 
812 .keywords: matrix, linear system, solve, LU, Cholesky, add
813 
814 .seealso: MatSolve(), MatSolveTrans(), MatSolveTransAdd()
815 @*/
816 int MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
817 {
818   Scalar one = 1.0;
819   Vec    tmp;
820   int    ierr;
821   PetscValidHeaderSpecific(mat,MAT_COOKIE);PetscValidHeaderSpecific(y,VEC_COOKIE);
822   PetscValidHeaderSpecific(b,VEC_COOKIE);  PetscValidHeaderSpecific(x,VEC_COOKIE);
823   if (x == b) SETERRQ(1,"MatSolveAdd:x and b must be different vectors");
824   if (!mat->factor) SETERRQ(1,"MatSolveAdd:Unfactored matrix");
825   if (mat->N != x->N) SETERRQ(PETSC_ERR_SIZ,"MatSolveAdd:Mat mat,Vec x: global dim");
826   if (mat->M != b->N) SETERRQ(PETSC_ERR_SIZ,"MatSolveAdd:Mat mat,Vec b: global dim");
827   if (mat->M != y->N) SETERRQ(PETSC_ERR_SIZ,"MatSolveAdd:Mat mat,Vec y: global dim");
828   if (mat->m != b->n) SETERRQ(PETSC_ERR_SIZ,"MatSolveAdd:Mat mat,Vec b: local dim");
829   if (x->n != y->n) SETERRQ(PETSC_ERR_SIZ,"MatSolveAdd:Vec x,Vec y: local dim");
830 
831   PLogEventBegin(MAT_SolveAdd,mat,b,x,y);
832   if (mat->ops.solveadd)  {
833     ierr = (*mat->ops.solveadd)(mat,b,y,x); CHKERRQ(ierr);
834   }
835   else {
836     /* do the solve then the add manually */
837     if (x != y) {
838       ierr = MatSolve(mat,b,x); CHKERRQ(ierr);
839       ierr = VecAXPY(&one,y,x); CHKERRQ(ierr);
840     }
841     else {
842       ierr = VecDuplicate(x,&tmp); CHKERRQ(ierr);
843       PLogObjectParent(mat,tmp);
844       ierr = VecCopy(x,tmp); CHKERRQ(ierr);
845       ierr = MatSolve(mat,b,x); CHKERRQ(ierr);
846       ierr = VecAXPY(&one,tmp,x); CHKERRQ(ierr);
847       ierr = VecDestroy(tmp); CHKERRQ(ierr);
848     }
849   }
850   PLogEventEnd(MAT_SolveAdd,mat,b,x,y);
851   return 0;
852 }
853 /*@
854    MatSolveTrans - Solves A' x = b, given a factored matrix.
855 
856    Input Parameters:
857 .  mat - the factored matrix
858 .  b - the right-hand-side vector
859 
860    Output Parameter:
861 .  x - the result vector
862 
863 .keywords: matrix, linear system, solve, LU, Cholesky, transpose
864 
865 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransAdd()
866 @*/
867 int MatSolveTrans(Mat mat,Vec b,Vec x)
868 {
869   int ierr;
870   PetscValidHeaderSpecific(mat,MAT_COOKIE);
871   PetscValidHeaderSpecific(b,VEC_COOKIE);  PetscValidHeaderSpecific(x,VEC_COOKIE);
872   if (!mat->factor) SETERRQ(1,"MatSolveTrans:Unfactored matrix");
873   if (x == b) SETERRQ(1,"MatSolveTrans:x and b must be different vectors");
874   if (!mat->ops.solvetrans) SETERRQ(PETSC_ERR_SUP,"MatSolveTrans");
875   if (mat->M != x->N) SETERRQ(PETSC_ERR_SIZ,"MatSolveTrans:Mat mat,Vec x: global dim");
876   if (mat->N != b->N) SETERRQ(PETSC_ERR_SIZ,"MatSolveTrans:Mat mat,Vec b: global dim");
877 
878   PLogEventBegin(MAT_SolveTrans,mat,b,x,0);
879   ierr = (*mat->ops.solvetrans)(mat,b,x); CHKERRQ(ierr);
880   PLogEventEnd(MAT_SolveTrans,mat,b,x,0);
881   return 0;
882 }
883 /*@
884    MatSolveTransAdd - Computes x = y + inv(trans(A)) b, given a
885                       factored matrix.
886 
887    Input Parameters:
888 .  mat - the factored matrix
889 .  b - the right-hand-side vector
890 .  y - the vector to be added to
891 
892    Output Parameter:
893 .  x - the result vector
894 
895 .keywords: matrix, linear system, solve, LU, Cholesky, transpose, add
896 
897 .seealso: MatSolve(), MatSolveAdd(), MatSolveTrans()
898 @*/
899 int MatSolveTransAdd(Mat mat,Vec b,Vec y,Vec x)
900 {
901   Scalar one = 1.0;
902   int    ierr;
903   Vec    tmp;
904   PetscValidHeaderSpecific(mat,MAT_COOKIE);PetscValidHeaderSpecific(y,VEC_COOKIE);
905   PetscValidHeaderSpecific(b,VEC_COOKIE);  PetscValidHeaderSpecific(x,VEC_COOKIE);
906   if (x == b) SETERRQ(1,"MatSolveTransAdd:x and b must be different vectors");
907   if (!mat->factor) SETERRQ(1,"MatSolveTransAdd:Unfactored matrix");
908   if (mat->M != x->N) SETERRQ(PETSC_ERR_SIZ,"MatSolveTransAdd:Mat mat,Vec x: global dim");
909   if (mat->N != b->N) SETERRQ(PETSC_ERR_SIZ,"MatSolveTransAdd:Mat mat,Vec b: global dim");
910   if (mat->N != y->N) SETERRQ(PETSC_ERR_SIZ,"MatSolveTransAdd:Mat mat,Vec y: global dim");
911   if (x->n != y->n) SETERRQ(PETSC_ERR_SIZ,"MatSolveTransAdd:Vec x,Vec y: local dim");
912 
913   PLogEventBegin(MAT_SolveTransAdd,mat,b,x,y);
914   if (mat->ops.solvetransadd) {
915     ierr = (*mat->ops.solvetransadd)(mat,b,y,x); CHKERRQ(ierr);
916   }
917   else {
918     /* do the solve then the add manually */
919     if (x != y) {
920       ierr = MatSolveTrans(mat,b,x); CHKERRQ(ierr);
921       ierr = VecAXPY(&one,y,x); CHKERRQ(ierr);
922     }
923     else {
924       ierr = VecDuplicate(x,&tmp); CHKERRQ(ierr);
925       PLogObjectParent(mat,tmp);
926       ierr = VecCopy(x,tmp); CHKERRQ(ierr);
927       ierr = MatSolveTrans(mat,b,x); CHKERRQ(ierr);
928       ierr = VecAXPY(&one,tmp,x); CHKERRQ(ierr);
929       ierr = VecDestroy(tmp); CHKERRQ(ierr);
930     }
931   }
932   PLogEventEnd(MAT_SolveTransAdd,mat,b,x,y);
933   return 0;
934 }
935 /* ----------------------------------------------------------------*/
936 
937 /*@
938    MatRelax - Computes one relaxation sweep.
939 
940    Input Parameters:
941 .  mat - the matrix
942 .  b - the right hand side
943 .  omega - the relaxation factor
944 .  flag - flag indicating the type of SOR, one of
945 $     SOR_FORWARD_SWEEP
946 $     SOR_BACKWARD_SWEEP
947 $     SOR_SYMMETRIC_SWEEP (SSOR method)
948 $     SOR_LOCAL_FORWARD_SWEEP
949 $     SOR_LOCAL_BACKWARD_SWEEP
950 $     SOR_LOCAL_SYMMETRIC_SWEEP (local SSOR)
951 $     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
952 $       upper/lower triangular part of matrix to
953 $       vector (with omega)
954 $     SOR_ZERO_INITIAL_GUESS - zero initial guess
955 .  shift -  diagonal shift
956 .  its - the number of iterations
957 
958    Output Parameters:
959 .  x - the solution (can contain an initial guess)
960 
961    Notes:
962    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
963    SOR_LOCAL_SYMMETRIC_SWEEP perform seperate independent smoothings
964    on each processor.
965 
966    Application programmers will not generally use MatRelax() directly,
967    but instead will employ the SLES/PC interface.
968 
969    Notes for Advanced Users:
970    The flags are implemented as bitwise inclusive or operations.
971    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
972    to specify a zero initial guess for SSOR.
973 
974 .keywords: matrix, relax, relaxation, sweep
975 @*/
976 int MatRelax(Mat mat,Vec b,double omega,MatSORType flag,double shift,
977              int its,Vec x)
978 {
979   int ierr;
980   PetscValidHeaderSpecific(mat,MAT_COOKIE);
981   PetscValidHeaderSpecific(b,VEC_COOKIE);  PetscValidHeaderSpecific(x,VEC_COOKIE);
982   if (!mat->ops.relax) SETERRQ(PETSC_ERR_SUP,"MatRelax");
983   if (!mat->assembled) SETERRQ(1,"MatRelax:Not for unassembled matrix");
984   if (mat->N != x->N) SETERRQ(PETSC_ERR_SIZ,"MatRelax:Mat mat,Vec x: global dim");
985   if (mat->M != b->N) SETERRQ(PETSC_ERR_SIZ,"MatRelax:Mat mat,Vec b: global dim");
986   if (mat->m != b->n) SETERRQ(PETSC_ERR_SIZ,"MatRelax:Mat mat,Vec b: local dim");
987 
988   PLogEventBegin(MAT_Relax,mat,b,x,0);
989   ierr =(*mat->ops.relax)(mat,b,omega,flag,shift,its,x); CHKERRQ(ierr);
990   PLogEventEnd(MAT_Relax,mat,b,x,0);
991   return 0;
992 }
993 
994 /*
995       Default matrix copy routine.
996 */
997 int MatCopy_Basic(Mat A,Mat B)
998 {
999   int    ierr,i,rstart,rend,nz,*cwork;
1000   Scalar *vwork;
1001 
1002   ierr = MatZeroEntries(B); CHKERRQ(ierr);
1003   ierr = MatGetOwnershipRange(A,&rstart,&rend); CHKERRQ(ierr);
1004   for (i=rstart; i<rend; i++) {
1005     ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
1006     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
1007     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
1008   }
1009   ierr = MatAssemblyBegin(B,FINAL_ASSEMBLY); CHKERRQ(ierr);
1010   ierr = MatAssemblyEnd(B,FINAL_ASSEMBLY); CHKERRQ(ierr);
1011   return 0;
1012 }
1013 
1014 /*@C
1015    MatCopy - Copys a matrix to another matrix.
1016 
1017    Input Parameters:
1018 .  A - the matrix
1019 
1020    Output Parameter:
1021 .  B - where the copy is put
1022 
1023    Notes:
1024    MatCopy() copies the matrix entries of a matrix to another existing
1025    matrix (after first zeroing the second matrix).  A related routine is
1026    MatConvert(), which first creates a new matrix and then copies the data.
1027 
1028 .keywords: matrix, copy, convert
1029 
1030 .seealso: MatConvert()
1031 @*/
1032 int MatCopy(Mat A,Mat B)
1033 {
1034   int ierr;
1035   PetscValidHeaderSpecific(A,MAT_COOKIE); PetscValidHeaderSpecific(B,MAT_COOKIE);
1036   if (!A->assembled) SETERRQ(1,"MatCopy:Not for unassembled matrix");
1037   if (A->M != B->M || A->N != B->N) SETERRQ(PETSC_ERR_SIZ,"MatCopy:Mat A,Mat B: global dim");
1038 
1039   PLogEventBegin(MAT_Copy,A,B,0,0);
1040   if (A->ops.copy) {
1041     ierr = (*A->ops.copy)(A,B); CHKERRQ(ierr);
1042   }
1043   else { /* generic conversion */
1044     ierr = MatCopy_Basic(A,B); CHKERRQ(ierr);
1045   }
1046   PLogEventEnd(MAT_Copy,A,B,0,0);
1047   return 0;
1048 }
1049 
1050 /*@C
1051    MatConvert - Converts a matrix to another matrix, either of the same
1052    or different type.
1053 
1054    Input Parameters:
1055 .  mat - the matrix
1056 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
1057    same type as the original matrix.
1058 
1059    Output Parameter:
1060 .  M - pointer to place new matrix
1061 
1062    Notes:
1063    MatConvert() first creates a new matrix and then copies the data from
1064    the first matrix.  A related routine is MatCopy(), which copies the matrix
1065    entries of one matrix to another already existing matrix context.
1066 
1067 .keywords: matrix, copy, convert
1068 
1069 .seealso: MatCopy()
1070 @*/
1071 int MatConvert(Mat mat,MatType newtype,Mat *M)
1072 {
1073   int ierr;
1074   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1075   if (!M) SETERRQ(1,"MatConvert:Bad new matrix address");
1076   if (!mat->assembled) SETERRQ(1,"MatConvert:Not for unassembled matrix");
1077 
1078   PLogEventBegin(MAT_Convert,mat,0,0,0);
1079   if (newtype == mat->type || newtype == MATSAME) {
1080     if (mat->ops.convertsametype) { /* customized copy */
1081       ierr = (*mat->ops.convertsametype)(mat,M,COPY_VALUES); CHKERRQ(ierr);
1082     }
1083     else { /* generic conversion */
1084       ierr = MatConvert_Basic(mat,newtype,M); CHKERRQ(ierr);
1085     }
1086   }
1087   else if (mat->ops.convert) { /* customized conversion */
1088     ierr = (*mat->ops.convert)(mat,newtype,M); CHKERRQ(ierr);
1089   }
1090   else { /* generic conversion */
1091     ierr = MatConvert_Basic(mat,newtype,M); CHKERRQ(ierr);
1092   }
1093   PLogEventEnd(MAT_Convert,mat,0,0,0);
1094   return 0;
1095 }
1096 
1097 /*@
1098    MatGetDiagonal - Gets the diagonal of a matrix.
1099 
1100    Input Parameters:
1101 .  mat - the matrix
1102 .  v - the vector for storing the diagonal
1103 
1104    Output Parameter:
1105 .  v - the diagonal of the matrix
1106 
1107 .keywords: matrix, get, diagonal
1108 @*/
1109 int MatGetDiagonal(Mat mat,Vec v)
1110 {
1111   PetscValidHeaderSpecific(mat,MAT_COOKIE);PetscValidHeaderSpecific(v,VEC_COOKIE);
1112   if (!mat->assembled) SETERRQ(1,"MatGetDiagonal:Not for unassembled matrix");
1113   if (mat->ops.getdiagonal) return (*mat->ops.getdiagonal)(mat,v);
1114   SETERRQ(PETSC_ERR_SUP,"MatGetDiagonal");
1115 }
1116 
1117 /*@C
1118    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
1119 
1120    Input Parameter:
1121 .  mat - the matrix to transpose
1122 
1123    Output Parameters:
1124 .  B - the transpose (or pass in PETSC_NULL for an in-place transpose)
1125 
1126 .keywords: matrix, transpose
1127 
1128 .seealso: MatMultTrans(), MatMultTransAdd()
1129 @*/
1130 int MatTranspose(Mat mat,Mat *B)
1131 {
1132   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1133   if (!mat->assembled) SETERRQ(1,"MatTranspose:Not for unassembled matrix");
1134   if (mat->ops.transpose) return (*mat->ops.transpose)(mat,B);
1135   SETERRQ(PETSC_ERR_SUP,"MatTranspose");
1136 }
1137 
1138 /*@
1139    MatEqual - Compares two matrices.
1140 
1141    Input Parameters:
1142 .  A - the first matrix
1143 .  B - the second matrix
1144 
1145    Output Parameter:
1146 .  flg : PETSC_TRUE if the matrices are equal;
1147          PETSC_FALSE otherwise.
1148 
1149 .keywords: matrix, equal, equivalent
1150 @*/
1151 int MatEqual(Mat A,Mat B,PetscTruth *flg)
1152 {
1153   PetscValidHeaderSpecific(A,MAT_COOKIE); PetscValidHeaderSpecific(B,MAT_COOKIE);
1154   if (!A->assembled) SETERRQ(1,"MatEqual:Not for unassembled matrix");
1155   if (!B->assembled) SETERRQ(1,"MatEqual:Not for unassembled matrix");
1156   if (A->M != B->M || A->N != B->N) SETERRQ(PETSC_ERR_SIZ,"MatCopy:Mat A,Mat B: global dim");
1157   if (A->ops.equal) return (*A->ops.equal)(A,B,flg);
1158   SETERRQ(PETSC_ERR_SUP,"MatEqual");
1159 }
1160 
1161 /*@
1162    MatDiagonalScale - Scales a matrix on the left and right by diagonal
1163    matrices that are stored as vectors.  Either of the two scaling
1164    matrices can be PETSC_NULL.
1165 
1166    Input Parameters:
1167 .  mat - the matrix to be scaled
1168 .  l - the left scaling vector (or PETSC_NULL)
1169 .  r - the right scaling vector (or PETSC_NULL)
1170 
1171    Notes:
1172    MatDiagonalScale() computes A <- LAR, where
1173 $      L = a diagonal matrix
1174 $      R = a diagonal matrix
1175 
1176 .keywords: matrix, diagonal, scale
1177 
1178 .seealso: MatDiagonalScale()
1179 @*/
1180 int MatDiagonalScale(Mat mat,Vec l,Vec r)
1181 {
1182   int ierr;
1183   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1184   if (!mat->ops.diagonalscale) SETERRQ(PETSC_ERR_SUP,"MatDiagonalScale");
1185   if (l) PetscValidHeaderSpecific(l,VEC_COOKIE);
1186   if (r) PetscValidHeaderSpecific(r,VEC_COOKIE);
1187   if (!mat->assembled) SETERRQ(1,"MatDiagonalScale:Not for unassembled matrix");
1188 
1189   PLogEventBegin(MAT_Scale,mat,0,0,0);
1190   ierr = (*mat->ops.diagonalscale)(mat,l,r); CHKERRQ(ierr);
1191   PLogEventEnd(MAT_Scale,mat,0,0,0);
1192   return 0;
1193 }
1194 
1195 /*@
1196     MatScale - Scales all elements of a matrix by a given number.
1197 
1198     Input Parameters:
1199 .   mat - the matrix to be scaled
1200 .   a  - the scaling value
1201 
1202     Output Parameter:
1203 .   mat - the scaled matrix
1204 
1205 .keywords: matrix, scale
1206 
1207 .seealso: MatDiagonalScale()
1208 @*/
1209 int MatScale(Scalar *a,Mat mat)
1210 {
1211   int ierr;
1212   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1213   if (!mat->ops.scale) SETERRQ(PETSC_ERR_SUP,"MatScale");
1214   if (!mat->assembled) SETERRQ(1,"MatScale:Not for unassembled matrix");
1215 
1216   PLogEventBegin(MAT_Scale,mat,0,0,0);
1217   ierr = (*mat->ops.scale)(a,mat); CHKERRQ(ierr);
1218   PLogEventEnd(MAT_Scale,mat,0,0,0);
1219   return 0;
1220 }
1221 
1222 /*@
1223    MatNorm - Calculates various norms of a matrix.
1224 
1225    Input Parameters:
1226 .  mat - the matrix
1227 .  type - the type of norm, NORM_1, NORM_2, NORM_FROBENIUS, NORM_INFINITY
1228 
1229    Output Parameters:
1230 .  norm - the resulting norm
1231 
1232 .keywords: matrix, norm, Frobenius
1233 @*/
1234 int MatNorm(Mat mat,NormType type,double *norm)
1235 {
1236   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1237 
1238   if (!norm) SETERRQ(1,"MatNorm:bad addess for value");
1239   if (!mat->assembled) SETERRQ(1,"MatNorm:Not for unassembled matrix");
1240   if (mat->ops.norm) return (*mat->ops.norm)(mat,type,norm);
1241   SETERRQ(PETSC_ERR_SUP,"MatNorm:Not for this matrix type");
1242 }
1243 
1244 /*@
1245    MatAssemblyBegin - Begins assembling the matrix.  This routine should
1246    be called after completing all calls to MatSetValues().
1247 
1248    Input Parameters:
1249 .  mat - the matrix
1250 .  type - type of assembly, either FLUSH_ASSEMBLY or FINAL_ASSEMBLY
1251 
1252    Notes:
1253    MatSetValues() generally caches the values.  The matrix is ready to
1254    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
1255    Use FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
1256    in MatSetValues(); use FINAL_ASSEMBLY for the final assembly before
1257    using the matrix.
1258 
1259 .keywords: matrix, assembly, assemble, begin
1260 
1261 .seealso: MatAssemblyEnd(), MatSetValues()
1262 @*/
1263 int MatAssemblyBegin(Mat mat,MatAssemblyType type)
1264 {
1265   int ierr;
1266   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1267   if (mat->assembled) {
1268     mat->was_assembled = PETSC_TRUE;
1269     mat->assembled     = PETSC_FALSE;
1270   }
1271   PLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
1272   if (mat->ops.assemblybegin){ierr = (*mat->ops.assemblybegin)(mat,type);CHKERRQ(ierr);}
1273   PLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
1274   return 0;
1275 }
1276 
1277 /*@
1278    MatAssemblyEnd - Completes assembling the matrix.  This routine should
1279    be called after MatAssemblyBegin().
1280 
1281    Input Parameters:
1282 .  mat - the matrix
1283 .  type - type of assembly, either FLUSH_ASSEMBLY or FINAL_ASSEMBLY
1284 
1285    Options Database Keys:
1286 $  -mat_view_info : Prints info on matrix at
1287 $      conclusion of MatEndAssembly()
1288 $  -mat_view_info_detailed: Prints more detailed info.
1289 $  -mat_view : Prints matrix in ASCII format.
1290 $  -mat_view_matlab : Prints matrix in Matlab format.
1291 $  -mat_view_draw : Draws nonzero structure of matrix,
1292 $      using MatView() and DrawOpenX().
1293 $  -display <name> : Set display name (default is host)
1294 $  -draw_pause <sec> : Set number of seconds to pause after display
1295 
1296    Notes:
1297    MatSetValues() generally caches the values.  The matrix is ready to
1298    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
1299    Use FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
1300    in MatSetValues(); use FINAL_ASSEMBLY for the final assembly before
1301    using the matrix.
1302 
1303 .keywords: matrix, assembly, assemble, end
1304 
1305 .seealso: MatAssemblyBegin(), MatSetValues(), DrawOpenX(), MatView()
1306 @*/
1307 int MatAssemblyEnd(Mat mat,MatAssemblyType type)
1308 {
1309   int        ierr,flg;
1310   static int inassm = 0;
1311 
1312   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1313   inassm++;
1314   PLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
1315   if (mat->ops.assemblyend) {ierr = (*mat->ops.assemblyend)(mat,type); CHKERRQ(ierr);}
1316   mat->assembled = PETSC_TRUE; mat->num_ass++;
1317   PLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
1318 
1319   if (inassm == 1) {
1320     ierr = OptionsHasName(PETSC_NULL,"-mat_view_info",&flg); CHKERRQ(ierr);
1321     if (flg) {
1322       Viewer viewer;
1323       ierr = ViewerFileOpenASCII(mat->comm,"stdout",&viewer);CHKERRQ(ierr);
1324       ierr = ViewerSetFormat(viewer,ASCII_FORMAT_INFO,0);CHKERRQ(ierr);
1325       ierr = MatView(mat,viewer); CHKERRQ(ierr);
1326       ierr = ViewerDestroy(viewer); CHKERRQ(ierr);
1327     }
1328     ierr = OptionsHasName(PETSC_NULL,"-mat_view_info_detailed",&flg);CHKERRQ(ierr);
1329     if (flg) {
1330       Viewer viewer;
1331       ierr = ViewerFileOpenASCII(mat->comm,"stdout",&viewer);CHKERRQ(ierr);
1332       ierr = ViewerSetFormat(viewer,ASCII_FORMAT_INFO_DETAILED,0);CHKERRQ(ierr);
1333       ierr = MatView(mat,viewer); CHKERRQ(ierr);
1334       ierr = ViewerDestroy(viewer); CHKERRQ(ierr);
1335     }
1336     ierr = OptionsHasName(PETSC_NULL,"-mat_view",&flg); CHKERRQ(ierr);
1337     if (flg) {
1338       Viewer viewer;
1339       ierr = ViewerFileOpenASCII(mat->comm,"stdout",&viewer);CHKERRQ(ierr);
1340       ierr = MatView(mat,viewer); CHKERRQ(ierr);
1341       ierr = ViewerDestroy(viewer); CHKERRQ(ierr);
1342     }
1343     ierr = OptionsHasName(PETSC_NULL,"-mat_view_matlab",&flg); CHKERRQ(ierr);
1344     if (flg) {
1345       Viewer viewer;
1346       ierr = ViewerFileOpenASCII(mat->comm,"stdout",&viewer);CHKERRQ(ierr);
1347       ierr = ViewerSetFormat(viewer,ASCII_FORMAT_MATLAB,"M");CHKERRQ(ierr);
1348       ierr = MatView(mat,viewer); CHKERRQ(ierr);
1349       ierr = ViewerDestroy(viewer); CHKERRQ(ierr);
1350     }
1351     ierr = OptionsHasName(PETSC_NULL,"-mat_view_draw",&flg); CHKERRQ(ierr);
1352     if (flg) {
1353       Viewer    viewer;
1354       ierr = ViewerDrawOpenX(mat->comm,0,0,0,0,300,300,&viewer); CHKERRQ(ierr);
1355       ierr = MatView(mat,viewer); CHKERRQ(ierr);
1356       ierr = ViewerFlush(viewer); CHKERRQ(ierr);
1357       ierr = ViewerDestroy(viewer); CHKERRQ(ierr);
1358     }
1359   }
1360   inassm--;
1361   return 0;
1362 }
1363 
1364 /*@
1365    MatCompress - Tries to store the matrix in as little space as
1366    possible.  May fail if memory is already fully used, since it
1367    tries to allocate new space.
1368 
1369    Input Parameters:
1370 .  mat - the matrix
1371 
1372 .keywords: matrix, compress
1373 @*/
1374 int MatCompress(Mat mat)
1375 {
1376   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1377   if (mat->ops.compress) return (*mat->ops.compress)(mat);
1378   return 0;
1379 }
1380 /*@
1381    MatSetOption - Sets a parameter option for a matrix. Some options
1382    may be specific to certain storage formats.  Some options
1383    determine how values will be inserted (or added). Sorted,
1384    row-oriented input will generally assemble the fastest. The default
1385    is row-oriented, nonsorted input.
1386 
1387    Input Parameters:
1388 .  mat - the matrix
1389 .  option - the option, one of the following:
1390 $    ROW_ORIENTED
1391 $    COLUMN_ORIENTED,
1392 $    ROWS_SORTED,
1393 $    COLUMNS_SORTED,
1394 $    NO_NEW_NONZERO_LOCATIONS,
1395 $    YES_NEW_NONZERO_LOCATIONS,
1396 $    SYMMETRIC_MATRIX,
1397 $    STRUCTURALLY_SYMMETRIC_MATRIX,
1398 $    NO_NEW_DIAGONALS,
1399 $    YES_NEW_DIAGONALS,
1400 $    and possibly others.
1401 
1402    Notes:
1403    Some options are relevant only for particular matrix types and
1404    are thus ignored by others.  Other options are not supported by
1405    certain matrix types and will generate an error message if set.
1406 
1407    If using a Fortran 77 module to compute a matrix, one may need to
1408    use the column-oriented option (or convert to the row-oriented
1409    format).
1410 
1411    NO_NEW_NONZERO_LOCATIONS indicates that any add or insertion
1412    that will generate a new entry in the nonzero structure is ignored.
1413    What this means is if memory is not allocated for this particular
1414    lot, then the insertion is ignored. For dense matrices, where
1415    the entire array is allocated, no entries are ever ignored.
1416 
1417 .keywords: matrix, option, row-oriented, column-oriented, sorted, nonzero
1418 @*/
1419 int MatSetOption(Mat mat,MatOption op)
1420 {
1421   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1422   if (mat->ops.setoption) return (*mat->ops.setoption)(mat,op);
1423   return 0;
1424 }
1425 
1426 /*@
1427    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
1428    this routine retains the old nonzero structure.
1429 
1430    Input Parameters:
1431 .  mat - the matrix
1432 
1433 .keywords: matrix, zero, entries
1434 
1435 .seealso: MatZeroRows()
1436 @*/
1437 int MatZeroEntries(Mat mat)
1438 {
1439   int ierr;
1440   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1441   if (!mat->ops.zeroentries) SETERRQ(PETSC_ERR_SUP,"MatZeroEntries");
1442 
1443   PLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
1444   ierr = (*mat->ops.zeroentries)(mat); CHKERRQ(ierr);
1445   PLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
1446   return 0;
1447 }
1448 
1449 /*@
1450    MatZeroRows - Zeros all entries (except possibly the main diagonal)
1451    of a set of rows of a matrix.
1452 
1453    Input Parameters:
1454 .  mat - the matrix
1455 .  is - index set of rows to remove
1456 .  diag - pointer to value put in all diagonals of eliminated rows.
1457           Note that diag is not a pointer to an array, but merely a
1458           pointer to a single value.
1459 
1460    Notes:
1461    For the AIJ matrix formats this removes the old nonzero structure,
1462    but does not release memory.  For the dense and block diagonal
1463    formats this does not alter the nonzero structure.
1464 
1465    The user can set a value in the diagonal entry (or for the AIJ and
1466    row formats can optionally remove the main diagonal entry from the
1467    nonzero structure as well, by passing a null pointer as the final
1468    argument).
1469 
1470 .keywords: matrix, zero, rows, boundary conditions
1471 
1472 .seealso: MatZeroEntries(), MatGetSubMatrix(), MatGetSubMatrixInPlace()
1473 @*/
1474 int MatZeroRows(Mat mat,IS is, Scalar *diag)
1475 {
1476   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1477   if (!mat->assembled) SETERRQ(1,"MatZeroRows:Not for unassembled matrix");
1478   if (mat->ops.zerorows) return (*mat->ops.zerorows)(mat,is,diag);
1479   SETERRQ(PETSC_ERR_SUP,"MatZeroRows");
1480 }
1481 
1482 /*@
1483    MatGetSize - Returns the numbers of rows and columns in a matrix.
1484 
1485    Input Parameter:
1486 .  mat - the matrix
1487 
1488    Output Parameters:
1489 .  m - the number of global rows
1490 .  n - the number of global columns
1491 
1492 .keywords: matrix, dimension, size, rows, columns, global, get
1493 
1494 .seealso: MatGetLocalSize()
1495 @*/
1496 int MatGetSize(Mat mat,int *m,int* n)
1497 {
1498   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1499   if (!m || !n) SETERRQ(1,"MatGetSize:Bad address for result");
1500   return (*mat->ops.getsize)(mat,m,n);
1501 }
1502 
1503 /*@
1504    MatGetLocalSize - Returns the number of rows and columns in a matrix
1505    stored locally.  This information may be implementation dependent, so
1506    use with care.
1507 
1508    Input Parameters:
1509 .  mat - the matrix
1510 
1511    Output Parameters:
1512 .  m - the number of local rows
1513 .  n - the number of local columns
1514 
1515 .keywords: matrix, dimension, size, local, rows, columns, get
1516 
1517 .seealso: MatGetSize()
1518 @*/
1519 int MatGetLocalSize(Mat mat,int *m,int* n)
1520 {
1521   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1522   if (!m || !n) SETERRQ(1,"MatGetLocalSize:Bad address for result");
1523   return (*mat->ops.getlocalsize)(mat,m,n);
1524 }
1525 
1526 /*@
1527    MatGetOwnershipRange - Returns the range of matrix rows owned by
1528    this processor, assuming that the matrix is laid out with the first
1529    n1 rows on the first processor, the next n2 rows on the second, etc.
1530    For certain parallel layouts this range may not be well-defined.
1531 
1532    Input Parameters:
1533 .  mat - the matrix
1534 
1535    Output Parameters:
1536 .  m - the first local row
1537 .  n - one more then the last local row
1538 
1539 .keywords: matrix, get, range, ownership
1540 @*/
1541 int MatGetOwnershipRange(Mat mat,int *m,int* n)
1542 {
1543   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1544   if (!m || !n) SETERRQ(1,"MatGetOwnershipRange:Bad address for result");
1545   if (mat->ops.getownershiprange) return (*mat->ops.getownershiprange)(mat,m,n);
1546   SETERRQ(PETSC_ERR_SUP,"MatGetOwnershipRange");
1547 }
1548 
1549 /*@
1550    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
1551    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
1552    to complete the factorization.
1553 
1554    Input Parameters:
1555 .  mat - the matrix
1556 .  row - row permutation
1557 .  column - column permutation
1558 .  fill - number of levels of fill
1559 .  f - expected fill as ratio of the original number of nonzeros,
1560        for example 3.0; choosing this parameter well can result in
1561        more efficient use of time and space.
1562 
1563    Output Parameters:
1564 .  fact - new matrix that has been symbolically factored
1565 
1566    Options Database Key:
1567 $   -mat_ilu_fill <f>, where f is the fill ratio
1568 
1569    Notes:
1570    See the file $(PETSC_DIR)/Performace for additional information about
1571    choosing the fill factor for better efficiency.
1572 
1573 .keywords: matrix, factor, incomplete, ILU, symbolic, fill
1574 
1575 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric()
1576 @*/
1577 int MatILUFactorSymbolic(Mat mat,IS row,IS col,double f,int fill,Mat *fact)
1578 {
1579   int ierr,flg;
1580 
1581   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1582   if (fill < 0) SETERRQ(1,"MatILUFactorSymbolic:Levels of fill negative");
1583   if (!fact) SETERRQ(1,"MatILUFactorSymbolic:Fact argument is missing");
1584   if (!mat->ops.ilufactorsymbolic) SETERRQ(PETSC_ERR_SUP,"MatILUFactorSymbolic");
1585   if (!mat->assembled) SETERRQ(1,"MatILUFactorSymbolic:Not for unassembled matrix");
1586 
1587   ierr = OptionsGetDouble(PETSC_NULL,"-mat_ilu_fill",&f,&flg); CHKERRQ(ierr);
1588   PLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
1589   ierr = (*mat->ops.ilufactorsymbolic)(mat,row,col,f,fill,fact); CHKERRQ(ierr);
1590   PLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
1591   return 0;
1592 }
1593 
1594 /*@
1595    MatIncompleteCholeskyFactorSymbolic - Performs symbolic incomplete
1596    Cholesky factorization for a symmetric matrix.  Use
1597    MatCholeskyFactorNumeric() to complete the factorization.
1598 
1599    Input Parameters:
1600 .  mat - the matrix
1601 .  perm - row and column permutation
1602 .  fill - levels of fill
1603 .  f - expected fill as ratio of original fill
1604 
1605    Output Parameter:
1606 .  fact - the factored matrix
1607 
1608    Note:  Currently only no-fill factorization is supported.
1609 
1610 .keywords: matrix, factor, incomplete, ICC, Cholesky, symbolic, fill
1611 
1612 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor()
1613 @*/
1614 int MatIncompleteCholeskyFactorSymbolic(Mat mat,IS perm,double f,int fill,
1615                                         Mat *fact)
1616 {
1617   int ierr;
1618   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1619   if (fill < 0) SETERRQ(1,"MatIncompleteCholeskyFactorSymbolic:Fill negative");
1620   if (!fact) SETERRQ(1,"MatIncompleteCholeskyFactorSymbolic:Missing fact argument");
1621   if (!mat->ops.incompletecholeskyfactorsymbolic)
1622      SETERRQ(PETSC_ERR_SUP,"MatIncompleteCholeskyFactorSymbolic");
1623   if (!mat->assembled)
1624      SETERRQ(1,"MatIncompleteCholeskyFactorSymbolic:Not for unassembled matrix");
1625 
1626   PLogEventBegin(MAT_IncompleteCholeskyFactorSymbolic,mat,perm,0,0);
1627   ierr = (*mat->ops.incompletecholeskyfactorsymbolic)(mat,perm,f,fill,fact);CHKERRQ(ierr);
1628   PLogEventEnd(MAT_IncompleteCholeskyFactorSymbolic,mat,perm,0,0);
1629   return 0;
1630 }
1631 
1632 /*@C
1633    MatGetArray - Returns a pointer to the element values in the matrix.
1634    This routine  is implementation dependent, and may not even work for
1635    certain matrix types. You MUST call MatRestoreArray() when you no
1636    longer need to access the array.
1637 
1638    Input Parameter:
1639 .  mat - the matrix
1640 
1641    Output Parameter:
1642 .  v - the location of the values
1643 
1644    Fortran Note:
1645    The Fortran interface is slightly different from that given below.
1646    See the Fortran chapter of the users manual and
1647    petsc/src/mat/examples for details.
1648 
1649 .keywords: matrix, array, elements, values
1650 
1651 .seeaols: MatRestoreArray()
1652 @*/
1653 int MatGetArray(Mat mat,Scalar **v)
1654 {
1655   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1656   if (!v) SETERRQ(1,"MatGetArray:Bad input, array pointer location");
1657   if (!mat->ops.getarray) SETERRQ(PETSC_ERR_SUP,"MatGetArray");
1658   return (*mat->ops.getarray)(mat,v);
1659 }
1660 
1661 /*@C
1662    MatRestoreArray - Restores the matrix after MatGetArray has been called.
1663 
1664    Input Parameter:
1665 .  mat - the matrix
1666 .  v - the location of the values
1667 
1668    Fortran Note:
1669    The Fortran interface is slightly different from that given below.
1670    See the users manual and petsc/src/mat/examples for details.
1671 
1672 .keywords: matrix, array, elements, values, resrore
1673 
1674 .seealso: MatGetArray()
1675 @*/
1676 int MatRestoreArray(Mat mat,Scalar **v)
1677 {
1678   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1679   if (!v) SETERRQ(1,"MatRestoreArray:Bad input, array pointer location");
1680   if (!mat->ops.restorearray) SETERRQ(PETSC_ERR_SUP,"MatResroreArray");
1681   return (*mat->ops.restorearray)(mat,v);
1682 }
1683 
1684 /*@C
1685    MatGetSubMatrix - Extracts a submatrix from a matrix. If submat points
1686                      to a valid matrix, it may be reused.
1687 
1688    Input Parameters:
1689 .  mat - the matrix
1690 .  irow, icol - index sets of rows and columns to extract
1691 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
1692 
1693    Output Parameter:
1694 .  submat - the submatrix
1695 
1696    Notes:
1697    MatGetSubMatrix() can be useful in setting boundary conditions.
1698 
1699    Use MatGetSubMatrices() to extract multiple submatrices.
1700 
1701 .keywords: matrix, get, submatrix, boundary conditions
1702 
1703 .seealso: MatZeroRows(), MatGetSubMatrixInPlace(), MatGetSubMatrices()
1704 @*/
1705 int MatGetSubMatrix(Mat mat,IS irow,IS icol,MatGetSubMatrixCall scall,Mat *submat)
1706 {
1707   int ierr;
1708   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1709   if (scall == MAT_REUSE_MATRIX) {
1710     PetscValidHeaderSpecific(*submat,MAT_COOKIE);
1711   }
1712   if (!mat->ops.getsubmatrix) SETERRQ(PETSC_ERR_SUP,"MatGetSubMatrix");
1713   if (!mat->assembled) SETERRQ(1,"MatGetSubMatrix:Not for unassembled matrix");
1714 
1715   /* PLogEventBegin(MAT_GetSubMatrix,mat,irow,icol,0); */
1716   ierr = (*mat->ops.getsubmatrix)(mat,irow,icol,scall,submat); CHKERRQ(ierr);
1717   /* PLogEventEnd(MAT_GetSubMatrix,mat,irow,icol,0); */
1718   return 0;
1719 }
1720 
1721 /*@C
1722    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
1723    points to an array of valid matrices, it may be reused.
1724 
1725    Input Parameters:
1726 .  mat - the matrix
1727 .  irow, icol - index sets of rows and columns to extract
1728 
1729    Output Parameter:
1730 .  submat - the submatrices
1731 
1732    Note:
1733    Use MatGetSubMatrix() for extracting a sinble submatrix.
1734 
1735 .keywords: matrix, get, submatrix, submatrices
1736 
1737 .seealso: MatGetSubMatrix()
1738 @*/
1739 int MatGetSubMatrices(Mat mat,int n, IS *irow,IS *icol,MatGetSubMatrixCall scall,
1740                       Mat **submat)
1741 {
1742   int ierr;
1743   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1744   if (!mat->ops.getsubmatrices) SETERRQ(PETSC_ERR_SUP,"MatGetSubMatrices");
1745   if (!mat->assembled) SETERRQ(1,"MatGetSubMatrices:Not for unassembled matrix");
1746 
1747   PLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
1748   ierr = (*mat->ops.getsubmatrices)(mat,n,irow,icol,scall,submat); CHKERRQ(ierr);
1749   PLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
1750   return 0;
1751 }
1752 
1753 /*@
1754    MatGetSubMatrixInPlace - Extracts a submatrix from a matrix, returning
1755    the submatrix in place of the original matrix.
1756 
1757    Input Parameters:
1758 .  mat - the matrix
1759 .  irow, icol - index sets of rows and columns to extract
1760 
1761 .keywords: matrix, get, submatrix, boundary conditions, in-place
1762 
1763 .seealso: MatZeroRows(), MatGetSubMatrix()
1764 @*/
1765 int MatGetSubMatrixInPlace(Mat mat,IS irow,IS icol)
1766 {
1767   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1768   if (!mat->assembled) SETERRQ(1,"MatGetSubMatrixInPlace:Not for unassembled matrix");
1769 
1770   if (!mat->ops.getsubmatrixinplace) SETERRQ(PETSC_ERR_SUP,"MatGetSubmatrixInPlace");
1771   return (*mat->ops.getsubmatrixinplace)(mat,irow,icol);
1772 }
1773 
1774 /*@
1775    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
1776    replaces the index by larger ones that represent submatrices with more
1777    overlap.
1778 
1779    Input Parameters:
1780 .  mat - the matrix
1781 .  n   - the number of index sets
1782 .  is  - the array of pointers to index sets
1783 .  ov  - the additional overlap requested
1784 
1785 .keywords: matrix, overlap, Schwarz
1786 
1787 .seealso: MatGetSubMatrices()
1788 @*/
1789 int MatIncreaseOverlap(Mat mat,int n, IS *is,int ov)
1790 {
1791   int ierr;
1792   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1793   if (!mat->assembled) SETERRQ(1,"MatIncreaseOverlap:Not for unassembled matrix");
1794 
1795   if (ov == 0) return 0;
1796   if (!mat->ops.increaseoverlap) SETERRQ(PETSC_ERR_SUP,"MatIncreaseOverlap");
1797   PLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
1798   ierr = (*mat->ops.increaseoverlap)(mat,n,is,ov); CHKERRQ(ierr);
1799   PLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
1800   return 0;
1801 }
1802 
1803 /*@
1804    MatPrintHelp - Prints all the options for the matrix.
1805 
1806    Input Parameter:
1807 .  mat - the matrix
1808 
1809    Options Database Keys:
1810 $  -help, -h
1811 
1812 .keywords: mat, help
1813 
1814 .seealso: MatCreate(), MatCreateXXX()
1815 @*/
1816 int MatPrintHelp(Mat mat)
1817 {
1818   static int called = 0;
1819   MPI_Comm   comm = mat->comm;
1820 
1821   if (!called) {
1822     PetscPrintf(comm,"General matrix options:\n");
1823     PetscPrintf(comm,"  -mat_view_info : view basic matrix info during MatAssemblyEnd()\n");
1824     PetscPrintf(comm,"  -mat_view_info_detailed : view detailed matrix info during MatAssemblyEnd()\n");
1825     PetscPrintf(comm,"  -mat_view_draw : draw nonzero matrix structure during MatAssemblyEnd()\n");
1826     PetscPrintf(comm,"      -draw_pause <sec> : set seconds of display pause\n");
1827     PetscPrintf(comm,"      -display <name> : set alternate display\n");
1828     called = 1;
1829   }
1830   if (mat->ops.printhelp) (*mat->ops.printhelp)(mat);
1831   return 0;
1832 }
1833 
1834