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