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