xref: /petsc/src/mat/interface/matrix.c (revision bac399c20ecee5b1ee9f76762aea50d757f447a1)
1 /*$Id: matrix.c,v 1.414 2001/09/28 18:57:28 balay 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    (http://www.llnl.gov/CASC/hypre)
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 #ifndef PETSC_HAVE_CONSTRAINTS
1098   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1099   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
1100   if (mat->m != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %d %d",mat->m,y->n);
1101 #endif
1102 
1103   if (mat->nullsp) {
1104     ierr = MatNullSpaceRemove(mat->nullsp,x,&x);CHKERRQ(ierr);
1105   }
1106 
1107   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
1108   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
1109   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
1110 
1111   if (mat->nullsp) {
1112     ierr = MatNullSpaceRemove(mat->nullsp,y,PETSC_NULL);CHKERRQ(ierr);
1113   }
1114   PetscFunctionReturn(0);
1115 }
1116 
1117 #undef __FUNCT__
1118 #define __FUNCT__ "MatMultTranspose"
1119 /*@
1120    MatMultTranspose - Computes matrix transpose times a vector.
1121 
1122    Collective on Mat and Vec
1123 
1124    Input Parameters:
1125 +  mat - the matrix
1126 -  x   - the vector to be multilplied
1127 
1128    Output Parameters:
1129 .  y - the result
1130 
1131    Notes:
1132    The vectors x and y cannot be the same.  I.e., one cannot
1133    call MatMultTranspose(A,y,y).
1134 
1135    Level: beginner
1136 
1137    Concepts: matrix vector product^transpose
1138 
1139 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd()
1140 @*/
1141 int MatMultTranspose(Mat mat,Vec x,Vec y)
1142 {
1143   int ierr;
1144 
1145   PetscFunctionBegin;
1146   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1147   PetscValidType(mat);
1148   MatPreallocated(mat);
1149   PetscValidHeaderSpecific(x,VEC_COOKIE);
1150   PetscValidHeaderSpecific(y,VEC_COOKIE);
1151 
1152   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1153   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1154   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1155 #ifndef PETSC_HAVE_CONSTRAINTS
1156   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
1157   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->N,y->N);
1158 #endif
1159 
1160   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
1161   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
1162   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
1163   PetscFunctionReturn(0);
1164 }
1165 
1166 #undef __FUNCT__
1167 #define __FUNCT__ "MatMultAdd"
1168 /*@
1169     MatMultAdd -  Computes v3 = v2 + A * v1.
1170 
1171     Collective on Mat and Vec
1172 
1173     Input Parameters:
1174 +   mat - the matrix
1175 -   v1, v2 - the vectors
1176 
1177     Output Parameters:
1178 .   v3 - the result
1179 
1180     Notes:
1181     The vectors v1 and v3 cannot be the same.  I.e., one cannot
1182     call MatMultAdd(A,v1,v2,v1).
1183 
1184     Level: beginner
1185 
1186     Concepts: matrix vector product^addition
1187 
1188 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
1189 @*/
1190 int MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1191 {
1192   int ierr;
1193 
1194   PetscFunctionBegin;
1195   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1196   PetscValidType(mat);
1197   MatPreallocated(mat);
1198   PetscValidHeaderSpecific(v1,VEC_COOKIE);
1199   PetscValidHeaderSpecific(v2,VEC_COOKIE);
1200   PetscValidHeaderSpecific(v3,VEC_COOKIE);
1201 
1202   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1203   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1204   if (mat->N != v1->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %d %d",mat->N,v1->N);
1205   if (mat->M != v2->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %d %d",mat->M,v2->N);
1206   if (mat->M != v3->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %d %d",mat->M,v3->N);
1207   if (mat->m != v3->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %d %d",mat->m,v3->n);
1208   if (mat->m != v2->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %d %d",mat->m,v2->n);
1209   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1210 
1211   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1212   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
1213   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1214   PetscFunctionReturn(0);
1215 }
1216 
1217 #undef __FUNCT__
1218 #define __FUNCT__ "MatMultTransposeAdd"
1219 /*@
1220    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
1221 
1222    Collective on Mat and Vec
1223 
1224    Input Parameters:
1225 +  mat - the matrix
1226 -  v1, v2 - the vectors
1227 
1228    Output Parameters:
1229 .  v3 - the result
1230 
1231    Notes:
1232    The vectors v1 and v3 cannot be the same.  I.e., one cannot
1233    call MatMultTransposeAdd(A,v1,v2,v1).
1234 
1235    Level: beginner
1236 
1237    Concepts: matrix vector product^transpose and addition
1238 
1239 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
1240 @*/
1241 int MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1242 {
1243   int ierr;
1244 
1245   PetscFunctionBegin;
1246   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1247   PetscValidType(mat);
1248   MatPreallocated(mat);
1249   PetscValidHeaderSpecific(v1,VEC_COOKIE);
1250   PetscValidHeaderSpecific(v2,VEC_COOKIE);
1251   PetscValidHeaderSpecific(v3,VEC_COOKIE);
1252 
1253   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1254   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1255   if (!mat->ops->multtransposeadd) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1256   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1257   if (mat->M != v1->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %d %d",mat->M,v1->N);
1258   if (mat->N != v2->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %d %d",mat->N,v2->N);
1259   if (mat->N != v3->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %d %d",mat->N,v3->N);
1260 
1261   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1262   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
1263   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1264   PetscFunctionReturn(0);
1265 }
1266 
1267 #undef __FUNCT__
1268 #define __FUNCT__ "MatMultConstrained"
1269 /*@
1270    MatMultConstrained - The inner multiplication routine for a
1271    constrained matrix P^T A P.
1272 
1273    Collective on Mat and Vec
1274 
1275    Input Parameters:
1276 +  mat - the matrix
1277 -  x   - the vector to be multilplied
1278 
1279    Output Parameters:
1280 .  y - the result
1281 
1282    Notes:
1283    The vectors x and y cannot be the same.  I.e., one cannot
1284    call MatMult(A,y,y).
1285 
1286    Level: beginner
1287 
1288 .keywords: matrix, multiply, matrix-vector product, constraint
1289 .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1290 @*/
1291 int MatMultConstrained(Mat mat,Vec x,Vec y)
1292 {
1293   int ierr;
1294 
1295   PetscFunctionBegin;
1296   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1297   PetscValidHeaderSpecific(x,VEC_COOKIE);PetscValidHeaderSpecific(y,VEC_COOKIE);
1298   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1299   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1300   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1301   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1302   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
1303   if (mat->m != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %d %d",mat->m,y->n);
1304 
1305   MatLogEventBegin(MAT_MultConstrained,mat,x,y,0);
1306   ierr = (*mat->ops->multconstrained)(mat,x,y); CHKERRQ(ierr);
1307   MatLogEventEnd(MAT_MultConstrained,mat,x,y,0);
1308 
1309   PetscFunctionReturn(0);
1310 }
1311 
1312 #undef __FUNCT__
1313 #define __FUNCT__ "MatMultTransposeConstrained"
1314 /*@
1315    MatMultTransposeConstrained - The inner multiplication routine for a
1316    constrained matrix P^T A^T P.
1317 
1318    Collective on Mat and Vec
1319 
1320    Input Parameters:
1321 +  mat - the matrix
1322 -  x   - the vector to be multilplied
1323 
1324    Output Parameters:
1325 .  y - the result
1326 
1327    Notes:
1328    The vectors x and y cannot be the same.  I.e., one cannot
1329    call MatMult(A,y,y).
1330 
1331    Level: beginner
1332 
1333 .keywords: matrix, multiply, matrix-vector product, constraint
1334 .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1335 @*/
1336 int MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
1337 {
1338   int ierr;
1339 
1340   PetscFunctionBegin;
1341   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1342   PetscValidHeaderSpecific(x,VEC_COOKIE);PetscValidHeaderSpecific(y,VEC_COOKIE);
1343   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1344   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1345   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1346   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1347   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
1348 
1349   MatLogEventBegin(MAT_MultConstrained,mat,x,y,0);
1350   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y); CHKERRQ(ierr);
1351   MatLogEventEnd(MAT_MultConstrained,mat,x,y,0);
1352 
1353   PetscFunctionReturn(0);
1354 }
1355 /* ------------------------------------------------------------*/
1356 #undef __FUNCT__
1357 #define __FUNCT__ "MatGetInfo"
1358 /*@C
1359    MatGetInfo - Returns information about matrix storage (number of
1360    nonzeros, memory, etc.).
1361 
1362    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used
1363    as the flag
1364 
1365    Input Parameters:
1366 .  mat - the matrix
1367 
1368    Output Parameters:
1369 +  flag - flag indicating the type of parameters to be returned
1370    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
1371    MAT_GLOBAL_SUM - sum over all processors)
1372 -  info - matrix information context
1373 
1374    Notes:
1375    The MatInfo context contains a variety of matrix data, including
1376    number of nonzeros allocated and used, number of mallocs during
1377    matrix assembly, etc.  Additional information for factored matrices
1378    is provided (such as the fill ratio, number of mallocs during
1379    factorization, etc.).  Much of this info is printed to STDOUT
1380    when using the runtime options
1381 $       -log_info -mat_view_info
1382 
1383    Example for C/C++ Users:
1384    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
1385    data within the MatInfo context.  For example,
1386 .vb
1387       MatInfo info;
1388       Mat     A;
1389       double  mal, nz_a, nz_u;
1390 
1391       MatGetInfo(A,MAT_LOCAL,&info);
1392       mal  = info.mallocs;
1393       nz_a = info.nz_allocated;
1394 .ve
1395 
1396    Example for Fortran Users:
1397    Fortran users should declare info as a double precision
1398    array of dimension MAT_INFO_SIZE, and then extract the parameters
1399    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
1400    a complete list of parameter names.
1401 .vb
1402       double  precision info(MAT_INFO_SIZE)
1403       double  precision mal, nz_a
1404       Mat     A
1405       integer ierr
1406 
1407       call MatGetInfo(A,MAT_LOCAL,info,ierr)
1408       mal = info(MAT_INFO_MALLOCS)
1409       nz_a = info(MAT_INFO_NZ_ALLOCATED)
1410 .ve
1411 
1412     Level: intermediate
1413 
1414     Concepts: matrices^getting information on
1415 
1416 @*/
1417 int MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
1418 {
1419   int ierr;
1420 
1421   PetscFunctionBegin;
1422   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1423   PetscValidType(mat);
1424   MatPreallocated(mat);
1425   PetscValidPointer(info);
1426   if (!mat->ops->getinfo) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1427   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
1428   PetscFunctionReturn(0);
1429 }
1430 
1431 /* ----------------------------------------------------------*/
1432 #undef __FUNCT__
1433 #define __FUNCT__ "MatILUDTFactor"
1434 /*@C
1435    MatILUDTFactor - Performs a drop tolerance ILU factorization.
1436 
1437    Collective on Mat
1438 
1439    Input Parameters:
1440 +  mat - the matrix
1441 .  info - information about the factorization to be done
1442 .  row - row permutation
1443 -  col - column permutation
1444 
1445    Output Parameters:
1446 .  fact - the factored matrix
1447 
1448    Level: developer
1449 
1450    Notes:
1451    Most users should employ the simplified SLES interface for linear solvers
1452    instead of working directly with matrix algebra routines such as this.
1453    See, e.g., SLESCreate().
1454 
1455    This is currently only supported for the SeqAIJ matrix format using code
1456    from Yousef Saad's SPARSEKIT2  package (translated to C with f2c) and/or
1457    Matlab. SPARSEKIT2 is copyrighted by Yousef Saad with the GNU copyright
1458    and thus can be distributed with PETSc.
1459 
1460     Concepts: matrices^ILUDT factorization
1461 
1462 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatILUInfo
1463 @*/
1464 int MatILUDTFactor(Mat mat,MatILUInfo *info,IS row,IS col,Mat *fact)
1465 {
1466   int ierr;
1467 
1468   PetscFunctionBegin;
1469   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1470   PetscValidType(mat);
1471   MatPreallocated(mat);
1472   PetscValidPointer(fact);
1473   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1474   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1475   if (!mat->ops->iludtfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1476 
1477   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1478   ierr = (*mat->ops->iludtfactor)(mat,info,row,col,fact);CHKERRQ(ierr);
1479   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1480 
1481   PetscFunctionReturn(0);
1482 }
1483 
1484 #undef __FUNCT__
1485 #define __FUNCT__ "MatLUFactor"
1486 /*@
1487    MatLUFactor - Performs in-place LU factorization of matrix.
1488 
1489    Collective on Mat
1490 
1491    Input Parameters:
1492 +  mat - the matrix
1493 .  row - row permutation
1494 .  col - column permutation
1495 -  info - options for factorization, includes
1496 $          fill - expected fill as ratio of original fill.
1497 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
1498 $                   Run with the option -log_info to determine an optimal value to use
1499 
1500    Notes:
1501    Most users should employ the simplified SLES interface for linear solvers
1502    instead of working directly with matrix algebra routines such as this.
1503    See, e.g., SLESCreate().
1504 
1505    This changes the state of the matrix to a factored matrix; it cannot be used
1506    for example with MatSetValues() unless one first calls MatSetUnfactored().
1507 
1508    Level: developer
1509 
1510    Concepts: matrices^LU factorization
1511 
1512 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
1513           MatGetOrdering(), MatSetUnfactored(), MatLUInfo
1514 
1515 @*/
1516 int MatLUFactor(Mat mat,IS row,IS col,MatLUInfo *info)
1517 {
1518   int ierr;
1519 
1520   PetscFunctionBegin;
1521   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1522   PetscValidType(mat);
1523   MatPreallocated(mat);
1524   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1525   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1526   if (!mat->ops->lufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1527 
1528   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
1529   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
1530   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
1531   PetscFunctionReturn(0);
1532 }
1533 
1534 #undef __FUNCT__
1535 #define __FUNCT__ "MatILUFactor"
1536 /*@
1537    MatILUFactor - Performs in-place ILU factorization of matrix.
1538 
1539    Collective on Mat
1540 
1541    Input Parameters:
1542 +  mat - the matrix
1543 .  row - row permutation
1544 .  col - column permutation
1545 -  info - structure containing
1546 $      levels - number of levels of fill.
1547 $      expected fill - as ratio of original fill.
1548 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
1549                 missing diagonal entries)
1550 
1551    Notes:
1552    Probably really in-place only when level of fill is zero, otherwise allocates
1553    new space to store factored matrix and deletes previous memory.
1554 
1555    Most users should employ the simplified SLES interface for linear solvers
1556    instead of working directly with matrix algebra routines such as this.
1557    See, e.g., SLESCreate().
1558 
1559    Level: developer
1560 
1561    Concepts: matrices^ILU factorization
1562 
1563 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatILUInfo
1564 @*/
1565 int MatILUFactor(Mat mat,IS row,IS col,MatILUInfo *info)
1566 {
1567   int ierr;
1568 
1569   PetscFunctionBegin;
1570   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1571   PetscValidType(mat);
1572   MatPreallocated(mat);
1573   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
1574   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1575   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1576   if (!mat->ops->ilufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1577 
1578   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1579   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
1580   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1581   PetscFunctionReturn(0);
1582 }
1583 
1584 #undef __FUNCT__
1585 #define __FUNCT__ "MatLUFactorSymbolic"
1586 /*@
1587    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
1588    Call this routine before calling MatLUFactorNumeric().
1589 
1590    Collective on Mat
1591 
1592    Input Parameters:
1593 +  mat - the matrix
1594 .  row, col - row and column permutations
1595 -  info - options for factorization, includes
1596 $          fill - expected fill as ratio of original fill.
1597 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
1598 $                   Run with the option -log_info to determine an optimal value to use
1599 
1600    Output Parameter:
1601 .  fact - new matrix that has been symbolically factored
1602 
1603    Notes:
1604    See the users manual for additional information about
1605    choosing the fill factor for better efficiency.
1606 
1607    Most users should employ the simplified SLES interface for linear solvers
1608    instead of working directly with matrix algebra routines such as this.
1609    See, e.g., SLESCreate().
1610 
1611    Level: developer
1612 
1613    Concepts: matrices^LU symbolic factorization
1614 
1615 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatLUInfo
1616 @*/
1617 int MatLUFactorSymbolic(Mat mat,IS row,IS col,MatLUInfo *info,Mat *fact)
1618 {
1619   int ierr;
1620 
1621   PetscFunctionBegin;
1622   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1623   PetscValidType(mat);
1624   MatPreallocated(mat);
1625   PetscValidPointer(fact);
1626   PetscValidHeaderSpecific(row,IS_COOKIE);
1627   PetscValidHeaderSpecific(col,IS_COOKIE);
1628   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1629   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1630   if (!mat->ops->lufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic LU",mat->type_name);
1631 
1632   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
1633   ierr = (*mat->ops->lufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
1634   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
1635   PetscFunctionReturn(0);
1636 }
1637 
1638 #undef __FUNCT__
1639 #define __FUNCT__ "MatLUFactorNumeric"
1640 /*@
1641    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
1642    Call this routine after first calling MatLUFactorSymbolic().
1643 
1644    Collective on Mat
1645 
1646    Input Parameters:
1647 +  mat - the matrix
1648 -  fact - the matrix generated for the factor, from MatLUFactorSymbolic()
1649 
1650    Notes:
1651    See MatLUFactor() for in-place factorization.  See
1652    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
1653 
1654    Most users should employ the simplified SLES interface for linear solvers
1655    instead of working directly with matrix algebra routines such as this.
1656    See, e.g., SLESCreate().
1657 
1658    Level: developer
1659 
1660    Concepts: matrices^LU numeric factorization
1661 
1662 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
1663 @*/
1664 int MatLUFactorNumeric(Mat mat,Mat *fact)
1665 {
1666   int        ierr;
1667   PetscTruth flg;
1668 
1669   PetscFunctionBegin;
1670   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1671   PetscValidType(mat);
1672   MatPreallocated(mat);
1673   PetscValidPointer(fact);
1674   PetscValidHeaderSpecific(*fact,MAT_COOKIE);
1675   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1676   if (mat->M != (*fact)->M || mat->N != (*fact)->N) {
1677     SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat *fact: global dimensions are different %d should = %d %d should = %d",
1678             mat->M,(*fact)->M,mat->N,(*fact)->N);
1679   }
1680   if (!(*fact)->ops->lufactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1681 
1682   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
1683   ierr = (*(*fact)->ops->lufactornumeric)(mat,fact);CHKERRQ(ierr);
1684   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
1685   ierr = PetscOptionsHasName(PETSC_NULL,"-mat_view_draw",&flg);CHKERRQ(ierr);
1686   if (flg) {
1687     ierr = PetscOptionsHasName(PETSC_NULL,"-mat_view_contour",&flg);CHKERRQ(ierr);
1688     if (flg) {
1689       ierr = PetscViewerPushFormat(PETSC_VIEWER_DRAW_(mat->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
1690     }
1691     ierr = MatView(*fact,PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
1692     ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
1693     if (flg) {
1694       ierr = PetscViewerPopFormat(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
1695     }
1696   }
1697   PetscFunctionReturn(0);
1698 }
1699 
1700 #undef __FUNCT__
1701 #define __FUNCT__ "MatCholeskyFactor"
1702 /*@
1703    MatCholeskyFactor - Performs in-place Cholesky factorization of a
1704    symmetric matrix.
1705 
1706    Collective on Mat
1707 
1708    Input Parameters:
1709 +  mat - the matrix
1710 .  perm - row and column permutations
1711 -  f - expected fill as ratio of original fill
1712 
1713    Notes:
1714    See MatLUFactor() for the nonsymmetric case.  See also
1715    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
1716 
1717    Most users should employ the simplified SLES interface for linear solvers
1718    instead of working directly with matrix algebra routines such as this.
1719    See, e.g., SLESCreate().
1720 
1721    Level: developer
1722 
1723    Concepts: matrices^Cholesky factorization
1724 
1725 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
1726           MatGetOrdering()
1727 
1728 @*/
1729 int MatCholeskyFactor(Mat mat,IS perm,PetscReal f)
1730 {
1731   int ierr;
1732 
1733   PetscFunctionBegin;
1734   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1735   PetscValidType(mat);
1736   MatPreallocated(mat);
1737   PetscValidHeaderSpecific(perm,IS_COOKIE);
1738   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
1739   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1740   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1741   if (!mat->ops->choleskyfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1742 
1743   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
1744   ierr = (*mat->ops->choleskyfactor)(mat,perm,f);CHKERRQ(ierr);
1745   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
1746   PetscFunctionReturn(0);
1747 }
1748 
1749 #undef __FUNCT__
1750 #define __FUNCT__ "MatCholeskyFactorSymbolic"
1751 /*@
1752    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
1753    of a symmetric matrix.
1754 
1755    Collective on Mat
1756 
1757    Input Parameters:
1758 +  mat - the matrix
1759 .  perm - row and column permutations
1760 -  f - expected fill as ratio of original
1761 
1762    Output Parameter:
1763 .  fact - the factored matrix
1764 
1765    Notes:
1766    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
1767    MatCholeskyFactor() and MatCholeskyFactorNumeric().
1768 
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 symbolic factorization
1776 
1777 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
1778           MatGetOrdering()
1779 
1780 @*/
1781 int MatCholeskyFactorSymbolic(Mat mat,IS perm,PetscReal f,Mat *fact)
1782 {
1783   int ierr;
1784 
1785   PetscFunctionBegin;
1786   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1787   PetscValidType(mat);
1788   MatPreallocated(mat);
1789   PetscValidPointer(fact);
1790   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
1791   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1792   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1793   if (!mat->ops->choleskyfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1794 
1795   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
1796   ierr = (*mat->ops->choleskyfactorsymbolic)(mat,perm,f,fact);CHKERRQ(ierr);
1797   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
1798   PetscFunctionReturn(0);
1799 }
1800 
1801 #undef __FUNCT__
1802 #define __FUNCT__ "MatCholeskyFactorNumeric"
1803 /*@
1804    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
1805    of a symmetric matrix. Call this routine after first calling
1806    MatCholeskyFactorSymbolic().
1807 
1808    Collective on Mat
1809 
1810    Input Parameter:
1811 .  mat - the initial matrix
1812 
1813    Output Parameter:
1814 .  fact - the factored matrix
1815 
1816    Notes:
1817    Most users should employ the simplified SLES interface for linear solvers
1818    instead of working directly with matrix algebra routines such as this.
1819    See, e.g., SLESCreate().
1820 
1821    Level: developer
1822 
1823    Concepts: matrices^Cholesky numeric factorization
1824 
1825 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
1826 @*/
1827 int MatCholeskyFactorNumeric(Mat mat,Mat *fact)
1828 {
1829   int ierr;
1830 
1831   PetscFunctionBegin;
1832   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1833   PetscValidType(mat);
1834   MatPreallocated(mat);
1835   PetscValidPointer(fact);
1836   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1837   if (!(*fact)->ops->choleskyfactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1838   if (mat->M != (*fact)->M || mat->N != (*fact)->N) {
1839     SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat *fact: global dim %d should = %d %d should = %d",
1840             mat->M,(*fact)->M,mat->N,(*fact)->N);
1841   }
1842 
1843   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
1844   ierr = (*(*fact)->ops->choleskyfactornumeric)(mat,fact);CHKERRQ(ierr);
1845   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
1846   PetscFunctionReturn(0);
1847 }
1848 
1849 /* ----------------------------------------------------------------*/
1850 #undef __FUNCT__
1851 #define __FUNCT__ "MatSolve"
1852 /*@
1853    MatSolve - Solves A x = b, given a factored matrix.
1854 
1855    Collective on Mat and Vec
1856 
1857    Input Parameters:
1858 +  mat - the factored matrix
1859 -  b - the right-hand-side vector
1860 
1861    Output Parameter:
1862 .  x - the result vector
1863 
1864    Notes:
1865    The vectors b and x cannot be the same.  I.e., one cannot
1866    call MatSolve(A,x,x).
1867 
1868    Notes:
1869    Most users should employ the simplified SLES interface for linear solvers
1870    instead of working directly with matrix algebra routines such as this.
1871    See, e.g., SLESCreate().
1872 
1873    Level: developer
1874 
1875    Concepts: matrices^triangular solves
1876 
1877 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
1878 @*/
1879 int MatSolve(Mat mat,Vec b,Vec x)
1880 {
1881   int ierr;
1882 
1883   PetscFunctionBegin;
1884   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1885   PetscValidType(mat);
1886   MatPreallocated(mat);
1887   PetscValidHeaderSpecific(b,VEC_COOKIE);
1888   PetscValidHeaderSpecific(x,VEC_COOKIE);
1889   PetscCheckSameComm(mat,b);
1890   PetscCheckSameComm(mat,x);
1891   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
1892   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
1893   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1894   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
1895   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
1896   if (mat->M == 0 && mat->N == 0) PetscFunctionReturn(0);
1897 
1898   if (!mat->ops->solve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1899   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
1900   ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
1901   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
1902   PetscFunctionReturn(0);
1903 }
1904 
1905 #undef __FUNCT__
1906 #define __FUNCT__ "MatForwardSolve"
1907 /* @
1908    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU.
1909 
1910    Collective on Mat and Vec
1911 
1912    Input Parameters:
1913 +  mat - the factored matrix
1914 -  b - the right-hand-side vector
1915 
1916    Output Parameter:
1917 .  x - the result vector
1918 
1919    Notes:
1920    MatSolve() should be used for most applications, as it performs
1921    a forward solve followed by a backward solve.
1922 
1923    The vectors b and x cannot be the same.  I.e., one cannot
1924    call MatForwardSolve(A,x,x).
1925 
1926    Most users should employ the simplified SLES interface for linear solvers
1927    instead of working directly with matrix algebra routines such as this.
1928    See, e.g., SLESCreate().
1929 
1930    Level: developer
1931 
1932    Concepts: matrices^forward solves
1933 
1934 .seealso: MatSolve(), MatBackwardSolve()
1935 @ */
1936 int MatForwardSolve(Mat mat,Vec b,Vec x)
1937 {
1938   int ierr;
1939 
1940   PetscFunctionBegin;
1941   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1942   PetscValidType(mat);
1943   MatPreallocated(mat);
1944   PetscValidHeaderSpecific(b,VEC_COOKIE);
1945   PetscValidHeaderSpecific(x,VEC_COOKIE);
1946   PetscCheckSameComm(mat,b);
1947   PetscCheckSameComm(mat,x);
1948   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
1949   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
1950   if (!mat->ops->forwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1951   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1952   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
1953   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
1954 
1955   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
1956   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
1957   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
1958   PetscFunctionReturn(0);
1959 }
1960 
1961 #undef __FUNCT__
1962 #define __FUNCT__ "MatBackwardSolve"
1963 /* @
1964    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
1965 
1966    Collective on Mat and Vec
1967 
1968    Input Parameters:
1969 +  mat - the factored matrix
1970 -  b - the right-hand-side vector
1971 
1972    Output Parameter:
1973 .  x - the result vector
1974 
1975    Notes:
1976    MatSolve() should be used for most applications, as it performs
1977    a forward solve followed by a backward solve.
1978 
1979    The vectors b and x cannot be the same.  I.e., one cannot
1980    call MatBackwardSolve(A,x,x).
1981 
1982    Most users should employ the simplified SLES interface for linear solvers
1983    instead of working directly with matrix algebra routines such as this.
1984    See, e.g., SLESCreate().
1985 
1986    Level: developer
1987 
1988    Concepts: matrices^backward solves
1989 
1990 .seealso: MatSolve(), MatForwardSolve()
1991 @ */
1992 int MatBackwardSolve(Mat mat,Vec b,Vec x)
1993 {
1994   int ierr;
1995 
1996   PetscFunctionBegin;
1997   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1998   PetscValidType(mat);
1999   MatPreallocated(mat);
2000   PetscValidHeaderSpecific(b,VEC_COOKIE);
2001   PetscValidHeaderSpecific(x,VEC_COOKIE);
2002   PetscCheckSameComm(mat,b);
2003   PetscCheckSameComm(mat,x);
2004   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2005   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2006   if (!mat->ops->backwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2007   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2008   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2009   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2010 
2011   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
2012   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
2013   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
2014   PetscFunctionReturn(0);
2015 }
2016 
2017 #undef __FUNCT__
2018 #define __FUNCT__ "MatSolveAdd"
2019 /*@
2020    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
2021 
2022    Collective on Mat and Vec
2023 
2024    Input Parameters:
2025 +  mat - the factored matrix
2026 .  b - the right-hand-side vector
2027 -  y - the vector to be added to
2028 
2029    Output Parameter:
2030 .  x - the result vector
2031 
2032    Notes:
2033    The vectors b and x cannot be the same.  I.e., one cannot
2034    call MatSolveAdd(A,x,y,x).
2035 
2036    Most users should employ the simplified SLES interface for linear solvers
2037    instead of working directly with matrix algebra routines such as this.
2038    See, e.g., SLESCreate().
2039 
2040    Level: developer
2041 
2042    Concepts: matrices^triangular solves
2043 
2044 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
2045 @*/
2046 int MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
2047 {
2048   PetscScalar one = 1.0;
2049   Vec    tmp;
2050   int    ierr;
2051 
2052   PetscFunctionBegin;
2053   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2054   PetscValidType(mat);
2055   MatPreallocated(mat);
2056   PetscValidHeaderSpecific(y,VEC_COOKIE);
2057   PetscValidHeaderSpecific(b,VEC_COOKIE);
2058   PetscValidHeaderSpecific(x,VEC_COOKIE);
2059   PetscCheckSameComm(mat,b);
2060   PetscCheckSameComm(mat,y);
2061   PetscCheckSameComm(mat,x);
2062   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2063   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2064   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2065   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2066   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
2067   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2068   if (x->n != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %d %d",x->n,y->n);
2069 
2070   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
2071   if (mat->ops->solveadd)  {
2072     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
2073   } else {
2074     /* do the solve then the add manually */
2075     if (x != y) {
2076       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
2077       ierr = VecAXPY(&one,y,x);CHKERRQ(ierr);
2078     } else {
2079       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
2080       PetscLogObjectParent(mat,tmp);
2081       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
2082       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
2083       ierr = VecAXPY(&one,tmp,x);CHKERRQ(ierr);
2084       ierr = VecDestroy(tmp);CHKERRQ(ierr);
2085     }
2086   }
2087   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
2088   PetscFunctionReturn(0);
2089 }
2090 
2091 #undef __FUNCT__
2092 #define __FUNCT__ "MatSolveTranspose"
2093 /*@
2094    MatSolveTranspose - Solves A' x = b, given a factored matrix.
2095 
2096    Collective on Mat and Vec
2097 
2098    Input Parameters:
2099 +  mat - the factored matrix
2100 -  b - the right-hand-side vector
2101 
2102    Output Parameter:
2103 .  x - the result vector
2104 
2105    Notes:
2106    The vectors b and x cannot be the same.  I.e., one cannot
2107    call MatSolveTranspose(A,x,x).
2108 
2109    Most users should employ the simplified SLES interface for linear solvers
2110    instead of working directly with matrix algebra routines such as this.
2111    See, e.g., SLESCreate().
2112 
2113    Level: developer
2114 
2115    Concepts: matrices^triangular solves
2116 
2117 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
2118 @*/
2119 int MatSolveTranspose(Mat mat,Vec b,Vec x)
2120 {
2121   int ierr;
2122 
2123   PetscFunctionBegin;
2124   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2125   PetscValidType(mat);
2126   MatPreallocated(mat);
2127   PetscValidHeaderSpecific(b,VEC_COOKIE);
2128   PetscValidHeaderSpecific(x,VEC_COOKIE);
2129   PetscCheckSameComm(mat,b);
2130   PetscCheckSameComm(mat,x);
2131   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2132   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2133   if (!mat->ops->solvetranspose) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s",mat->type_name);
2134   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
2135   if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->N,b->N);
2136 
2137   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
2138   ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
2139   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
2140   PetscFunctionReturn(0);
2141 }
2142 
2143 #undef __FUNCT__
2144 #define __FUNCT__ "MatSolveTransposeAdd"
2145 /*@
2146    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
2147                       factored matrix.
2148 
2149    Collective on Mat and Vec
2150 
2151    Input Parameters:
2152 +  mat - the factored matrix
2153 .  b - the right-hand-side vector
2154 -  y - the vector to be added to
2155 
2156    Output Parameter:
2157 .  x - the result vector
2158 
2159    Notes:
2160    The vectors b and x cannot be the same.  I.e., one cannot
2161    call MatSolveTransposeAdd(A,x,y,x).
2162 
2163    Most users should employ the simplified SLES interface for linear solvers
2164    instead of working directly with matrix algebra routines such as this.
2165    See, e.g., SLESCreate().
2166 
2167    Level: developer
2168 
2169    Concepts: matrices^triangular solves
2170 
2171 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
2172 @*/
2173 int MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
2174 {
2175   PetscScalar one = 1.0;
2176   int         ierr;
2177   Vec         tmp;
2178 
2179   PetscFunctionBegin;
2180   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2181   PetscValidType(mat);
2182   MatPreallocated(mat);
2183   PetscValidHeaderSpecific(y,VEC_COOKIE);
2184   PetscValidHeaderSpecific(b,VEC_COOKIE);
2185   PetscValidHeaderSpecific(x,VEC_COOKIE);
2186   PetscCheckSameComm(mat,b);
2187   PetscCheckSameComm(mat,y);
2188   PetscCheckSameComm(mat,x);
2189   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2190   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2191   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
2192   if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->N,b->N);
2193   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->N,y->N);
2194   if (x->n != y->n)   SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %d %d",x->n,y->n);
2195 
2196   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
2197   if (mat->ops->solvetransposeadd) {
2198     ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
2199   } else {
2200     /* do the solve then the add manually */
2201     if (x != y) {
2202       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
2203       ierr = VecAXPY(&one,y,x);CHKERRQ(ierr);
2204     } else {
2205       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
2206       PetscLogObjectParent(mat,tmp);
2207       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
2208       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
2209       ierr = VecAXPY(&one,tmp,x);CHKERRQ(ierr);
2210       ierr = VecDestroy(tmp);CHKERRQ(ierr);
2211     }
2212   }
2213   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
2214   PetscFunctionReturn(0);
2215 }
2216 /* ----------------------------------------------------------------*/
2217 
2218 #undef __FUNCT__
2219 #define __FUNCT__ "MatRelax"
2220 /*@
2221    MatRelax - Computes one relaxation sweep.
2222 
2223    Collective on Mat and Vec
2224 
2225    Input Parameters:
2226 +  mat - the matrix
2227 .  b - the right hand side
2228 .  omega - the relaxation factor
2229 .  flag - flag indicating the type of SOR (see below)
2230 .  shift -  diagonal shift
2231 -  its - the number of iterations
2232 
2233    Output Parameters:
2234 .  x - the solution (can contain an initial guess)
2235 
2236    SOR Flags:
2237 .     SOR_FORWARD_SWEEP - forward SOR
2238 .     SOR_BACKWARD_SWEEP - backward SOR
2239 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
2240 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
2241 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
2242 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
2243 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
2244          upper/lower triangular part of matrix to
2245          vector (with omega)
2246 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
2247 
2248    Notes:
2249    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
2250    SOR_LOCAL_SYMMETRIC_SWEEP perform seperate independent smoothings
2251    on each processor.
2252 
2253    Application programmers will not generally use MatRelax() directly,
2254    but instead will employ the SLES/PC interface.
2255 
2256    Notes for Advanced Users:
2257    The flags are implemented as bitwise inclusive or operations.
2258    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
2259    to specify a zero initial guess for SSOR.
2260 
2261    Most users should employ the simplified SLES interface for linear solvers
2262    instead of working directly with matrix algebra routines such as this.
2263    See, e.g., SLESCreate().
2264 
2265    Level: developer
2266 
2267    Concepts: matrices^relaxation
2268    Concepts: matrices^SOR
2269    Concepts: matrices^Gauss-Seidel
2270 
2271 @*/
2272 int MatRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,int its,Vec x)
2273 {
2274   int ierr;
2275 
2276   PetscFunctionBegin;
2277   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2278   PetscValidType(mat);
2279   MatPreallocated(mat);
2280   PetscValidHeaderSpecific(b,VEC_COOKIE);
2281   PetscValidHeaderSpecific(x,VEC_COOKIE);
2282   PetscCheckSameComm(mat,b);
2283   PetscCheckSameComm(mat,x);
2284   if (!mat->ops->relax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2285   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2286   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2287   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2288   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2289   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2290 
2291   ierr = PetscLogEventBegin(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2292   ierr =(*mat->ops->relax)(mat,b,omega,flag,shift,its,x);CHKERRQ(ierr);
2293   ierr = PetscLogEventEnd(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2294   PetscFunctionReturn(0);
2295 }
2296 
2297 #undef __FUNCT__
2298 #define __FUNCT__ "MatCopy_Basic"
2299 /*
2300       Default matrix copy routine.
2301 */
2302 int MatCopy_Basic(Mat A,Mat B,MatStructure str)
2303 {
2304   int         ierr,i,rstart,rend,nz,*cwork;
2305   PetscScalar *vwork;
2306 
2307   PetscFunctionBegin;
2308   ierr = MatZeroEntries(B);CHKERRQ(ierr);
2309   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
2310   for (i=rstart; i<rend; i++) {
2311     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
2312     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
2313     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
2314   }
2315   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2316   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2317   PetscFunctionReturn(0);
2318 }
2319 
2320 #undef __FUNCT__
2321 #define __FUNCT__ "MatCopy"
2322 /*@C
2323    MatCopy - Copys a matrix to another matrix.
2324 
2325    Collective on Mat
2326 
2327    Input Parameters:
2328 +  A - the matrix
2329 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
2330 
2331    Output Parameter:
2332 .  B - where the copy is put
2333 
2334    Notes:
2335    If you use SAME_NONZERO_PATTERN then the zero matrices had better have the
2336    same nonzero pattern or the routine will crash.
2337 
2338    MatCopy() copies the matrix entries of a matrix to another existing
2339    matrix (after first zeroing the second matrix).  A related routine is
2340    MatConvert(), which first creates a new matrix and then copies the data.
2341 
2342    Level: intermediate
2343 
2344    Concepts: matrices^copying
2345 
2346 .seealso: MatConvert()
2347 @*/
2348 int MatCopy(Mat A,Mat B,MatStructure str)
2349 {
2350   int ierr;
2351 
2352   PetscFunctionBegin;
2353   PetscValidHeaderSpecific(A,MAT_COOKIE);
2354   PetscValidHeaderSpecific(B,MAT_COOKIE);
2355   PetscValidType(A);
2356   MatPreallocated(A);
2357   PetscValidType(B);
2358   MatPreallocated(B);
2359   PetscCheckSameComm(A,B);
2360   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2361   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2362   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,
2363                                              A->N,B->N);
2364 
2365   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
2366   if (A->ops->copy) {
2367     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
2368   } else { /* generic conversion */
2369     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2370   }
2371   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
2372   PetscFunctionReturn(0);
2373 }
2374 
2375 #include "petscsys.h"
2376 PetscTruth MatConvertRegisterAllCalled = PETSC_FALSE;
2377 PetscFList MatConvertList              = 0;
2378 
2379 #undef __FUNCT__
2380 #define __FUNCT__ "MatConvertRegister"
2381 /*@C
2382     MatConvertRegister - Allows one to register a routine that reads matrices
2383         from a binary file for a particular matrix type.
2384 
2385   Not Collective
2386 
2387   Input Parameters:
2388 +   type - the type of matrix (defined in include/petscmat.h), for example, MATSEQAIJ.
2389 -   Converter - the function that reads the matrix from the binary file.
2390 
2391   Level: developer
2392 
2393 .seealso: MatConvertRegisterAll(), MatConvert()
2394 
2395 @*/
2396 int MatConvertRegister(char *sname,char *path,char *name,int (*function)(Mat,MatType,Mat*))
2397 {
2398   int  ierr;
2399   char fullname[256];
2400 
2401   PetscFunctionBegin;
2402   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
2403   ierr = PetscFListAdd(&MatConvertList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
2404   PetscFunctionReturn(0);
2405 }
2406 
2407 #undef __FUNCT__
2408 #define __FUNCT__ "MatConvert"
2409 /*@C
2410    MatConvert - Converts a matrix to another matrix, either of the same
2411    or different type.
2412 
2413    Collective on Mat
2414 
2415    Input Parameters:
2416 +  mat - the matrix
2417 -  newtype - new matrix type.  Use MATSAME to create a new matrix of the
2418    same type as the original matrix.
2419 
2420    Output Parameter:
2421 .  M - pointer to place new matrix
2422 
2423    Notes:
2424    MatConvert() first creates a new matrix and then copies the data from
2425    the first matrix.  A related routine is MatCopy(), which copies the matrix
2426    entries of one matrix to another already existing matrix context.
2427 
2428    Level: intermediate
2429 
2430    Concepts: matrices^converting between storage formats
2431 
2432 .seealso: MatCopy(), MatDuplicate()
2433 @*/
2434 int MatConvert(Mat mat,MatType newtype,Mat *M)
2435 {
2436   int        ierr;
2437   PetscTruth sametype,issame,flg;
2438   char       convname[256],mtype[256];
2439 
2440   PetscFunctionBegin;
2441   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2442   PetscValidType(mat);
2443   MatPreallocated(mat);
2444   PetscValidPointer(M);
2445   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2446   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2447 
2448   ierr = PetscOptionsGetString(PETSC_NULL,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
2449   if (flg) {
2450     newtype = mtype;
2451   }
2452   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2453 
2454   ierr = PetscTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
2455   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
2456   if ((sametype || issame) && mat->ops->duplicate) {
2457     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
2458   } else {
2459     int (*conv)(Mat,MatType,Mat*);
2460     if (!MatConvertRegisterAllCalled) {
2461       ierr = MatConvertRegisterAll(PETSC_NULL);CHKERRQ(ierr);
2462     }
2463     ierr = PetscFListFind(mat->comm,MatConvertList,newtype,(void(**)(void))&conv);CHKERRQ(ierr);
2464     if (conv) {
2465       ierr = (*conv)(mat,newtype,M);CHKERRQ(ierr);
2466     } else {
2467       ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
2468       ierr = PetscStrcat(convname,mat->type_name);CHKERRQ(ierr);
2469       ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
2470       ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
2471       ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
2472       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
2473       if (conv) {
2474         ierr = (*conv)(mat,newtype,M);CHKERRQ(ierr);
2475       } else {
2476         if (mat->ops->convert) {
2477           ierr = (*mat->ops->convert)(mat,newtype,M);CHKERRQ(ierr);
2478         } else {
2479           ierr = MatConvert_Basic(mat,newtype,M);CHKERRQ(ierr);
2480         }
2481       }
2482     }
2483   }
2484   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2485   PetscFunctionReturn(0);
2486 }
2487 
2488 
2489 #undef __FUNCT__
2490 #define __FUNCT__ "MatDuplicate"
2491 /*@C
2492    MatDuplicate - Duplicates a matrix including the non-zero structure.
2493 
2494    Collective on Mat
2495 
2496    Input Parameters:
2497 +  mat - the matrix
2498 -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
2499         values as well or not
2500 
2501    Output Parameter:
2502 .  M - pointer to place new matrix
2503 
2504    Level: intermediate
2505 
2506    Concepts: matrices^duplicating
2507 
2508 .seealso: MatCopy(), MatConvert()
2509 @*/
2510 int MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
2511 {
2512   int ierr;
2513 
2514   PetscFunctionBegin;
2515   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2516   PetscValidType(mat);
2517   MatPreallocated(mat);
2518   PetscValidPointer(M);
2519   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2520   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2521 
2522   *M  = 0;
2523   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2524   if (!mat->ops->duplicate) {
2525     SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type");
2526   }
2527   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
2528   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2529   PetscFunctionReturn(0);
2530 }
2531 
2532 #undef __FUNCT__
2533 #define __FUNCT__ "MatGetDiagonal"
2534 /*@
2535    MatGetDiagonal - Gets the diagonal of a matrix.
2536 
2537    Collective on Mat and Vec
2538 
2539    Input Parameters:
2540 +  mat - the matrix
2541 -  v - the vector for storing the diagonal
2542 
2543    Output Parameter:
2544 .  v - the diagonal of the matrix
2545 
2546    Notes:
2547    For the SeqAIJ matrix format, this routine may also be called
2548    on a LU factored matrix; in that case it routines the reciprocal of
2549    the diagonal entries in U. It returns the entries permuted by the
2550    row and column permutation used during the symbolic factorization.
2551 
2552    Level: intermediate
2553 
2554    Concepts: matrices^accessing diagonals
2555 
2556 .seealso: MatGetRow(), MatGetSubmatrices(), MatGetSubmatrix(), MatGetRowMax()
2557 @*/
2558 int MatGetDiagonal(Mat mat,Vec v)
2559 {
2560   int ierr;
2561 
2562   PetscFunctionBegin;
2563   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2564   PetscValidType(mat);
2565   MatPreallocated(mat);
2566   PetscValidHeaderSpecific(v,VEC_COOKIE);
2567   /* PetscCheckSameComm(mat,v); Could be MPI vector but Seq matrix cause of two submatrix storage */
2568   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2569   if (!mat->ops->getdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2570 
2571   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
2572   PetscFunctionReturn(0);
2573 }
2574 
2575 #undef __FUNCT__
2576 #define __FUNCT__ "MatGetRowMax"
2577 /*@
2578    MatGetRowMax - Gets the maximum value (in absolute value) of each
2579         row of the matrix
2580 
2581    Collective on Mat and Vec
2582 
2583    Input Parameters:
2584 .  mat - the matrix
2585 
2586    Output Parameter:
2587 .  v - the vector for storing the maximums
2588 
2589    Level: intermediate
2590 
2591    Concepts: matrices^getting row maximums
2592 
2593 .seealso: MatGetDiagonal(), MatGetSubmatrices(), MatGetSubmatrix()
2594 @*/
2595 int MatGetRowMax(Mat mat,Vec v)
2596 {
2597   int ierr;
2598 
2599   PetscFunctionBegin;
2600   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2601   PetscValidType(mat);
2602   MatPreallocated(mat);
2603   PetscValidHeaderSpecific(v,VEC_COOKIE);
2604   /* PetscCheckSameComm(mat,v); Could be MPI vector but Seq matrix cause of two submatrix storage */
2605   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2606   if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2607 
2608   ierr = (*mat->ops->getrowmax)(mat,v);CHKERRQ(ierr);
2609   PetscFunctionReturn(0);
2610 }
2611 
2612 #undef __FUNCT__
2613 #define __FUNCT__ "MatTranspose"
2614 /*@C
2615    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
2616 
2617    Collective on Mat
2618 
2619    Input Parameter:
2620 .  mat - the matrix to transpose
2621 
2622    Output Parameters:
2623 .  B - the transpose (or pass in PETSC_NULL for an in-place transpose)
2624 
2625    Level: intermediate
2626 
2627    Concepts: matrices^transposing
2628 
2629 .seealso: MatMultTranspose(), MatMultTransposeAdd()
2630 @*/
2631 int MatTranspose(Mat mat,Mat *B)
2632 {
2633   int ierr;
2634 
2635   PetscFunctionBegin;
2636   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2637   PetscValidType(mat);
2638   MatPreallocated(mat);
2639   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2640   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2641   if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2642   ierr = (*mat->ops->transpose)(mat,B);CHKERRQ(ierr);
2643   PetscFunctionReturn(0);
2644 }
2645 
2646 #undef __FUNCT__
2647 #define __FUNCT__ "MatPermute"
2648 /*@C
2649    MatPermute - Creates a new matrix with rows and columns permuted from the
2650    original.
2651 
2652    Collective on Mat
2653 
2654    Input Parameters:
2655 +  mat - the matrix to permute
2656 .  row - row permutation, each processor supplies only the permutation for its rows
2657 -  col - column permutation, each processor needs the entire column permutation, that is
2658          this is the same size as the total number of columns in the matrix
2659 
2660    Output Parameters:
2661 .  B - the permuted matrix
2662 
2663    Level: advanced
2664 
2665    Concepts: matrices^permuting
2666 
2667 .seealso: MatGetOrdering()
2668 @*/
2669 int MatPermute(Mat mat,IS row,IS col,Mat *B)
2670 {
2671   int ierr;
2672 
2673   PetscFunctionBegin;
2674   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2675   PetscValidType(mat);
2676   MatPreallocated(mat);
2677   PetscValidHeaderSpecific(row,IS_COOKIE);
2678   PetscValidHeaderSpecific(col,IS_COOKIE);
2679   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2680   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2681   if (!mat->ops->permute) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2682   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
2683   PetscFunctionReturn(0);
2684 }
2685 
2686 #undef __FUNCT__
2687 #define __FUNCT__ "MatPermuteSparsify"
2688 /*@C
2689   MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the
2690   original and sparsified to the prescribed tolerance.
2691 
2692   Collective on Mat
2693 
2694   Input Parameters:
2695 + A    - The matrix to permute
2696 . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
2697 . frac - The half-bandwidth as a fraction of the total size, or 0.0
2698 . tol  - The drop tolerance
2699 . rowp - The row permutation
2700 - colp - The column permutation
2701 
2702   Output Parameter:
2703 . B    - The permuted, sparsified matrix
2704 
2705   Level: advanced
2706 
2707   Note:
2708   The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
2709   restrict the half-bandwidth of the resulting matrix to 5% of the
2710   total matrix size.
2711 
2712 .keywords: matrix, permute, sparsify
2713 
2714 .seealso: MatGetOrdering(), MatPermute()
2715 @*/
2716 int MatPermuteSparsify(Mat A, int band, double frac, double tol, IS rowp, IS colp, Mat *B)
2717 {
2718   IS           irowp, icolp;
2719   int         *rows, *cols;
2720   int          M, N, locRowStart, locRowEnd;
2721   int          nz, newNz;
2722   int         *cwork, *cnew;
2723   PetscScalar *vwork, *vnew;
2724   int          bw, size;
2725   int          row, locRow, newRow, col, newCol;
2726   int          ierr;
2727 
2728   PetscFunctionBegin;
2729   PetscValidHeaderSpecific(A,    MAT_COOKIE);
2730   PetscValidHeaderSpecific(rowp, IS_COOKIE);
2731   PetscValidHeaderSpecific(colp, IS_COOKIE);
2732   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
2733   if (A->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
2734   if (!A->ops->permutesparsify) {
2735     ierr = MatGetSize(A, &M, &N);                                                                         CHKERRQ(ierr);
2736     ierr = MatGetOwnershipRange(A, &locRowStart, &locRowEnd);                                             CHKERRQ(ierr);
2737     ierr = ISGetSize(rowp, &size);                                                                        CHKERRQ(ierr);
2738     if (size != M) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %d for row permutation, should be %d", size, M);
2739     ierr = ISGetSize(colp, &size);                                                                        CHKERRQ(ierr);
2740     if (size != N) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %d for column permutation, should be %d", size, N);
2741     ierr = ISInvertPermutation(rowp, 0, &irowp);                                                          CHKERRQ(ierr);
2742     ierr = ISGetIndices(irowp, &rows);                                                                    CHKERRQ(ierr);
2743     ierr = ISInvertPermutation(colp, 0, &icolp);                                                          CHKERRQ(ierr);
2744     ierr = ISGetIndices(icolp, &cols);                                                                    CHKERRQ(ierr);
2745     ierr = PetscMalloc(N * sizeof(int),         &cnew);                                                   CHKERRQ(ierr);
2746     ierr = PetscMalloc(N * sizeof(PetscScalar), &vnew);                                                   CHKERRQ(ierr);
2747 
2748     /* Setup bandwidth to include */
2749     if (band == PETSC_DECIDE) {
2750       if (frac <= 0.0)
2751         bw = (int) (M * 0.05);
2752       else
2753         bw = (int) (M * frac);
2754     } else {
2755       if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
2756       bw = band;
2757     }
2758 
2759     /* Put values into new matrix */
2760     ierr = MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B);                                                    CHKERRQ(ierr);
2761     for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) {
2762       ierr = MatGetRow(A, row, &nz, &cwork, &vwork);                                                      CHKERRQ(ierr);
2763       newRow   = rows[locRow]+locRowStart;
2764       for(col = 0, newNz = 0; col < nz; col++) {
2765         newCol = cols[cwork[col]];
2766         if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (fabs(vwork[col]) >= tol)) {
2767           cnew[newNz] = newCol;
2768           vnew[newNz] = vwork[col];
2769           newNz++;
2770         }
2771       }
2772       ierr = MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES);                              CHKERRQ(ierr);
2773       ierr = MatRestoreRow(A, row, &nz, &cwork, &vwork);                                                  CHKERRQ(ierr);
2774     }
2775     ierr = PetscFree(cnew);                                                                               CHKERRQ(ierr);
2776     ierr = PetscFree(vnew);                                                                               CHKERRQ(ierr);
2777     ierr = MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY);                                                      CHKERRQ(ierr);
2778     ierr = MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY);                                                        CHKERRQ(ierr);
2779     ierr = ISRestoreIndices(irowp, &rows);                                                                CHKERRQ(ierr);
2780     ierr = ISRestoreIndices(icolp, &cols);                                                                CHKERRQ(ierr);
2781     ierr = ISDestroy(irowp);                                                                              CHKERRQ(ierr);
2782     ierr = ISDestroy(icolp);                                                                              CHKERRQ(ierr);
2783   } else {
2784     ierr = (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B);                                 CHKERRQ(ierr);
2785   }
2786   PetscFunctionReturn(0);
2787 }
2788 
2789 #undef __FUNCT__
2790 #define __FUNCT__ "MatEqual"
2791 /*@
2792    MatEqual - Compares two matrices.
2793 
2794    Collective on Mat
2795 
2796    Input Parameters:
2797 +  A - the first matrix
2798 -  B - the second matrix
2799 
2800    Output Parameter:
2801 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
2802 
2803    Level: intermediate
2804 
2805    Concepts: matrices^equality between
2806 @*/
2807 int MatEqual(Mat A,Mat B,PetscTruth *flg)
2808 {
2809   int ierr;
2810 
2811   PetscFunctionBegin;
2812   PetscValidHeaderSpecific(A,MAT_COOKIE);
2813   PetscValidHeaderSpecific(B,MAT_COOKIE);
2814   PetscValidType(A);
2815   MatPreallocated(A);
2816   PetscValidType(B);
2817   MatPreallocated(B);
2818   PetscValidIntPointer(flg);
2819   PetscCheckSameComm(A,B);
2820   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2821   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2822   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);
2823   if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",A->type_name);
2824   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
2825   PetscFunctionReturn(0);
2826 }
2827 
2828 #undef __FUNCT__
2829 #define __FUNCT__ "MatDiagonalScale"
2830 /*@
2831    MatDiagonalScale - Scales a matrix on the left and right by diagonal
2832    matrices that are stored as vectors.  Either of the two scaling
2833    matrices can be PETSC_NULL.
2834 
2835    Collective on Mat
2836 
2837    Input Parameters:
2838 +  mat - the matrix to be scaled
2839 .  l - the left scaling vector (or PETSC_NULL)
2840 -  r - the right scaling vector (or PETSC_NULL)
2841 
2842    Notes:
2843    MatDiagonalScale() computes A = LAR, where
2844    L = a diagonal matrix, R = a diagonal matrix
2845 
2846    Level: intermediate
2847 
2848    Concepts: matrices^diagonal scaling
2849    Concepts: diagonal scaling of matrices
2850 
2851 .seealso: MatScale()
2852 @*/
2853 int MatDiagonalScale(Mat mat,Vec l,Vec r)
2854 {
2855   int ierr;
2856 
2857   PetscFunctionBegin;
2858   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2859   PetscValidType(mat);
2860   MatPreallocated(mat);
2861   if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2862   if (l) {PetscValidHeaderSpecific(l,VEC_COOKIE);PetscCheckSameComm(mat,l);}
2863   if (r) {PetscValidHeaderSpecific(r,VEC_COOKIE);PetscCheckSameComm(mat,r);}
2864   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2865   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2866 
2867   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
2868   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
2869   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
2870   PetscFunctionReturn(0);
2871 }
2872 
2873 #undef __FUNCT__
2874 #define __FUNCT__ "MatScale"
2875 /*@
2876     MatScale - Scales all elements of a matrix by a given number.
2877 
2878     Collective on Mat
2879 
2880     Input Parameters:
2881 +   mat - the matrix to be scaled
2882 -   a  - the scaling value
2883 
2884     Output Parameter:
2885 .   mat - the scaled matrix
2886 
2887     Level: intermediate
2888 
2889     Concepts: matrices^scaling all entries
2890 
2891 .seealso: MatDiagonalScale()
2892 @*/
2893 int MatScale(PetscScalar *a,Mat mat)
2894 {
2895   int ierr;
2896 
2897   PetscFunctionBegin;
2898   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2899   PetscValidType(mat);
2900   MatPreallocated(mat);
2901   PetscValidScalarPointer(a);
2902   if (!mat->ops->scale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2903   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2904   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2905 
2906   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
2907   ierr = (*mat->ops->scale)(a,mat);CHKERRQ(ierr);
2908   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
2909   PetscFunctionReturn(0);
2910 }
2911 
2912 #undef __FUNCT__
2913 #define __FUNCT__ "MatNorm"
2914 /*@
2915    MatNorm - Calculates various norms of a matrix.
2916 
2917    Collective on Mat
2918 
2919    Input Parameters:
2920 +  mat - the matrix
2921 -  type - the type of norm, NORM_1, NORM_2, NORM_FROBENIUS, NORM_INFINITY
2922 
2923    Output Parameters:
2924 .  norm - the resulting norm
2925 
2926    Level: intermediate
2927 
2928    Concepts: matrices^norm
2929    Concepts: norm^of matrix
2930 @*/
2931 int MatNorm(Mat mat,NormType type,PetscReal *norm)
2932 {
2933   int ierr;
2934 
2935   PetscFunctionBegin;
2936   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2937   PetscValidType(mat);
2938   MatPreallocated(mat);
2939   PetscValidScalarPointer(norm);
2940 
2941   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2942   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2943   if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2944   ierr = (*mat->ops->norm)(mat,type,norm);CHKERRQ(ierr);
2945   PetscFunctionReturn(0);
2946 }
2947 
2948 /*
2949      This variable is used to prevent counting of MatAssemblyBegin() that
2950    are called from within a MatAssemblyEnd().
2951 */
2952 static int MatAssemblyEnd_InUse = 0;
2953 #undef __FUNCT__
2954 #define __FUNCT__ "MatAssemblyBegin"
2955 /*@
2956    MatAssemblyBegin - Begins assembling the matrix.  This routine should
2957    be called after completing all calls to MatSetValues().
2958 
2959    Collective on Mat
2960 
2961    Input Parameters:
2962 +  mat - the matrix
2963 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
2964 
2965    Notes:
2966    MatSetValues() generally caches the values.  The matrix is ready to
2967    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
2968    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
2969    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
2970    using the matrix.
2971 
2972    Level: beginner
2973 
2974    Concepts: matrices^assembling
2975 
2976 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
2977 @*/
2978 int MatAssemblyBegin(Mat mat,MatAssemblyType type)
2979 {
2980   int ierr;
2981 
2982   PetscFunctionBegin;
2983   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2984   PetscValidType(mat);
2985   MatPreallocated(mat);
2986   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
2987   if (mat->assembled) {
2988     mat->was_assembled = PETSC_TRUE;
2989     mat->assembled     = PETSC_FALSE;
2990   }
2991   if (!MatAssemblyEnd_InUse) {
2992     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
2993     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
2994     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
2995   } else {
2996     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
2997   }
2998   PetscFunctionReturn(0);
2999 }
3000 
3001 #undef __FUNCT__
3002 #define __FUNCT__ "MatAssembed"
3003 /*@
3004    MatAssembled - Indicates if a matrix has been assembled and is ready for
3005      use; for example, in matrix-vector product.
3006 
3007    Collective on Mat
3008 
3009    Input Parameter:
3010 .  mat - the matrix
3011 
3012    Output Parameter:
3013 .  assembled - PETSC_TRUE or PETSC_FALSE
3014 
3015    Level: advanced
3016 
3017    Concepts: matrices^assembled?
3018 
3019 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
3020 @*/
3021 int MatAssembled(Mat mat,PetscTruth *assembled)
3022 {
3023   PetscFunctionBegin;
3024   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3025   PetscValidType(mat);
3026   MatPreallocated(mat);
3027   *assembled = mat->assembled;
3028   PetscFunctionReturn(0);
3029 }
3030 
3031 #undef __FUNCT__
3032 #define __FUNCT__ "MatView_Private"
3033 /*
3034     Processes command line options to determine if/how a matrix
3035   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
3036 */
3037 int MatView_Private(Mat mat)
3038 {
3039   int        ierr;
3040   PetscTruth flg;
3041 
3042   PetscFunctionBegin;
3043   ierr = PetscOptionsHasName(mat->prefix,"-mat_view_info",&flg);CHKERRQ(ierr);
3044   if (flg) {
3045     ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
3046     ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3047     ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3048   }
3049   ierr = PetscOptionsHasName(mat->prefix,"-mat_view_info_detailed",&flg);CHKERRQ(ierr);
3050   if (flg) {
3051     ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO_LONG);CHKERRQ(ierr);
3052     ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3053     ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3054   }
3055   ierr = PetscOptionsHasName(mat->prefix,"-mat_view",&flg);CHKERRQ(ierr);
3056   if (flg) {
3057     ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3058   }
3059   ierr = PetscOptionsHasName(mat->prefix,"-mat_view_matlab",&flg);CHKERRQ(ierr);
3060   if (flg) {
3061     ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr);
3062     ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3063     ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3064   }
3065   ierr = PetscOptionsHasName(mat->prefix,"-mat_view_draw",&flg);CHKERRQ(ierr);
3066   if (flg) {
3067     ierr = PetscOptionsHasName(mat->prefix,"-mat_view_contour",&flg);CHKERRQ(ierr);
3068     if (flg) {
3069       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(mat->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
3070     }
3071     ierr = MatView(mat,PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3072     ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3073     if (flg) {
3074       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3075     }
3076   }
3077   ierr = PetscOptionsHasName(mat->prefix,"-mat_view_socket",&flg);CHKERRQ(ierr);
3078   if (flg) {
3079     ierr = MatView(mat,PETSC_VIEWER_SOCKET_(mat->comm));CHKERRQ(ierr);
3080     ierr = PetscViewerFlush(PETSC_VIEWER_SOCKET_(mat->comm));CHKERRQ(ierr);
3081   }
3082   ierr = PetscOptionsHasName(mat->prefix,"-mat_view_binary",&flg);CHKERRQ(ierr);
3083   if (flg) {
3084     ierr = MatView(mat,PETSC_VIEWER_BINARY_(mat->comm));CHKERRQ(ierr);
3085     ierr = PetscViewerFlush(PETSC_VIEWER_BINARY_(mat->comm));CHKERRQ(ierr);
3086   }
3087   PetscFunctionReturn(0);
3088 }
3089 
3090 #undef __FUNCT__
3091 #define __FUNCT__ "MatAssemblyEnd"
3092 /*@
3093    MatAssemblyEnd - Completes assembling the matrix.  This routine should
3094    be called after MatAssemblyBegin().
3095 
3096    Collective on Mat
3097 
3098    Input Parameters:
3099 +  mat - the matrix
3100 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
3101 
3102    Options Database Keys:
3103 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
3104 .  -mat_view_info_detailed - Prints more detailed info
3105 .  -mat_view - Prints matrix in ASCII format
3106 .  -mat_view_matlab - Prints matrix in Matlab format
3107 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
3108 .  -display <name> - Sets display name (default is host)
3109 -  -draw_pause <sec> - Sets number of seconds to pause after display
3110 
3111    Notes:
3112    MatSetValues() generally caches the values.  The matrix is ready to
3113    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
3114    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
3115    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
3116    using the matrix.
3117 
3118    Level: beginner
3119 
3120 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled()
3121 @*/
3122 int MatAssemblyEnd(Mat mat,MatAssemblyType type)
3123 {
3124   int        ierr;
3125   static int inassm = 0;
3126 
3127   PetscFunctionBegin;
3128   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3129   PetscValidType(mat);
3130   MatPreallocated(mat);
3131 
3132   inassm++;
3133   MatAssemblyEnd_InUse++;
3134   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
3135     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
3136     if (mat->ops->assemblyend) {
3137       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
3138     }
3139     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
3140   } else {
3141     if (mat->ops->assemblyend) {
3142       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
3143     }
3144   }
3145 
3146   /* Flush assembly is not a true assembly */
3147   if (type != MAT_FLUSH_ASSEMBLY) {
3148     mat->assembled  = PETSC_TRUE; mat->num_ass++;
3149   }
3150   mat->insertmode = NOT_SET_VALUES;
3151   MatAssemblyEnd_InUse--;
3152 
3153   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
3154     ierr = MatView_Private(mat);CHKERRQ(ierr);
3155   }
3156   inassm--;
3157   PetscFunctionReturn(0);
3158 }
3159 
3160 
3161 #undef __FUNCT__
3162 #define __FUNCT__ "MatCompress"
3163 /*@
3164    MatCompress - Tries to store the matrix in as little space as
3165    possible.  May fail if memory is already fully used, since it
3166    tries to allocate new space.
3167 
3168    Collective on Mat
3169 
3170    Input Parameters:
3171 .  mat - the matrix
3172 
3173    Level: advanced
3174 
3175 @*/
3176 int MatCompress(Mat mat)
3177 {
3178   int ierr;
3179 
3180   PetscFunctionBegin;
3181   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3182   PetscValidType(mat);
3183   MatPreallocated(mat);
3184   if (mat->ops->compress) {ierr = (*mat->ops->compress)(mat);CHKERRQ(ierr);}
3185   PetscFunctionReturn(0);
3186 }
3187 
3188 #undef __FUNCT__
3189 #define __FUNCT__ "MatSetOption"
3190 /*@
3191    MatSetOption - Sets a parameter option for a matrix. Some options
3192    may be specific to certain storage formats.  Some options
3193    determine how values will be inserted (or added). Sorted,
3194    row-oriented input will generally assemble the fastest. The default
3195    is row-oriented, nonsorted input.
3196 
3197    Collective on Mat
3198 
3199    Input Parameters:
3200 +  mat - the matrix
3201 -  option - the option, one of those listed below (and possibly others),
3202              e.g., MAT_ROWS_SORTED, MAT_NEW_NONZERO_LOCATION_ERR
3203 
3204    Options Describing Matrix Structure:
3205 +    MAT_SYMMETRIC - symmetric in terms of both structure and value
3206 -    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
3207 
3208    Options For Use with MatSetValues():
3209    Insert a logically dense subblock, which can be
3210 +    MAT_ROW_ORIENTED - row-oriented
3211 .    MAT_COLUMN_ORIENTED - column-oriented
3212 .    MAT_ROWS_SORTED - sorted by row
3213 .    MAT_ROWS_UNSORTED - not sorted by row
3214 .    MAT_COLUMNS_SORTED - sorted by column
3215 -    MAT_COLUMNS_UNSORTED - not sorted by column
3216 
3217    Not these options reflect the data you pass in with MatSetValues(); it has
3218    nothing to do with how the data is stored internally in the matrix
3219    data structure.
3220 
3221    When (re)assembling a matrix, we can restrict the input for
3222    efficiency/debugging purposes.  These options include
3223 +    MAT_NO_NEW_NONZERO_LOCATIONS - additional insertions will not be
3224         allowed if they generate a new nonzero
3225 .    MAT_YES_NEW_NONZERO_LOCATIONS - additional insertions will be allowed
3226 .    MAT_NO_NEW_DIAGONALS - additional insertions will not be allowed if
3227          they generate a nonzero in a new diagonal (for block diagonal format only)
3228 .    MAT_YES_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
3229 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
3230 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
3231 -    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
3232 
3233    Notes:
3234    Some options are relevant only for particular matrix types and
3235    are thus ignored by others.  Other options are not supported by
3236    certain matrix types and will generate an error message if set.
3237 
3238    If using a Fortran 77 module to compute a matrix, one may need to
3239    use the column-oriented option (or convert to the row-oriented
3240    format).
3241 
3242    MAT_NO_NEW_NONZERO_LOCATIONS indicates that any add or insertion
3243    that would generate a new entry in the nonzero structure is instead
3244    ignored.  Thus, if memory has not alredy been allocated for this particular
3245    data, then the insertion is ignored. For dense matrices, in which
3246    the entire array is allocated, no entries are ever ignored.
3247 
3248    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
3249    that would generate a new entry in the nonzero structure instead produces
3250    an error. (Currently supported for AIJ and BAIJ formats only.)
3251    This is a useful flag when using SAME_NONZERO_PATTERN in calling
3252    SLESSetOperators() to ensure that the nonzero pattern truely does
3253    remain unchanged.
3254 
3255    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
3256    that would generate a new entry that has not been preallocated will
3257    instead produce an error. (Currently supported for AIJ and BAIJ formats
3258    only.) This is a useful flag when debugging matrix memory preallocation.
3259 
3260    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
3261    other processors should be dropped, rather than stashed.
3262    This is useful if you know that the "owning" processor is also
3263    always generating the correct matrix entries, so that PETSc need
3264    not transfer duplicate entries generated on another processor.
3265 
3266    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
3267    searches during matrix assembly. When this flag is set, the hash table
3268    is created during the first Matrix Assembly. This hash table is
3269    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
3270    to improve the searching of indices. MAT_NO_NEW_NONZERO_LOCATIONS flag
3271    should be used with MAT_USE_HASH_TABLE flag. This option is currently
3272    supported by MATMPIBAIJ format only.
3273 
3274    MAT_KEEP_ZEROED_ROWS indicates when MatZeroRows() is called the zeroed entries
3275    are kept in the nonzero structure
3276 
3277    MAT_IGNORE_ZERO_ENTRIES - when using ADD_VALUES for AIJ matrices this will stop
3278    zero values from creating a zero location in the matrix
3279 
3280    MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
3281    ROWBS matrix types
3282 
3283    MAT_DO_NOT_USE_INODES - indicates not using inode version of the code - works
3284    with AIJ and ROWBS matrix types
3285 
3286    Level: intermediate
3287 
3288    Concepts: matrices^setting options
3289 
3290 @*/
3291 int MatSetOption(Mat mat,MatOption op)
3292 {
3293   int ierr;
3294 
3295   PetscFunctionBegin;
3296   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3297   PetscValidType(mat);
3298   MatPreallocated(mat);
3299   switch (op) {
3300   case MAT_SYMMETRIC:
3301     mat->symmetric              = PETSC_TRUE;
3302     mat->structurally_symmetric = PETSC_TRUE;
3303     break;
3304   case MAT_STRUCTURALLY_SYMMETRIC:
3305     mat->structurally_symmetric = PETSC_TRUE;
3306     break;
3307   default:
3308     if (mat->ops->setoption) {ierr = (*mat->ops->setoption)(mat,op);CHKERRQ(ierr);}
3309     break;
3310   }
3311   PetscFunctionReturn(0);
3312 }
3313 
3314 #undef __FUNCT__
3315 #define __FUNCT__ "MatZeroEntries"
3316 /*@
3317    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
3318    this routine retains the old nonzero structure.
3319 
3320    Collective on Mat
3321 
3322    Input Parameters:
3323 .  mat - the matrix
3324 
3325    Level: intermediate
3326 
3327    Concepts: matrices^zeroing
3328 
3329 .seealso: MatZeroRows()
3330 @*/
3331 int MatZeroEntries(Mat mat)
3332 {
3333   int ierr;
3334 
3335   PetscFunctionBegin;
3336   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3337   PetscValidType(mat);
3338   MatPreallocated(mat);
3339   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3340   if (!mat->ops->zeroentries) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3341 
3342   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
3343   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
3344   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
3345   PetscFunctionReturn(0);
3346 }
3347 
3348 #undef __FUNCT__
3349 #define __FUNCT__ "MatZeroRows"
3350 /*@C
3351    MatZeroRows - Zeros all entries (except possibly the main diagonal)
3352    of a set of rows of a matrix.
3353 
3354    Collective on Mat
3355 
3356    Input Parameters:
3357 +  mat - the matrix
3358 .  is - index set of rows to remove
3359 -  diag - pointer to value put in all diagonals of eliminated rows.
3360           Note that diag is not a pointer to an array, but merely a
3361           pointer to a single value.
3362 
3363    Notes:
3364    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
3365    but does not release memory.  For the dense and block diagonal
3366    formats this does not alter the nonzero structure.
3367 
3368    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
3369    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
3370    merely zeroed.
3371 
3372    The user can set a value in the diagonal entry (or for the AIJ and
3373    row formats can optionally remove the main diagonal entry from the
3374    nonzero structure as well, by passing a null pointer (PETSC_NULL
3375    in C or PETSC_NULL_SCALAR in Fortran) as the final argument).
3376 
3377    For the parallel case, all processes that share the matrix (i.e.,
3378    those in the communicator used for matrix creation) MUST call this
3379    routine, regardless of whether any rows being zeroed are owned by
3380    them.
3381 
3382 
3383    Level: intermediate
3384 
3385    Concepts: matrices^zeroing rows
3386 
3387 .seealso: MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
3388 @*/
3389 int MatZeroRows(Mat mat,IS is,PetscScalar *diag)
3390 {
3391   int ierr;
3392 
3393   PetscFunctionBegin;
3394   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3395   PetscValidType(mat);
3396   MatPreallocated(mat);
3397   PetscValidHeaderSpecific(is,IS_COOKIE);
3398   if (diag) PetscValidScalarPointer(diag);
3399   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3400   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3401   if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3402 
3403   ierr = (*mat->ops->zerorows)(mat,is,diag);CHKERRQ(ierr);
3404   ierr = MatView_Private(mat);CHKERRQ(ierr);
3405   PetscFunctionReturn(0);
3406 }
3407 
3408 #undef __FUNCT__
3409 #define __FUNCT__ "MatZeroRowsLocal"
3410 /*@C
3411    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
3412    of a set of rows of a matrix; using local numbering of rows.
3413 
3414    Collective on Mat
3415 
3416    Input Parameters:
3417 +  mat - the matrix
3418 .  is - index set of rows to remove
3419 -  diag - pointer to value put in all diagonals of eliminated rows.
3420           Note that diag is not a pointer to an array, but merely a
3421           pointer to a single value.
3422 
3423    Notes:
3424    Before calling MatZeroRowsLocal(), the user must first set the
3425    local-to-global mapping by calling MatSetLocalToGlobalMapping().
3426 
3427    For the AIJ matrix formats this removes the old nonzero structure,
3428    but does not release memory.  For the dense and block diagonal
3429    formats this does not alter the nonzero structure.
3430 
3431    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
3432    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
3433    merely zeroed.
3434 
3435    The user can set a value in the diagonal entry (or for the AIJ and
3436    row formats can optionally remove the main diagonal entry from the
3437    nonzero structure as well, by passing a null pointer (PETSC_NULL
3438    in C or PETSC_NULL_SCALAR in Fortran) as the final argument).
3439 
3440    Level: intermediate
3441 
3442    Concepts: matrices^zeroing
3443 
3444 .seealso: MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
3445 @*/
3446 int MatZeroRowsLocal(Mat mat,IS is,PetscScalar *diag)
3447 {
3448   int ierr;
3449   IS  newis;
3450 
3451   PetscFunctionBegin;
3452   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3453   PetscValidType(mat);
3454   MatPreallocated(mat);
3455   PetscValidHeaderSpecific(is,IS_COOKIE);
3456   if (diag) PetscValidScalarPointer(diag);
3457   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3458   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3459 
3460   if (mat->ops->zerorowslocal) {
3461     ierr = (*mat->ops->zerorowslocal)(mat,is,diag);CHKERRQ(ierr);
3462   } else {
3463     if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
3464     ierr = ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);CHKERRQ(ierr);
3465     ierr = (*mat->ops->zerorows)(mat,newis,diag);CHKERRQ(ierr);
3466     ierr = ISDestroy(newis);CHKERRQ(ierr);
3467   }
3468   PetscFunctionReturn(0);
3469 }
3470 
3471 #undef __FUNCT__
3472 #define __FUNCT__ "MatGetSize"
3473 /*@
3474    MatGetSize - Returns the numbers of rows and columns in a matrix.
3475 
3476    Not Collective
3477 
3478    Input Parameter:
3479 .  mat - the matrix
3480 
3481    Output Parameters:
3482 +  m - the number of global rows
3483 -  n - the number of global columns
3484 
3485    Level: beginner
3486 
3487    Concepts: matrices^size
3488 
3489 .seealso: MatGetLocalSize()
3490 @*/
3491 int MatGetSize(Mat mat,int *m,int* n)
3492 {
3493   PetscFunctionBegin;
3494   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3495   if (m) *m = mat->M;
3496   if (n) *n = mat->N;
3497   PetscFunctionReturn(0);
3498 }
3499 
3500 #undef __FUNCT__
3501 #define __FUNCT__ "MatGetLocalSize"
3502 /*@
3503    MatGetLocalSize - Returns the number of rows and columns in a matrix
3504    stored locally.  This information may be implementation dependent, so
3505    use with care.
3506 
3507    Not Collective
3508 
3509    Input Parameters:
3510 .  mat - the matrix
3511 
3512    Output Parameters:
3513 +  m - the number of local rows
3514 -  n - the number of local columns
3515 
3516    Level: beginner
3517 
3518    Concepts: matrices^local size
3519 
3520 .seealso: MatGetSize()
3521 @*/
3522 int MatGetLocalSize(Mat mat,int *m,int* n)
3523 {
3524   PetscFunctionBegin;
3525   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3526   if (m) *m = mat->m;
3527   if (n) *n = mat->n;
3528   PetscFunctionReturn(0);
3529 }
3530 
3531 #undef __FUNCT__
3532 #define __FUNCT__ "MatGetOwnershipRange"
3533 /*@
3534    MatGetOwnershipRange - Returns the range of matrix rows owned by
3535    this processor, assuming that the matrix is laid out with the first
3536    n1 rows on the first processor, the next n2 rows on the second, etc.
3537    For certain parallel layouts this range may not be well defined.
3538 
3539    Not Collective
3540 
3541    Input Parameters:
3542 .  mat - the matrix
3543 
3544    Output Parameters:
3545 +  m - the global index of the first local row
3546 -  n - one more than the global index of the last local row
3547 
3548    Level: beginner
3549 
3550    Concepts: matrices^row ownership
3551 @*/
3552 int MatGetOwnershipRange(Mat mat,int *m,int* n)
3553 {
3554   int ierr;
3555 
3556   PetscFunctionBegin;
3557   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3558   PetscValidType(mat);
3559   MatPreallocated(mat);
3560   if (m) PetscValidIntPointer(m);
3561   if (n) PetscValidIntPointer(n);
3562   ierr = PetscMapGetLocalRange(mat->rmap,m,n);CHKERRQ(ierr);
3563   PetscFunctionReturn(0);
3564 }
3565 
3566 #undef __FUNCT__
3567 #define __FUNCT__ "MatILUFactorSymbolic"
3568 /*@
3569    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
3570    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
3571    to complete the factorization.
3572 
3573    Collective on Mat
3574 
3575    Input Parameters:
3576 +  mat - the matrix
3577 .  row - row permutation
3578 .  column - column permutation
3579 -  info - structure containing
3580 $      levels - number of levels of fill.
3581 $      expected fill - as ratio of original fill.
3582 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
3583                 missing diagonal entries)
3584 
3585    Output Parameters:
3586 .  fact - new matrix that has been symbolically factored
3587 
3588    Notes:
3589    See the users manual for additional information about
3590    choosing the fill factor for better efficiency.
3591 
3592    Most users should employ the simplified SLES interface for linear solvers
3593    instead of working directly with matrix algebra routines such as this.
3594    See, e.g., SLESCreate().
3595 
3596    Level: developer
3597 
3598   Concepts: matrices^symbolic LU factorization
3599   Concepts: matrices^factorization
3600   Concepts: LU^symbolic factorization
3601 
3602 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
3603           MatGetOrdering(), MatILUInfo
3604 
3605 @*/
3606 int MatILUFactorSymbolic(Mat mat,IS row,IS col,MatILUInfo *info,Mat *fact)
3607 {
3608   int ierr;
3609 
3610   PetscFunctionBegin;
3611   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3612   PetscValidType(mat);
3613   MatPreallocated(mat);
3614   PetscValidPointer(fact);
3615   PetscValidHeaderSpecific(row,IS_COOKIE);
3616   PetscValidHeaderSpecific(col,IS_COOKIE);
3617   if (info && info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %d",info->levels);
3618   if (info && info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",info->fill);
3619   if (!mat->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",mat->type_name);
3620   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3621   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3622 
3623   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3624   ierr = (*mat->ops->ilufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
3625   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3626   PetscFunctionReturn(0);
3627 }
3628 
3629 #undef __FUNCT__
3630 #define __FUNCT__ "MatICCFactorSymbolic"
3631 /*@
3632    MatICCFactorSymbolic - Performs symbolic incomplete
3633    Cholesky factorization for a symmetric matrix.  Use
3634    MatCholeskyFactorNumeric() to complete the factorization.
3635 
3636    Collective on Mat
3637 
3638    Input Parameters:
3639 +  mat - the matrix
3640 .  perm - row and column permutation
3641 .  fill - levels of fill
3642 -  f - expected fill as ratio of original fill
3643 
3644    Output Parameter:
3645 .  fact - the factored matrix
3646 
3647    Notes:
3648    Currently only no-fill factorization is supported.
3649 
3650    Most users should employ the simplified SLES interface for linear solvers
3651    instead of working directly with matrix algebra routines such as this.
3652    See, e.g., SLESCreate().
3653 
3654    Level: developer
3655 
3656   Concepts: matrices^symbolic incomplete Cholesky factorization
3657   Concepts: matrices^factorization
3658   Concepts: Cholsky^symbolic factorization
3659 
3660 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor()
3661 @*/
3662 int MatICCFactorSymbolic(Mat mat,IS perm,PetscReal f,int fill,Mat *fact)
3663 {
3664   int ierr;
3665 
3666   PetscFunctionBegin;
3667   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3668   PetscValidType(mat);
3669   MatPreallocated(mat);
3670   PetscValidPointer(fact);
3671   PetscValidHeaderSpecific(perm,IS_COOKIE);
3672   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3673   if (fill < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Fill negative %d",fill);
3674   if (f < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",f);
3675   if (!mat->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",mat->type_name);
3676   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3677 
3678   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3679   ierr = (*mat->ops->iccfactorsymbolic)(mat,perm,f,fill,fact);CHKERRQ(ierr);
3680   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3681   PetscFunctionReturn(0);
3682 }
3683 
3684 #undef __FUNCT__
3685 #define __FUNCT__ "MatGetArray"
3686 /*@C
3687    MatGetArray - Returns a pointer to the element values in the matrix.
3688    The result of this routine is dependent on the underlying matrix data
3689    structure, and may not even work for certain matrix types.  You MUST
3690    call MatRestoreArray() when you no longer need to access the array.
3691 
3692    Not Collective
3693 
3694    Input Parameter:
3695 .  mat - the matrix
3696 
3697    Output Parameter:
3698 .  v - the location of the values
3699 
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    Concepts: matrices^access array
3724 
3725 .seealso: MatRestoreArray(), MatGetArrayF90()
3726 @*/
3727 int MatGetArray(Mat mat,PetscScalar **v)
3728 {
3729   int ierr;
3730 
3731   PetscFunctionBegin;
3732   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3733   PetscValidType(mat);
3734   MatPreallocated(mat);
3735   PetscValidPointer(v);
3736   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3737   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
3738   PetscFunctionReturn(0);
3739 }
3740 
3741 #undef __FUNCT__
3742 #define __FUNCT__ "MatRestoreArray"
3743 /*@C
3744    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
3745 
3746    Not Collective
3747 
3748    Input Parameter:
3749 +  mat - the matrix
3750 -  v - the location of the values
3751 
3752    Fortran Note:
3753    This routine is used differently from Fortran, e.g.,
3754 .vb
3755         Mat         mat
3756         PetscScalar mat_array(1)
3757         PetscOffset i_mat
3758         int         ierr
3759         call MatGetArray(mat,mat_array,i_mat,ierr)
3760 
3761   C  Access first local entry in matrix; note that array is
3762   C  treated as one dimensional
3763         value = mat_array(i_mat + 1)
3764 
3765         [... other code ...]
3766         call MatRestoreArray(mat,mat_array,i_mat,ierr)
3767 .ve
3768 
3769    See the Fortran chapter of the users manual and
3770    petsc/src/mat/examples/tests for details
3771 
3772    Level: advanced
3773 
3774 .seealso: MatGetArray(), MatRestoreArrayF90()
3775 @*/
3776 int MatRestoreArray(Mat mat,PetscScalar **v)
3777 {
3778   int ierr;
3779 
3780   PetscFunctionBegin;
3781   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3782   PetscValidType(mat);
3783   MatPreallocated(mat);
3784   PetscValidPointer(v);
3785   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3786   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
3787   PetscFunctionReturn(0);
3788 }
3789 
3790 #undef __FUNCT__
3791 #define __FUNCT__ "MatGetSubMatrices"
3792 /*@C
3793    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
3794    points to an array of valid matrices, they may be reused to store the new
3795    submatrices.
3796 
3797    Collective on Mat
3798 
3799    Input Parameters:
3800 +  mat - the matrix
3801 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
3802 .  irow, icol - index sets of rows and columns to extract
3803 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
3804 
3805    Output Parameter:
3806 .  submat - the array of submatrices
3807 
3808    Notes:
3809    MatGetSubMatrices() can extract only sequential submatrices
3810    (from both sequential and parallel matrices). Use MatGetSubMatrix()
3811    to extract a parallel submatrix.
3812 
3813    When extracting submatrices from a parallel matrix, each processor can
3814    form a different submatrix by setting the rows and columns of its
3815    individual index sets according to the local submatrix desired.
3816 
3817    When finished using the submatrices, the user should destroy
3818    them with MatDestroyMatrices().
3819 
3820    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
3821    original matrix has not changed from that last call to MatGetSubMatrices().
3822 
3823    This routine creates the matrices submat; you should NOT create them before
3824    calling it.
3825 
3826    Fortran Note:
3827    The Fortran interface is slightly different from that given below; it
3828    requires one to pass in  as submat a Mat (integer) array of size at least m.
3829 
3830    Level: advanced
3831 
3832    Concepts: matrices^accessing submatrices
3833    Concepts: submatrices
3834 
3835 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal()
3836 @*/
3837 int MatGetSubMatrices(Mat mat,int n,IS *irow,IS *icol,MatReuse scall,Mat **submat)
3838 {
3839   int        ierr;
3840 
3841   PetscFunctionBegin;
3842   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3843   PetscValidType(mat);
3844   MatPreallocated(mat);
3845   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3846   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3847 
3848   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
3849   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
3850   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
3851   PetscFunctionReturn(0);
3852 }
3853 
3854 #undef __FUNCT__
3855 #define __FUNCT__ "MatDestroyMatrices"
3856 /*@C
3857    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
3858 
3859    Collective on Mat
3860 
3861    Input Parameters:
3862 +  n - the number of local matrices
3863 -  mat - the matrices
3864 
3865    Level: advanced
3866 
3867     Notes: Frees not only the matrices, but also the array that contains the matrices
3868 
3869 .seealso: MatGetSubMatrices()
3870 @*/
3871 int MatDestroyMatrices(int n,Mat **mat)
3872 {
3873   int ierr,i;
3874 
3875   PetscFunctionBegin;
3876   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %d",n);
3877   PetscValidPointer(mat);
3878   for (i=0; i<n; i++) {
3879     ierr = MatDestroy((*mat)[i]);CHKERRQ(ierr);
3880   }
3881   /* memory is allocated even if n = 0 */
3882   ierr = PetscFree(*mat);CHKERRQ(ierr);
3883   PetscFunctionReturn(0);
3884 }
3885 
3886 #undef __FUNCT__
3887 #define __FUNCT__ "MatIncreaseOverlap"
3888 /*@
3889    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
3890    replaces the index sets by larger ones that represent submatrices with
3891    additional overlap.
3892 
3893    Collective on Mat
3894 
3895    Input Parameters:
3896 +  mat - the matrix
3897 .  n   - the number of index sets
3898 .  is  - the array of pointers to index sets
3899 -  ov  - the additional overlap requested
3900 
3901    Level: developer
3902 
3903    Concepts: overlap
3904    Concepts: ASM^computing overlap
3905 
3906 .seealso: MatGetSubMatrices()
3907 @*/
3908 int MatIncreaseOverlap(Mat mat,int n,IS *is,int ov)
3909 {
3910   int ierr;
3911 
3912   PetscFunctionBegin;
3913   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3914   PetscValidType(mat);
3915   MatPreallocated(mat);
3916   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3917   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3918 
3919   if (!ov) PetscFunctionReturn(0);
3920   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3921   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
3922   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
3923   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
3924   PetscFunctionReturn(0);
3925 }
3926 
3927 #undef __FUNCT__
3928 #define __FUNCT__ "MatPrintHelp"
3929 /*@
3930    MatPrintHelp - Prints all the options for the matrix.
3931 
3932    Collective on Mat
3933 
3934    Input Parameter:
3935 .  mat - the matrix
3936 
3937    Options Database Keys:
3938 +  -help - Prints matrix options
3939 -  -h - Prints matrix options
3940 
3941    Level: developer
3942 
3943 .seealso: MatCreate(), MatCreateXXX()
3944 @*/
3945 int MatPrintHelp(Mat mat)
3946 {
3947   static PetscTruth called = PETSC_FALSE;
3948   int               ierr;
3949   MPI_Comm          comm;
3950 
3951   PetscFunctionBegin;
3952   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3953   PetscValidType(mat);
3954   MatPreallocated(mat);
3955 
3956   comm = mat->comm;
3957   if (!called) {
3958     ierr = (*PetscHelpPrintf)(comm,"General matrix options:\n");CHKERRQ(ierr);
3959     ierr = (*PetscHelpPrintf)(comm,"  -mat_view_info: view basic matrix info during MatAssemblyEnd()\n");CHKERRQ(ierr);
3960     ierr = (*PetscHelpPrintf)(comm,"  -mat_view_info_detailed: view detailed matrix info during MatAssemblyEnd()\n");CHKERRQ(ierr);
3961     ierr = (*PetscHelpPrintf)(comm,"  -mat_view_draw: draw nonzero matrix structure during MatAssemblyEnd()\n");CHKERRQ(ierr);
3962     ierr = (*PetscHelpPrintf)(comm,"      -draw_pause <sec>: set seconds of display pause\n");CHKERRQ(ierr);
3963     ierr = (*PetscHelpPrintf)(comm,"      -display <name>: set alternate display\n");CHKERRQ(ierr);
3964     called = PETSC_TRUE;
3965   }
3966   if (mat->ops->printhelp) {
3967     ierr = (*mat->ops->printhelp)(mat);CHKERRQ(ierr);
3968   }
3969   PetscFunctionReturn(0);
3970 }
3971 
3972 #undef __FUNCT__
3973 #define __FUNCT__ "MatGetBlockSize"
3974 /*@
3975    MatGetBlockSize - Returns the matrix block size; useful especially for the
3976    block row and block diagonal formats.
3977 
3978    Not Collective
3979 
3980    Input Parameter:
3981 .  mat - the matrix
3982 
3983    Output Parameter:
3984 .  bs - block size
3985 
3986    Notes:
3987    Block diagonal formats are MATSEQBDIAG, MATMPIBDIAG.
3988    Block row formats are MATSEQBAIJ, MATMPIBAIJ
3989 
3990    Level: intermediate
3991 
3992    Concepts: matrices^block size
3993 
3994 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatCreateSeqBDiag(), MatCreateMPIBDiag()
3995 @*/
3996 int MatGetBlockSize(Mat mat,int *bs)
3997 {
3998   int ierr;
3999 
4000   PetscFunctionBegin;
4001   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4002   PetscValidType(mat);
4003   MatPreallocated(mat);
4004   PetscValidIntPointer(bs);
4005   if (!mat->ops->getblocksize) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4006   ierr = (*mat->ops->getblocksize)(mat,bs);CHKERRQ(ierr);
4007   PetscFunctionReturn(0);
4008 }
4009 
4010 #undef __FUNCT__
4011 #define __FUNCT__ "MatGetRowIJ"
4012 /*@C
4013     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
4014 
4015    Collective on Mat
4016 
4017     Input Parameters:
4018 +   mat - the matrix
4019 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
4020 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4021                 symmetrized
4022 
4023     Output Parameters:
4024 +   n - number of rows in the (possibly compressed) matrix
4025 .   ia - the row pointers
4026 .   ja - the column indices
4027 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
4028 
4029     Level: developer
4030 
4031 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
4032 @*/
4033 int MatGetRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
4034 {
4035   int ierr;
4036 
4037   PetscFunctionBegin;
4038   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4039   PetscValidType(mat);
4040   MatPreallocated(mat);
4041   if (ia) PetscValidIntPointer(ia);
4042   if (ja) PetscValidIntPointer(ja);
4043   PetscValidIntPointer(done);
4044   if (!mat->ops->getrowij) *done = PETSC_FALSE;
4045   else {
4046     *done = PETSC_TRUE;
4047     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4048   }
4049   PetscFunctionReturn(0);
4050 }
4051 
4052 #undef __FUNCT__
4053 #define __FUNCT__ "MatGetColumnIJ"
4054 /*@C
4055     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
4056 
4057     Collective on Mat
4058 
4059     Input Parameters:
4060 +   mat - the matrix
4061 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4062 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4063                 symmetrized
4064 
4065     Output Parameters:
4066 +   n - number of columns in the (possibly compressed) matrix
4067 .   ia - the column pointers
4068 .   ja - the row indices
4069 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
4070 
4071     Level: developer
4072 
4073 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
4074 @*/
4075 int MatGetColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
4076 {
4077   int ierr;
4078 
4079   PetscFunctionBegin;
4080   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4081   PetscValidType(mat);
4082   MatPreallocated(mat);
4083   if (ia) PetscValidIntPointer(ia);
4084   if (ja) PetscValidIntPointer(ja);
4085   PetscValidIntPointer(done);
4086 
4087   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
4088   else {
4089     *done = PETSC_TRUE;
4090     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4091   }
4092   PetscFunctionReturn(0);
4093 }
4094 
4095 #undef __FUNCT__
4096 #define __FUNCT__ "MatRestoreRowIJ"
4097 /*@C
4098     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
4099     MatGetRowIJ().
4100 
4101     Collective on Mat
4102 
4103     Input Parameters:
4104 +   mat - the matrix
4105 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4106 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4107                 symmetrized
4108 
4109     Output Parameters:
4110 +   n - size of (possibly compressed) matrix
4111 .   ia - the row pointers
4112 .   ja - the column indices
4113 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
4114 
4115     Level: developer
4116 
4117 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
4118 @*/
4119 int MatRestoreRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
4120 {
4121   int ierr;
4122 
4123   PetscFunctionBegin;
4124   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4125   PetscValidType(mat);
4126   MatPreallocated(mat);
4127   if (ia) PetscValidIntPointer(ia);
4128   if (ja) PetscValidIntPointer(ja);
4129   PetscValidIntPointer(done);
4130 
4131   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
4132   else {
4133     *done = PETSC_TRUE;
4134     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4135   }
4136   PetscFunctionReturn(0);
4137 }
4138 
4139 #undef __FUNCT__
4140 #define __FUNCT__ "MatRestoreColumnIJ"
4141 /*@C
4142     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
4143     MatGetColumnIJ().
4144 
4145     Collective on Mat
4146 
4147     Input Parameters:
4148 +   mat - the matrix
4149 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4150 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4151                 symmetrized
4152 
4153     Output Parameters:
4154 +   n - size of (possibly compressed) matrix
4155 .   ia - the column pointers
4156 .   ja - the row indices
4157 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
4158 
4159     Level: developer
4160 
4161 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
4162 @*/
4163 int MatRestoreColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
4164 {
4165   int ierr;
4166 
4167   PetscFunctionBegin;
4168   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4169   PetscValidType(mat);
4170   MatPreallocated(mat);
4171   if (ia) PetscValidIntPointer(ia);
4172   if (ja) PetscValidIntPointer(ja);
4173   PetscValidIntPointer(done);
4174 
4175   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
4176   else {
4177     *done = PETSC_TRUE;
4178     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4179   }
4180   PetscFunctionReturn(0);
4181 }
4182 
4183 #undef __FUNCT__
4184 #define __FUNCT__ "MatColoringPatch"
4185 /*@C
4186     MatColoringPatch -Used inside matrix coloring routines that
4187     use MatGetRowIJ() and/or MatGetColumnIJ().
4188 
4189     Collective on Mat
4190 
4191     Input Parameters:
4192 +   mat - the matrix
4193 .   n   - number of colors
4194 -   colorarray - array indicating color for each column
4195 
4196     Output Parameters:
4197 .   iscoloring - coloring generated using colorarray information
4198 
4199     Level: developer
4200 
4201 .seealso: MatGetRowIJ(), MatGetColumnIJ()
4202 
4203 @*/
4204 int MatColoringPatch(Mat mat,int n,int ncolors,int *colorarray,ISColoring *iscoloring)
4205 {
4206   int ierr;
4207 
4208   PetscFunctionBegin;
4209   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4210   PetscValidType(mat);
4211   MatPreallocated(mat);
4212   PetscValidIntPointer(colorarray);
4213 
4214   if (!mat->ops->coloringpatch){
4215     ierr = ISColoringCreate(mat->comm,n,colorarray,iscoloring);CHKERRQ(ierr);
4216   } else {
4217     ierr = (*mat->ops->coloringpatch)(mat,n,ncolors,colorarray,iscoloring);CHKERRQ(ierr);
4218   }
4219   PetscFunctionReturn(0);
4220 }
4221 
4222 
4223 #undef __FUNCT__
4224 #define __FUNCT__ "MatSetUnfactored"
4225 /*@
4226    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
4227 
4228    Collective on Mat
4229 
4230    Input Parameter:
4231 .  mat - the factored matrix to be reset
4232 
4233    Notes:
4234    This routine should be used only with factored matrices formed by in-place
4235    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
4236    format).  This option can save memory, for example, when solving nonlinear
4237    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
4238    ILU(0) preconditioner.
4239 
4240    Note that one can specify in-place ILU(0) factorization by calling
4241 .vb
4242      PCType(pc,PCILU);
4243      PCILUSeUseInPlace(pc);
4244 .ve
4245    or by using the options -pc_type ilu -pc_ilu_in_place
4246 
4247    In-place factorization ILU(0) can also be used as a local
4248    solver for the blocks within the block Jacobi or additive Schwarz
4249    methods (runtime option: -sub_pc_ilu_in_place).  See the discussion
4250    of these preconditioners in the users manual for details on setting
4251    local solver options.
4252 
4253    Most users should employ the simplified SLES interface for linear solvers
4254    instead of working directly with matrix algebra routines such as this.
4255    See, e.g., SLESCreate().
4256 
4257    Level: developer
4258 
4259 .seealso: PCILUSetUseInPlace(), PCLUSetUseInPlace()
4260 
4261    Concepts: matrices^unfactored
4262 
4263 @*/
4264 int MatSetUnfactored(Mat mat)
4265 {
4266   int ierr;
4267 
4268   PetscFunctionBegin;
4269   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4270   PetscValidType(mat);
4271   MatPreallocated(mat);
4272   mat->factor = 0;
4273   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
4274   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
4275   PetscFunctionReturn(0);
4276 }
4277 
4278 /*MC
4279     MatGetArrayF90 - Accesses a matrix array from Fortran90.
4280 
4281     Synopsis:
4282     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
4283 
4284     Not collective
4285 
4286     Input Parameter:
4287 .   x - matrix
4288 
4289     Output Parameters:
4290 +   xx_v - the Fortran90 pointer to the array
4291 -   ierr - error code
4292 
4293     Example of Usage:
4294 .vb
4295       PetscScalar, pointer xx_v(:)
4296       ....
4297       call MatGetArrayF90(x,xx_v,ierr)
4298       a = xx_v(3)
4299       call MatRestoreArrayF90(x,xx_v,ierr)
4300 .ve
4301 
4302     Notes:
4303     Not yet supported for all F90 compilers
4304 
4305     Level: advanced
4306 
4307 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
4308 
4309     Concepts: matrices^accessing array
4310 
4311 M*/
4312 
4313 /*MC
4314     MatRestoreArrayF90 - Restores a matrix array that has been
4315     accessed with MatGetArrayF90().
4316 
4317     Synopsis:
4318     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
4319 
4320     Not collective
4321 
4322     Input Parameters:
4323 +   x - matrix
4324 -   xx_v - the Fortran90 pointer to the array
4325 
4326     Output Parameter:
4327 .   ierr - error code
4328 
4329     Example of Usage:
4330 .vb
4331        PetscScalar, pointer xx_v(:)
4332        ....
4333        call MatGetArrayF90(x,xx_v,ierr)
4334        a = xx_v(3)
4335        call MatRestoreArrayF90(x,xx_v,ierr)
4336 .ve
4337 
4338     Notes:
4339     Not yet supported for all F90 compilers
4340 
4341     Level: advanced
4342 
4343 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
4344 
4345 M*/
4346 
4347 
4348 #undef __FUNCT__
4349 #define __FUNCT__ "MatGetSubMatrix"
4350 /*@
4351     MatGetSubMatrix - Gets a single submatrix on the same number of processors
4352                       as the original matrix.
4353 
4354     Collective on Mat
4355 
4356     Input Parameters:
4357 +   mat - the original matrix
4358 .   isrow - rows this processor should obtain
4359 .   iscol - columns for all processors you wish to keep
4360 .   csize - number of columns "local" to this processor (does nothing for sequential
4361             matrices). This should match the result from VecGetLocalSize(x,...) if you
4362             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
4363 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4364 
4365     Output Parameter:
4366 .   newmat - the new submatrix, of the same type as the old
4367 
4368     Level: advanced
4369 
4370     Notes: the iscol argument MUST be the same on each processor.
4371 
4372       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
4373    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
4374    to this routine with a mat of the same nonzero structure will reuse the matrix
4375    generated the first time.
4376 
4377     Concepts: matrices^submatrices
4378 
4379 .seealso: MatGetSubMatrices()
4380 @*/
4381 int MatGetSubMatrix(Mat mat,IS isrow,IS iscol,int csize,MatReuse cll,Mat *newmat)
4382 {
4383   int     ierr, size;
4384   Mat     *local;
4385 
4386   PetscFunctionBegin;
4387   PetscValidType(mat);
4388   MatPreallocated(mat);
4389   ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr);
4390 
4391   /* if original matrix is on just one processor then use submatrix generated */
4392   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
4393     ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
4394     PetscFunctionReturn(0);
4395   } else if (!mat->ops->getsubmatrix && size == 1) {
4396     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
4397     *newmat = *local;
4398     ierr    = PetscFree(local);CHKERRQ(ierr);
4399     PetscFunctionReturn(0);
4400   }
4401 
4402   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4403   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscol,csize,cll,newmat);CHKERRQ(ierr);
4404   PetscFunctionReturn(0);
4405 }
4406 
4407 #undef __FUNCT__
4408 #define __FUNCT__ "MatGetPetscMaps"
4409 /*@C
4410    MatGetPetscMaps - Returns the maps associated with the matrix.
4411 
4412    Not Collective
4413 
4414    Input Parameter:
4415 .  mat - the matrix
4416 
4417    Output Parameters:
4418 +  rmap - the row (right) map
4419 -  cmap - the column (left) map
4420 
4421    Level: developer
4422 
4423    Concepts: maps^getting from matrix
4424 
4425 @*/
4426 int MatGetPetscMaps(Mat mat,PetscMap *rmap,PetscMap *cmap)
4427 {
4428   int ierr;
4429 
4430   PetscFunctionBegin;
4431   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4432   PetscValidType(mat);
4433   MatPreallocated(mat);
4434   ierr = (*mat->ops->getmaps)(mat,rmap,cmap);CHKERRQ(ierr);
4435   PetscFunctionReturn(0);
4436 }
4437 
4438 /*
4439       Version that works for all PETSc matrices
4440 */
4441 #undef __FUNCT__
4442 #define __FUNCT__ "MatGetPetscMaps_Petsc"
4443 int MatGetPetscMaps_Petsc(Mat mat,PetscMap *rmap,PetscMap *cmap)
4444 {
4445   PetscFunctionBegin;
4446   if (rmap) *rmap = mat->rmap;
4447   if (cmap) *cmap = mat->cmap;
4448   PetscFunctionReturn(0);
4449 }
4450 
4451 #undef __FUNCT__
4452 #define __FUNCT__ "MatSetStashInitialSize"
4453 /*@
4454    MatSetStashInitialSize - sets the sizes of the matrix stash, that is
4455    used during the assembly process to store values that belong to
4456    other processors.
4457 
4458    Not Collective
4459 
4460    Input Parameters:
4461 +  mat   - the matrix
4462 .  size  - the initial size of the stash.
4463 -  bsize - the initial size of the block-stash(if used).
4464 
4465    Options Database Keys:
4466 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
4467 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
4468 
4469    Level: intermediate
4470 
4471    Notes:
4472      The block-stash is used for values set with VecSetValuesBlocked() while
4473      the stash is used for values set with VecSetValues()
4474 
4475      Run with the option -log_info and look for output of the form
4476      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
4477      to determine the appropriate value, MM, to use for size and
4478      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
4479      to determine the value, BMM to use for bsize
4480 
4481    Concepts: stash^setting matrix size
4482    Concepts: matrices^stash
4483 
4484 @*/
4485 int MatSetStashInitialSize(Mat mat,int size, int bsize)
4486 {
4487   int ierr;
4488 
4489   PetscFunctionBegin;
4490   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4491   PetscValidType(mat);
4492   MatPreallocated(mat);
4493   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
4494   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
4495   PetscFunctionReturn(0);
4496 }
4497 
4498 #undef __FUNCT__
4499 #define __FUNCT__ "MatInterpolateAdd"
4500 /*@
4501    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
4502      the matrix
4503 
4504    Collective on Mat
4505 
4506    Input Parameters:
4507 +  mat   - the matrix
4508 .  x,y - the vectors
4509 -  w - where the result is stored
4510 
4511    Level: intermediate
4512 
4513    Notes:
4514     w may be the same vector as y.
4515 
4516     This allows one to use either the restriction or interpolation (its transpose)
4517     matrix to do the interpolation
4518 
4519     Concepts: interpolation
4520 
4521 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
4522 
4523 @*/
4524 int MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
4525 {
4526   int M,N,ierr;
4527 
4528   PetscFunctionBegin;
4529   PetscValidType(A);
4530   MatPreallocated(A);
4531   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4532   if (N > M) {
4533     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
4534   } else {
4535     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
4536   }
4537   PetscFunctionReturn(0);
4538 }
4539 
4540 #undef __FUNCT__
4541 #define __FUNCT__ "MatInterpolate"
4542 /*@
4543    MatInterpolate - y = A*x or A'*x depending on the shape of
4544      the matrix
4545 
4546    Collective on Mat
4547 
4548    Input Parameters:
4549 +  mat   - the matrix
4550 -  x,y - the vectors
4551 
4552    Level: intermediate
4553 
4554    Notes:
4555     This allows one to use either the restriction or interpolation (its transpose)
4556     matrix to do the interpolation
4557 
4558    Concepts: matrices^interpolation
4559 
4560 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
4561 
4562 @*/
4563 int MatInterpolate(Mat A,Vec x,Vec y)
4564 {
4565   int M,N,ierr;
4566 
4567   PetscFunctionBegin;
4568   PetscValidType(A);
4569   MatPreallocated(A);
4570   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4571   if (N > M) {
4572     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
4573   } else {
4574     ierr = MatMult(A,x,y);CHKERRQ(ierr);
4575   }
4576   PetscFunctionReturn(0);
4577 }
4578 
4579 #undef __FUNCT__
4580 #define __FUNCT__ "MatRestrict"
4581 /*@
4582    MatRestrict - y = A*x or A'*x
4583 
4584    Collective on Mat
4585 
4586    Input Parameters:
4587 +  mat   - the matrix
4588 -  x,y - the vectors
4589 
4590    Level: intermediate
4591 
4592    Notes:
4593     This allows one to use either the restriction or interpolation (its transpose)
4594     matrix to do the restriction
4595 
4596    Concepts: matrices^restriction
4597 
4598 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
4599 
4600 @*/
4601 int MatRestrict(Mat A,Vec x,Vec y)
4602 {
4603   int M,N,ierr;
4604 
4605   PetscFunctionBegin;
4606   PetscValidType(A);
4607   MatPreallocated(A);
4608   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4609   if (N > M) {
4610     ierr = MatMult(A,x,y);CHKERRQ(ierr);
4611   } else {
4612     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
4613   }
4614   PetscFunctionReturn(0);
4615 }
4616 
4617 #undef __FUNCT__
4618 #define __FUNCT__ "MatNullSpaceAttach"
4619 /*@C
4620    MatNullSpaceAttach - attaches a null space to a matrix.
4621         This null space will be removed from the resulting vector whenever
4622         MatMult() is called
4623 
4624    Collective on Mat
4625 
4626    Input Parameters:
4627 +  mat - the matrix
4628 -  nullsp - the null space object
4629 
4630    Level: developer
4631 
4632    Notes:
4633       Overwrites any previous null space that may have been attached
4634 
4635    Concepts: null space^attaching to matrix
4636 
4637 .seealso: MatCreate(), MatNullSpaceCreate()
4638 @*/
4639 int MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
4640 {
4641   int ierr;
4642 
4643   PetscFunctionBegin;
4644   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4645   PetscValidType(mat);
4646   MatPreallocated(mat);
4647   PetscValidHeaderSpecific(nullsp,MATNULLSPACE_COOKIE);
4648 
4649   if (mat->nullsp) {
4650     ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr);
4651   }
4652   mat->nullsp = nullsp;
4653   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
4654   PetscFunctionReturn(0);
4655 }
4656 
4657 #undef __FUNCT__
4658 #define __FUNCT__ "MatICCFactor"
4659 /*@
4660    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
4661 
4662    Collective on Mat
4663 
4664    Input Parameters:
4665 +  mat - the matrix
4666 .  row - row/column permutation
4667 .  fill - expected fill factor >= 1.0
4668 -  level - level of fill, for ICC(k)
4669 
4670    Notes:
4671    Probably really in-place only when level of fill is zero, otherwise allocates
4672    new space to store factored matrix and deletes previous memory.
4673 
4674    Most users should employ the simplified SLES interface for linear solvers
4675    instead of working directly with matrix algebra routines such as this.
4676    See, e.g., SLESCreate().
4677 
4678    Level: developer
4679 
4680    Concepts: matrices^incomplete Cholesky factorization
4681    Concepts: Cholesky factorization
4682 
4683 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
4684 @*/
4685 int MatICCFactor(Mat mat,IS row,PetscReal fill,int level)
4686 {
4687   int ierr;
4688 
4689   PetscFunctionBegin;
4690   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4691   PetscValidType(mat);
4692   MatPreallocated(mat);
4693   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
4694   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4695   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4696   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4697   ierr = (*mat->ops->iccfactor)(mat,row,fill,level);CHKERRQ(ierr);
4698   PetscFunctionReturn(0);
4699 }
4700 
4701 #undef __FUNCT__
4702 #define __FUNCT__ "MatSetValuesAdic"
4703 /*@
4704    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
4705 
4706    Not Collective
4707 
4708    Input Parameters:
4709 +  mat - the matrix
4710 -  v - the values compute with ADIC
4711 
4712    Level: developer
4713 
4714    Notes:
4715      Must call MatSetColoring() before using this routine. Also this matrix must already
4716      have its nonzero pattern determined.
4717 
4718 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
4719           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
4720 @*/
4721 int MatSetValuesAdic(Mat mat,void *v)
4722 {
4723   int ierr;
4724 
4725   PetscFunctionBegin;
4726   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4727   PetscValidType(mat);
4728 
4729   if (!mat->assembled) {
4730     SETERRQ(1,"Matrix must be already assembled");
4731   }
4732   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
4733   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4734   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
4735   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
4736   ierr = MatView_Private(mat);CHKERRQ(ierr);
4737   PetscFunctionReturn(0);
4738 }
4739 
4740 
4741 #undef __FUNCT__
4742 #define __FUNCT__ "MatSetColoring"
4743 /*@
4744    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
4745 
4746    Not Collective
4747 
4748    Input Parameters:
4749 +  mat - the matrix
4750 -  coloring - the coloring
4751 
4752    Level: developer
4753 
4754 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
4755           MatSetValues(), MatSetValuesAdic()
4756 @*/
4757 int MatSetColoring(Mat mat,ISColoring coloring)
4758 {
4759   int ierr;
4760 
4761   PetscFunctionBegin;
4762   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4763   PetscValidType(mat);
4764 
4765   if (!mat->assembled) {
4766     SETERRQ(1,"Matrix must be already assembled");
4767   }
4768   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4769   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
4770   PetscFunctionReturn(0);
4771 }
4772 
4773 #undef __FUNCT__
4774 #define __FUNCT__ "MatSetValuesAdifor"
4775 /*@
4776    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
4777 
4778    Not Collective
4779 
4780    Input Parameters:
4781 +  mat - the matrix
4782 .  nl - leading dimension of v
4783 -  v - the values compute with ADIFOR
4784 
4785    Level: developer
4786 
4787    Notes:
4788      Must call MatSetColoring() before using this routine. Also this matrix must already
4789      have its nonzero pattern determined.
4790 
4791 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
4792           MatSetValues(), MatSetColoring()
4793 @*/
4794 int MatSetValuesAdifor(Mat mat,int nl,void *v)
4795 {
4796   int ierr;
4797 
4798   PetscFunctionBegin;
4799   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4800   PetscValidType(mat);
4801 
4802   if (!mat->assembled) {
4803     SETERRQ(1,"Matrix must be already assembled");
4804   }
4805   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
4806   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4807   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
4808   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
4809   PetscFunctionReturn(0);
4810 }
4811