xref: /petsc/src/mat/interface/matrix.c (revision c134de8d2530e1d0e12b3d536a25fd1369966ab4)
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 #if 0
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 #if 0
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    The user can set a value in the diagonal entry (or for the AIJ and
3432    row formats can optionally remove the main diagonal entry from the
3433    nonzero structure as well, by passing a null pointer (PETSC_NULL
3434    in C or PETSC_NULL_SCALAR in Fortran) as the final argument).
3435 
3436    Level: intermediate
3437 
3438    Concepts: matrices^zeroing
3439 
3440 .seealso: MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
3441 @*/
3442 int MatZeroRowsLocal(Mat mat,IS is,PetscScalar *diag)
3443 {
3444   int ierr;
3445   IS  newis;
3446 
3447   PetscFunctionBegin;
3448   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3449   PetscValidType(mat);
3450   MatPreallocated(mat);
3451   PetscValidHeaderSpecific(is,IS_COOKIE);
3452   if (diag) PetscValidScalarPointer(diag);
3453   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3454   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3455 
3456   if (mat->ops->zerorowslocal) {
3457     ierr = (*mat->ops->zerorowslocal)(mat,is,diag);CHKERRQ(ierr);
3458   } else {
3459     if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
3460     ierr = ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);CHKERRQ(ierr);
3461     ierr = (*mat->ops->zerorows)(mat,newis,diag);CHKERRQ(ierr);
3462     ierr = ISDestroy(newis);CHKERRQ(ierr);
3463   }
3464   PetscFunctionReturn(0);
3465 }
3466 
3467 #undef __FUNCT__
3468 #define __FUNCT__ "MatGetSize"
3469 /*@
3470    MatGetSize - Returns the numbers of rows and columns in a matrix.
3471 
3472    Not Collective
3473 
3474    Input Parameter:
3475 .  mat - the matrix
3476 
3477    Output Parameters:
3478 +  m - the number of global rows
3479 -  n - the number of global columns
3480 
3481    Level: beginner
3482 
3483    Concepts: matrices^size
3484 
3485 .seealso: MatGetLocalSize()
3486 @*/
3487 int MatGetSize(Mat mat,int *m,int* n)
3488 {
3489   PetscFunctionBegin;
3490   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3491   if (m) *m = mat->M;
3492   if (n) *n = mat->N;
3493   PetscFunctionReturn(0);
3494 }
3495 
3496 #undef __FUNCT__
3497 #define __FUNCT__ "MatGetLocalSize"
3498 /*@
3499    MatGetLocalSize - Returns the number of rows and columns in a matrix
3500    stored locally.  This information may be implementation dependent, so
3501    use with care.
3502 
3503    Not Collective
3504 
3505    Input Parameters:
3506 .  mat - the matrix
3507 
3508    Output Parameters:
3509 +  m - the number of local rows
3510 -  n - the number of local columns
3511 
3512    Level: beginner
3513 
3514    Concepts: matrices^local size
3515 
3516 .seealso: MatGetSize()
3517 @*/
3518 int MatGetLocalSize(Mat mat,int *m,int* n)
3519 {
3520   PetscFunctionBegin;
3521   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3522   if (m) *m = mat->m;
3523   if (n) *n = mat->n;
3524   PetscFunctionReturn(0);
3525 }
3526 
3527 #undef __FUNCT__
3528 #define __FUNCT__ "MatGetOwnershipRange"
3529 /*@
3530    MatGetOwnershipRange - Returns the range of matrix rows owned by
3531    this processor, assuming that the matrix is laid out with the first
3532    n1 rows on the first processor, the next n2 rows on the second, etc.
3533    For certain parallel layouts this range may not be well defined.
3534 
3535    Not Collective
3536 
3537    Input Parameters:
3538 .  mat - the matrix
3539 
3540    Output Parameters:
3541 +  m - the global index of the first local row
3542 -  n - one more than the global index of the last local row
3543 
3544    Level: beginner
3545 
3546    Concepts: matrices^row ownership
3547 @*/
3548 int MatGetOwnershipRange(Mat mat,int *m,int* n)
3549 {
3550   int ierr;
3551 
3552   PetscFunctionBegin;
3553   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3554   PetscValidType(mat);
3555   MatPreallocated(mat);
3556   if (m) PetscValidIntPointer(m);
3557   if (n) PetscValidIntPointer(n);
3558   ierr = PetscMapGetLocalRange(mat->rmap,m,n);CHKERRQ(ierr);
3559   PetscFunctionReturn(0);
3560 }
3561 
3562 #undef __FUNCT__
3563 #define __FUNCT__ "MatILUFactorSymbolic"
3564 /*@
3565    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
3566    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
3567    to complete the factorization.
3568 
3569    Collective on Mat
3570 
3571    Input Parameters:
3572 +  mat - the matrix
3573 .  row - row permutation
3574 .  column - column permutation
3575 -  info - structure containing
3576 $      levels - number of levels of fill.
3577 $      expected fill - as ratio of original fill.
3578 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
3579                 missing diagonal entries)
3580 
3581    Output Parameters:
3582 .  fact - new matrix that has been symbolically factored
3583 
3584    Notes:
3585    See the users manual for additional information about
3586    choosing the fill factor for better efficiency.
3587 
3588    Most users should employ the simplified SLES interface for linear solvers
3589    instead of working directly with matrix algebra routines such as this.
3590    See, e.g., SLESCreate().
3591 
3592    Level: developer
3593 
3594   Concepts: matrices^symbolic LU factorization
3595   Concepts: matrices^factorization
3596   Concepts: LU^symbolic factorization
3597 
3598 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
3599           MatGetOrdering(), MatILUInfo
3600 
3601 @*/
3602 int MatILUFactorSymbolic(Mat mat,IS row,IS col,MatILUInfo *info,Mat *fact)
3603 {
3604   int ierr;
3605 
3606   PetscFunctionBegin;
3607   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3608   PetscValidType(mat);
3609   MatPreallocated(mat);
3610   PetscValidPointer(fact);
3611   PetscValidHeaderSpecific(row,IS_COOKIE);
3612   PetscValidHeaderSpecific(col,IS_COOKIE);
3613   if (info && info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %d",info->levels);
3614   if (info && info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",info->fill);
3615   if (!mat->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",mat->type_name);
3616   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3617   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3618 
3619   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3620   ierr = (*mat->ops->ilufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
3621   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3622   PetscFunctionReturn(0);
3623 }
3624 
3625 #undef __FUNCT__
3626 #define __FUNCT__ "MatICCFactorSymbolic"
3627 /*@
3628    MatICCFactorSymbolic - Performs symbolic incomplete
3629    Cholesky factorization for a symmetric matrix.  Use
3630    MatCholeskyFactorNumeric() to complete the factorization.
3631 
3632    Collective on Mat
3633 
3634    Input Parameters:
3635 +  mat - the matrix
3636 .  perm - row and column permutation
3637 .  fill - levels of fill
3638 -  f - expected fill as ratio of original fill
3639 
3640    Output Parameter:
3641 .  fact - the factored matrix
3642 
3643    Notes:
3644    Currently only no-fill factorization is supported.
3645 
3646    Most users should employ the simplified SLES interface for linear solvers
3647    instead of working directly with matrix algebra routines such as this.
3648    See, e.g., SLESCreate().
3649 
3650    Level: developer
3651 
3652   Concepts: matrices^symbolic incomplete Cholesky factorization
3653   Concepts: matrices^factorization
3654   Concepts: Cholsky^symbolic factorization
3655 
3656 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor()
3657 @*/
3658 int MatICCFactorSymbolic(Mat mat,IS perm,PetscReal f,int fill,Mat *fact)
3659 {
3660   int ierr;
3661 
3662   PetscFunctionBegin;
3663   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3664   PetscValidType(mat);
3665   MatPreallocated(mat);
3666   PetscValidPointer(fact);
3667   PetscValidHeaderSpecific(perm,IS_COOKIE);
3668   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3669   if (fill < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Fill negative %d",fill);
3670   if (f < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",f);
3671   if (!mat->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",mat->type_name);
3672   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3673 
3674   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3675   ierr = (*mat->ops->iccfactorsymbolic)(mat,perm,f,fill,fact);CHKERRQ(ierr);
3676   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3677   PetscFunctionReturn(0);
3678 }
3679 
3680 #undef __FUNCT__
3681 #define __FUNCT__ "MatGetArray"
3682 /*@C
3683    MatGetArray - Returns a pointer to the element values in the matrix.
3684    The result of this routine is dependent on the underlying matrix data
3685    structure, and may not even work for certain matrix types.  You MUST
3686    call MatRestoreArray() when you no longer need to access the array.
3687 
3688    Not Collective
3689 
3690    Input Parameter:
3691 .  mat - the matrix
3692 
3693    Output Parameter:
3694 .  v - the location of the values
3695 
3696 
3697    Fortran Note:
3698    This routine is used differently from Fortran, e.g.,
3699 .vb
3700         Mat         mat
3701         PetscScalar mat_array(1)
3702         PetscOffset i_mat
3703         int         ierr
3704         call MatGetArray(mat,mat_array,i_mat,ierr)
3705 
3706   C  Access first local entry in matrix; note that array is
3707   C  treated as one dimensional
3708         value = mat_array(i_mat + 1)
3709 
3710         [... other code ...]
3711         call MatRestoreArray(mat,mat_array,i_mat,ierr)
3712 .ve
3713 
3714    See the Fortran chapter of the users manual and
3715    petsc/src/mat/examples/tests for details.
3716 
3717    Level: advanced
3718 
3719    Concepts: matrices^access array
3720 
3721 .seealso: MatRestoreArray(), MatGetArrayF90()
3722 @*/
3723 int MatGetArray(Mat mat,PetscScalar **v)
3724 {
3725   int ierr;
3726 
3727   PetscFunctionBegin;
3728   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3729   PetscValidType(mat);
3730   MatPreallocated(mat);
3731   PetscValidPointer(v);
3732   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3733   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
3734   PetscFunctionReturn(0);
3735 }
3736 
3737 #undef __FUNCT__
3738 #define __FUNCT__ "MatRestoreArray"
3739 /*@C
3740    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
3741 
3742    Not Collective
3743 
3744    Input Parameter:
3745 +  mat - the matrix
3746 -  v - the location of the values
3747 
3748    Fortran Note:
3749    This routine is used differently from Fortran, e.g.,
3750 .vb
3751         Mat         mat
3752         PetscScalar mat_array(1)
3753         PetscOffset i_mat
3754         int         ierr
3755         call MatGetArray(mat,mat_array,i_mat,ierr)
3756 
3757   C  Access first local entry in matrix; note that array is
3758   C  treated as one dimensional
3759         value = mat_array(i_mat + 1)
3760 
3761         [... other code ...]
3762         call MatRestoreArray(mat,mat_array,i_mat,ierr)
3763 .ve
3764 
3765    See the Fortran chapter of the users manual and
3766    petsc/src/mat/examples/tests for details
3767 
3768    Level: advanced
3769 
3770 .seealso: MatGetArray(), MatRestoreArrayF90()
3771 @*/
3772 int MatRestoreArray(Mat mat,PetscScalar **v)
3773 {
3774   int ierr;
3775 
3776   PetscFunctionBegin;
3777   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3778   PetscValidType(mat);
3779   MatPreallocated(mat);
3780   PetscValidPointer(v);
3781   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3782   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
3783   PetscFunctionReturn(0);
3784 }
3785 
3786 #undef __FUNCT__
3787 #define __FUNCT__ "MatGetSubMatrices"
3788 /*@C
3789    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
3790    points to an array of valid matrices, they may be reused to store the new
3791    submatrices.
3792 
3793    Collective on Mat
3794 
3795    Input Parameters:
3796 +  mat - the matrix
3797 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
3798 .  irow, icol - index sets of rows and columns to extract
3799 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
3800 
3801    Output Parameter:
3802 .  submat - the array of submatrices
3803 
3804    Notes:
3805    MatGetSubMatrices() can extract only sequential submatrices
3806    (from both sequential and parallel matrices). Use MatGetSubMatrix()
3807    to extract a parallel submatrix.
3808 
3809    When extracting submatrices from a parallel matrix, each processor can
3810    form a different submatrix by setting the rows and columns of its
3811    individual index sets according to the local submatrix desired.
3812 
3813    When finished using the submatrices, the user should destroy
3814    them with MatDestroyMatrices().
3815 
3816    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
3817    original matrix has not changed from that last call to MatGetSubMatrices().
3818 
3819    This routine creates the matrices submat; you should NOT create them before
3820    calling it.
3821 
3822    Fortran Note:
3823    The Fortran interface is slightly different from that given below; it
3824    requires one to pass in  as submat a Mat (integer) array of size at least m.
3825 
3826    Level: advanced
3827 
3828    Concepts: matrices^accessing submatrices
3829    Concepts: submatrices
3830 
3831 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal()
3832 @*/
3833 int MatGetSubMatrices(Mat mat,int n,IS *irow,IS *icol,MatReuse scall,Mat **submat)
3834 {
3835   int        ierr;
3836 
3837   PetscFunctionBegin;
3838   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3839   PetscValidType(mat);
3840   MatPreallocated(mat);
3841   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3842   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3843 
3844   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
3845   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
3846   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
3847   PetscFunctionReturn(0);
3848 }
3849 
3850 #undef __FUNCT__
3851 #define __FUNCT__ "MatDestroyMatrices"
3852 /*@C
3853    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
3854 
3855    Collective on Mat
3856 
3857    Input Parameters:
3858 +  n - the number of local matrices
3859 -  mat - the matrices
3860 
3861    Level: advanced
3862 
3863     Notes: Frees not only the matrices, but also the array that contains the matrices
3864 
3865 .seealso: MatGetSubMatrices()
3866 @*/
3867 int MatDestroyMatrices(int n,Mat **mat)
3868 {
3869   int ierr,i;
3870 
3871   PetscFunctionBegin;
3872   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %d",n);
3873   PetscValidPointer(mat);
3874   for (i=0; i<n; i++) {
3875     ierr = MatDestroy((*mat)[i]);CHKERRQ(ierr);
3876   }
3877   /* memory is allocated even if n = 0 */
3878   ierr = PetscFree(*mat);CHKERRQ(ierr);
3879   PetscFunctionReturn(0);
3880 }
3881 
3882 #undef __FUNCT__
3883 #define __FUNCT__ "MatIncreaseOverlap"
3884 /*@
3885    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
3886    replaces the index sets by larger ones that represent submatrices with
3887    additional overlap.
3888 
3889    Collective on Mat
3890 
3891    Input Parameters:
3892 +  mat - the matrix
3893 .  n   - the number of index sets
3894 .  is  - the array of pointers to index sets
3895 -  ov  - the additional overlap requested
3896 
3897    Level: developer
3898 
3899    Concepts: overlap
3900    Concepts: ASM^computing overlap
3901 
3902 .seealso: MatGetSubMatrices()
3903 @*/
3904 int MatIncreaseOverlap(Mat mat,int n,IS *is,int ov)
3905 {
3906   int ierr;
3907 
3908   PetscFunctionBegin;
3909   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3910   PetscValidType(mat);
3911   MatPreallocated(mat);
3912   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3913   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3914 
3915   if (!ov) PetscFunctionReturn(0);
3916   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3917   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
3918   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
3919   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
3920   PetscFunctionReturn(0);
3921 }
3922 
3923 #undef __FUNCT__
3924 #define __FUNCT__ "MatPrintHelp"
3925 /*@
3926    MatPrintHelp - Prints all the options for the matrix.
3927 
3928    Collective on Mat
3929 
3930    Input Parameter:
3931 .  mat - the matrix
3932 
3933    Options Database Keys:
3934 +  -help - Prints matrix options
3935 -  -h - Prints matrix options
3936 
3937    Level: developer
3938 
3939 .seealso: MatCreate(), MatCreateXXX()
3940 @*/
3941 int MatPrintHelp(Mat mat)
3942 {
3943   static PetscTruth called = PETSC_FALSE;
3944   int               ierr;
3945   MPI_Comm          comm;
3946 
3947   PetscFunctionBegin;
3948   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3949   PetscValidType(mat);
3950   MatPreallocated(mat);
3951 
3952   comm = mat->comm;
3953   if (!called) {
3954     ierr = (*PetscHelpPrintf)(comm,"General matrix options:\n");CHKERRQ(ierr);
3955     ierr = (*PetscHelpPrintf)(comm,"  -mat_view_info: view basic matrix info during MatAssemblyEnd()\n");CHKERRQ(ierr);
3956     ierr = (*PetscHelpPrintf)(comm,"  -mat_view_info_detailed: view detailed matrix info during MatAssemblyEnd()\n");CHKERRQ(ierr);
3957     ierr = (*PetscHelpPrintf)(comm,"  -mat_view_draw: draw nonzero matrix structure during MatAssemblyEnd()\n");CHKERRQ(ierr);
3958     ierr = (*PetscHelpPrintf)(comm,"      -draw_pause <sec>: set seconds of display pause\n");CHKERRQ(ierr);
3959     ierr = (*PetscHelpPrintf)(comm,"      -display <name>: set alternate display\n");CHKERRQ(ierr);
3960     called = PETSC_TRUE;
3961   }
3962   if (mat->ops->printhelp) {
3963     ierr = (*mat->ops->printhelp)(mat);CHKERRQ(ierr);
3964   }
3965   PetscFunctionReturn(0);
3966 }
3967 
3968 #undef __FUNCT__
3969 #define __FUNCT__ "MatGetBlockSize"
3970 /*@
3971    MatGetBlockSize - Returns the matrix block size; useful especially for the
3972    block row and block diagonal formats.
3973 
3974    Not Collective
3975 
3976    Input Parameter:
3977 .  mat - the matrix
3978 
3979    Output Parameter:
3980 .  bs - block size
3981 
3982    Notes:
3983    Block diagonal formats are MATSEQBDIAG, MATMPIBDIAG.
3984    Block row formats are MATSEQBAIJ, MATMPIBAIJ
3985 
3986    Level: intermediate
3987 
3988    Concepts: matrices^block size
3989 
3990 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatCreateSeqBDiag(), MatCreateMPIBDiag()
3991 @*/
3992 int MatGetBlockSize(Mat mat,int *bs)
3993 {
3994   int ierr;
3995 
3996   PetscFunctionBegin;
3997   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3998   PetscValidType(mat);
3999   MatPreallocated(mat);
4000   PetscValidIntPointer(bs);
4001   if (!mat->ops->getblocksize) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4002   ierr = (*mat->ops->getblocksize)(mat,bs);CHKERRQ(ierr);
4003   PetscFunctionReturn(0);
4004 }
4005 
4006 #undef __FUNCT__
4007 #define __FUNCT__ "MatGetRowIJ"
4008 /*@C
4009     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
4010 
4011    Collective on Mat
4012 
4013     Input Parameters:
4014 +   mat - the matrix
4015 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
4016 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4017                 symmetrized
4018 
4019     Output Parameters:
4020 +   n - number of rows in the (possibly compressed) matrix
4021 .   ia - the row pointers
4022 .   ja - the column indices
4023 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
4024 
4025     Level: developer
4026 
4027 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
4028 @*/
4029 int MatGetRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
4030 {
4031   int ierr;
4032 
4033   PetscFunctionBegin;
4034   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4035   PetscValidType(mat);
4036   MatPreallocated(mat);
4037   if (ia) PetscValidIntPointer(ia);
4038   if (ja) PetscValidIntPointer(ja);
4039   PetscValidIntPointer(done);
4040   if (!mat->ops->getrowij) *done = PETSC_FALSE;
4041   else {
4042     *done = PETSC_TRUE;
4043     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4044   }
4045   PetscFunctionReturn(0);
4046 }
4047 
4048 #undef __FUNCT__
4049 #define __FUNCT__ "MatGetColumnIJ"
4050 /*@C
4051     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
4052 
4053     Collective on Mat
4054 
4055     Input Parameters:
4056 +   mat - the matrix
4057 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4058 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4059                 symmetrized
4060 
4061     Output Parameters:
4062 +   n - number of columns in the (possibly compressed) matrix
4063 .   ia - the column pointers
4064 .   ja - the row indices
4065 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
4066 
4067     Level: developer
4068 
4069 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
4070 @*/
4071 int MatGetColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
4072 {
4073   int ierr;
4074 
4075   PetscFunctionBegin;
4076   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4077   PetscValidType(mat);
4078   MatPreallocated(mat);
4079   if (ia) PetscValidIntPointer(ia);
4080   if (ja) PetscValidIntPointer(ja);
4081   PetscValidIntPointer(done);
4082 
4083   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
4084   else {
4085     *done = PETSC_TRUE;
4086     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4087   }
4088   PetscFunctionReturn(0);
4089 }
4090 
4091 #undef __FUNCT__
4092 #define __FUNCT__ "MatRestoreRowIJ"
4093 /*@C
4094     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
4095     MatGetRowIJ().
4096 
4097     Collective on Mat
4098 
4099     Input Parameters:
4100 +   mat - the matrix
4101 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4102 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4103                 symmetrized
4104 
4105     Output Parameters:
4106 +   n - size of (possibly compressed) matrix
4107 .   ia - the row pointers
4108 .   ja - the column indices
4109 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
4110 
4111     Level: developer
4112 
4113 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
4114 @*/
4115 int MatRestoreRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
4116 {
4117   int ierr;
4118 
4119   PetscFunctionBegin;
4120   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4121   PetscValidType(mat);
4122   MatPreallocated(mat);
4123   if (ia) PetscValidIntPointer(ia);
4124   if (ja) PetscValidIntPointer(ja);
4125   PetscValidIntPointer(done);
4126 
4127   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
4128   else {
4129     *done = PETSC_TRUE;
4130     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4131   }
4132   PetscFunctionReturn(0);
4133 }
4134 
4135 #undef __FUNCT__
4136 #define __FUNCT__ "MatRestoreColumnIJ"
4137 /*@C
4138     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
4139     MatGetColumnIJ().
4140 
4141     Collective on Mat
4142 
4143     Input Parameters:
4144 +   mat - the matrix
4145 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4146 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4147                 symmetrized
4148 
4149     Output Parameters:
4150 +   n - size of (possibly compressed) matrix
4151 .   ia - the column pointers
4152 .   ja - the row indices
4153 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
4154 
4155     Level: developer
4156 
4157 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
4158 @*/
4159 int MatRestoreColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
4160 {
4161   int ierr;
4162 
4163   PetscFunctionBegin;
4164   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4165   PetscValidType(mat);
4166   MatPreallocated(mat);
4167   if (ia) PetscValidIntPointer(ia);
4168   if (ja) PetscValidIntPointer(ja);
4169   PetscValidIntPointer(done);
4170 
4171   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
4172   else {
4173     *done = PETSC_TRUE;
4174     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4175   }
4176   PetscFunctionReturn(0);
4177 }
4178 
4179 #undef __FUNCT__
4180 #define __FUNCT__ "MatColoringPatch"
4181 /*@C
4182     MatColoringPatch -Used inside matrix coloring routines that
4183     use MatGetRowIJ() and/or MatGetColumnIJ().
4184 
4185     Collective on Mat
4186 
4187     Input Parameters:
4188 +   mat - the matrix
4189 .   n   - number of colors
4190 -   colorarray - array indicating color for each column
4191 
4192     Output Parameters:
4193 .   iscoloring - coloring generated using colorarray information
4194 
4195     Level: developer
4196 
4197 .seealso: MatGetRowIJ(), MatGetColumnIJ()
4198 
4199 @*/
4200 int MatColoringPatch(Mat mat,int n,int ncolors,int *colorarray,ISColoring *iscoloring)
4201 {
4202   int ierr;
4203 
4204   PetscFunctionBegin;
4205   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4206   PetscValidType(mat);
4207   MatPreallocated(mat);
4208   PetscValidIntPointer(colorarray);
4209 
4210   if (!mat->ops->coloringpatch){
4211     ierr = ISColoringCreate(mat->comm,n,colorarray,iscoloring);CHKERRQ(ierr);
4212   } else {
4213     ierr = (*mat->ops->coloringpatch)(mat,n,ncolors,colorarray,iscoloring);CHKERRQ(ierr);
4214   }
4215   PetscFunctionReturn(0);
4216 }
4217 
4218 
4219 #undef __FUNCT__
4220 #define __FUNCT__ "MatSetUnfactored"
4221 /*@
4222    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
4223 
4224    Collective on Mat
4225 
4226    Input Parameter:
4227 .  mat - the factored matrix to be reset
4228 
4229    Notes:
4230    This routine should be used only with factored matrices formed by in-place
4231    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
4232    format).  This option can save memory, for example, when solving nonlinear
4233    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
4234    ILU(0) preconditioner.
4235 
4236    Note that one can specify in-place ILU(0) factorization by calling
4237 .vb
4238      PCType(pc,PCILU);
4239      PCILUSeUseInPlace(pc);
4240 .ve
4241    or by using the options -pc_type ilu -pc_ilu_in_place
4242 
4243    In-place factorization ILU(0) can also be used as a local
4244    solver for the blocks within the block Jacobi or additive Schwarz
4245    methods (runtime option: -sub_pc_ilu_in_place).  See the discussion
4246    of these preconditioners in the users manual for details on setting
4247    local solver options.
4248 
4249    Most users should employ the simplified SLES interface for linear solvers
4250    instead of working directly with matrix algebra routines such as this.
4251    See, e.g., SLESCreate().
4252 
4253    Level: developer
4254 
4255 .seealso: PCILUSetUseInPlace(), PCLUSetUseInPlace()
4256 
4257    Concepts: matrices^unfactored
4258 
4259 @*/
4260 int MatSetUnfactored(Mat mat)
4261 {
4262   int ierr;
4263 
4264   PetscFunctionBegin;
4265   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4266   PetscValidType(mat);
4267   MatPreallocated(mat);
4268   mat->factor = 0;
4269   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
4270   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
4271   PetscFunctionReturn(0);
4272 }
4273 
4274 /*MC
4275     MatGetArrayF90 - Accesses a matrix array from Fortran90.
4276 
4277     Synopsis:
4278     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
4279 
4280     Not collective
4281 
4282     Input Parameter:
4283 .   x - matrix
4284 
4285     Output Parameters:
4286 +   xx_v - the Fortran90 pointer to the array
4287 -   ierr - error code
4288 
4289     Example of Usage:
4290 .vb
4291       PetscScalar, pointer xx_v(:)
4292       ....
4293       call MatGetArrayF90(x,xx_v,ierr)
4294       a = xx_v(3)
4295       call MatRestoreArrayF90(x,xx_v,ierr)
4296 .ve
4297 
4298     Notes:
4299     Not yet supported for all F90 compilers
4300 
4301     Level: advanced
4302 
4303 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
4304 
4305     Concepts: matrices^accessing array
4306 
4307 M*/
4308 
4309 /*MC
4310     MatRestoreArrayF90 - Restores a matrix array that has been
4311     accessed with MatGetArrayF90().
4312 
4313     Synopsis:
4314     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
4315 
4316     Not collective
4317 
4318     Input Parameters:
4319 +   x - matrix
4320 -   xx_v - the Fortran90 pointer to the array
4321 
4322     Output Parameter:
4323 .   ierr - error code
4324 
4325     Example of Usage:
4326 .vb
4327        PetscScalar, pointer xx_v(:)
4328        ....
4329        call MatGetArrayF90(x,xx_v,ierr)
4330        a = xx_v(3)
4331        call MatRestoreArrayF90(x,xx_v,ierr)
4332 .ve
4333 
4334     Notes:
4335     Not yet supported for all F90 compilers
4336 
4337     Level: advanced
4338 
4339 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
4340 
4341 M*/
4342 
4343 
4344 #undef __FUNCT__
4345 #define __FUNCT__ "MatGetSubMatrix"
4346 /*@
4347     MatGetSubMatrix - Gets a single submatrix on the same number of processors
4348                       as the original matrix.
4349 
4350     Collective on Mat
4351 
4352     Input Parameters:
4353 +   mat - the original matrix
4354 .   isrow - rows this processor should obtain
4355 .   iscol - columns for all processors you wish to keep
4356 .   csize - number of columns "local" to this processor (does nothing for sequential
4357             matrices). This should match the result from VecGetLocalSize(x,...) if you
4358             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
4359 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4360 
4361     Output Parameter:
4362 .   newmat - the new submatrix, of the same type as the old
4363 
4364     Level: advanced
4365 
4366     Notes: the iscol argument MUST be the same on each processor.
4367 
4368       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
4369    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
4370    to this routine with a mat of the same nonzero structure will reuse the matrix
4371    generated the first time.
4372 
4373     Concepts: matrices^submatrices
4374 
4375 .seealso: MatGetSubMatrices()
4376 @*/
4377 int MatGetSubMatrix(Mat mat,IS isrow,IS iscol,int csize,MatReuse cll,Mat *newmat)
4378 {
4379   int     ierr, size;
4380   Mat     *local;
4381 
4382   PetscFunctionBegin;
4383   PetscValidType(mat);
4384   MatPreallocated(mat);
4385   ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr);
4386 
4387   /* if original matrix is on just one processor then use submatrix generated */
4388   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
4389     ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
4390     PetscFunctionReturn(0);
4391   } else if (!mat->ops->getsubmatrix && size == 1) {
4392     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
4393     *newmat = *local;
4394     ierr    = PetscFree(local);CHKERRQ(ierr);
4395     PetscFunctionReturn(0);
4396   }
4397 
4398   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4399   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscol,csize,cll,newmat);CHKERRQ(ierr);
4400   PetscFunctionReturn(0);
4401 }
4402 
4403 #undef __FUNCT__
4404 #define __FUNCT__ "MatGetPetscMaps"
4405 /*@C
4406    MatGetPetscMaps - Returns the maps associated with the matrix.
4407 
4408    Not Collective
4409 
4410    Input Parameter:
4411 .  mat - the matrix
4412 
4413    Output Parameters:
4414 +  rmap - the row (right) map
4415 -  cmap - the column (left) map
4416 
4417    Level: developer
4418 
4419    Concepts: maps^getting from matrix
4420 
4421 @*/
4422 int MatGetPetscMaps(Mat mat,PetscMap *rmap,PetscMap *cmap)
4423 {
4424   int ierr;
4425 
4426   PetscFunctionBegin;
4427   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4428   PetscValidType(mat);
4429   MatPreallocated(mat);
4430   ierr = (*mat->ops->getmaps)(mat,rmap,cmap);CHKERRQ(ierr);
4431   PetscFunctionReturn(0);
4432 }
4433 
4434 /*
4435       Version that works for all PETSc matrices
4436 */
4437 #undef __FUNCT__
4438 #define __FUNCT__ "MatGetPetscMaps_Petsc"
4439 int MatGetPetscMaps_Petsc(Mat mat,PetscMap *rmap,PetscMap *cmap)
4440 {
4441   PetscFunctionBegin;
4442   if (rmap) *rmap = mat->rmap;
4443   if (cmap) *cmap = mat->cmap;
4444   PetscFunctionReturn(0);
4445 }
4446 
4447 #undef __FUNCT__
4448 #define __FUNCT__ "MatSetStashInitialSize"
4449 /*@
4450    MatSetStashInitialSize - sets the sizes of the matrix stash, that is
4451    used during the assembly process to store values that belong to
4452    other processors.
4453 
4454    Not Collective
4455 
4456    Input Parameters:
4457 +  mat   - the matrix
4458 .  size  - the initial size of the stash.
4459 -  bsize - the initial size of the block-stash(if used).
4460 
4461    Options Database Keys:
4462 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
4463 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
4464 
4465    Level: intermediate
4466 
4467    Notes:
4468      The block-stash is used for values set with VecSetValuesBlocked() while
4469      the stash is used for values set with VecSetValues()
4470 
4471      Run with the option -log_info and look for output of the form
4472      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
4473      to determine the appropriate value, MM, to use for size and
4474      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
4475      to determine the value, BMM to use for bsize
4476 
4477    Concepts: stash^setting matrix size
4478    Concepts: matrices^stash
4479 
4480 @*/
4481 int MatSetStashInitialSize(Mat mat,int size, int bsize)
4482 {
4483   int ierr;
4484 
4485   PetscFunctionBegin;
4486   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4487   PetscValidType(mat);
4488   MatPreallocated(mat);
4489   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
4490   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
4491   PetscFunctionReturn(0);
4492 }
4493 
4494 #undef __FUNCT__
4495 #define __FUNCT__ "MatInterpolateAdd"
4496 /*@
4497    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
4498      the matrix
4499 
4500    Collective on Mat
4501 
4502    Input Parameters:
4503 +  mat   - the matrix
4504 .  x,y - the vectors
4505 -  w - where the result is stored
4506 
4507    Level: intermediate
4508 
4509    Notes:
4510     w may be the same vector as y.
4511 
4512     This allows one to use either the restriction or interpolation (its transpose)
4513     matrix to do the interpolation
4514 
4515     Concepts: interpolation
4516 
4517 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
4518 
4519 @*/
4520 int MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
4521 {
4522   int M,N,ierr;
4523 
4524   PetscFunctionBegin;
4525   PetscValidType(A);
4526   MatPreallocated(A);
4527   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4528   if (N > M) {
4529     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
4530   } else {
4531     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
4532   }
4533   PetscFunctionReturn(0);
4534 }
4535 
4536 #undef __FUNCT__
4537 #define __FUNCT__ "MatInterpolate"
4538 /*@
4539    MatInterpolate - y = A*x or A'*x depending on the shape of
4540      the matrix
4541 
4542    Collective on Mat
4543 
4544    Input Parameters:
4545 +  mat   - the matrix
4546 -  x,y - the vectors
4547 
4548    Level: intermediate
4549 
4550    Notes:
4551     This allows one to use either the restriction or interpolation (its transpose)
4552     matrix to do the interpolation
4553 
4554    Concepts: matrices^interpolation
4555 
4556 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
4557 
4558 @*/
4559 int MatInterpolate(Mat A,Vec x,Vec y)
4560 {
4561   int M,N,ierr;
4562 
4563   PetscFunctionBegin;
4564   PetscValidType(A);
4565   MatPreallocated(A);
4566   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4567   if (N > M) {
4568     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
4569   } else {
4570     ierr = MatMult(A,x,y);CHKERRQ(ierr);
4571   }
4572   PetscFunctionReturn(0);
4573 }
4574 
4575 #undef __FUNCT__
4576 #define __FUNCT__ "MatRestrict"
4577 /*@
4578    MatRestrict - y = A*x or A'*x
4579 
4580    Collective on Mat
4581 
4582    Input Parameters:
4583 +  mat   - the matrix
4584 -  x,y - the vectors
4585 
4586    Level: intermediate
4587 
4588    Notes:
4589     This allows one to use either the restriction or interpolation (its transpose)
4590     matrix to do the restriction
4591 
4592    Concepts: matrices^restriction
4593 
4594 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
4595 
4596 @*/
4597 int MatRestrict(Mat A,Vec x,Vec y)
4598 {
4599   int M,N,ierr;
4600 
4601   PetscFunctionBegin;
4602   PetscValidType(A);
4603   MatPreallocated(A);
4604   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4605   if (N > M) {
4606     ierr = MatMult(A,x,y);CHKERRQ(ierr);
4607   } else {
4608     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
4609   }
4610   PetscFunctionReturn(0);
4611 }
4612 
4613 #undef __FUNCT__
4614 #define __FUNCT__ "MatNullSpaceAttach"
4615 /*@C
4616    MatNullSpaceAttach - attaches a null space to a matrix.
4617         This null space will be removed from the resulting vector whenever
4618         MatMult() is called
4619 
4620    Collective on Mat
4621 
4622    Input Parameters:
4623 +  mat - the matrix
4624 -  nullsp - the null space object
4625 
4626    Level: developer
4627 
4628    Notes:
4629       Overwrites any previous null space that may have been attached
4630 
4631    Concepts: null space^attaching to matrix
4632 
4633 .seealso: MatCreate(), MatNullSpaceCreate()
4634 @*/
4635 int MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
4636 {
4637   int ierr;
4638 
4639   PetscFunctionBegin;
4640   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4641   PetscValidType(mat);
4642   MatPreallocated(mat);
4643   PetscValidHeaderSpecific(nullsp,MATNULLSPACE_COOKIE);
4644 
4645   if (mat->nullsp) {
4646     ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr);
4647   }
4648   mat->nullsp = nullsp;
4649   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
4650   PetscFunctionReturn(0);
4651 }
4652 
4653 #undef __FUNCT__
4654 #define __FUNCT__ "MatICCFactor"
4655 /*@
4656    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
4657 
4658    Collective on Mat
4659 
4660    Input Parameters:
4661 +  mat - the matrix
4662 .  row - row/column permutation
4663 .  fill - expected fill factor >= 1.0
4664 -  level - level of fill, for ICC(k)
4665 
4666    Notes:
4667    Probably really in-place only when level of fill is zero, otherwise allocates
4668    new space to store factored matrix and deletes previous memory.
4669 
4670    Most users should employ the simplified SLES interface for linear solvers
4671    instead of working directly with matrix algebra routines such as this.
4672    See, e.g., SLESCreate().
4673 
4674    Level: developer
4675 
4676    Concepts: matrices^incomplete Cholesky factorization
4677    Concepts: Cholesky factorization
4678 
4679 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
4680 @*/
4681 int MatICCFactor(Mat mat,IS row,PetscReal fill,int level)
4682 {
4683   int ierr;
4684 
4685   PetscFunctionBegin;
4686   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4687   PetscValidType(mat);
4688   MatPreallocated(mat);
4689   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
4690   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4691   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4692   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4693   ierr = (*mat->ops->iccfactor)(mat,row,fill,level);CHKERRQ(ierr);
4694   PetscFunctionReturn(0);
4695 }
4696 
4697 #undef __FUNCT__
4698 #define __FUNCT__ "MatSetValuesAdic"
4699 /*@
4700    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
4701 
4702    Not Collective
4703 
4704    Input Parameters:
4705 +  mat - the matrix
4706 -  v - the values compute with ADIC
4707 
4708    Level: developer
4709 
4710    Notes:
4711      Must call MatSetColoring() before using this routine. Also this matrix must already
4712      have its nonzero pattern determined.
4713 
4714 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
4715           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
4716 @*/
4717 int MatSetValuesAdic(Mat mat,void *v)
4718 {
4719   int ierr;
4720 
4721   PetscFunctionBegin;
4722   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4723   PetscValidType(mat);
4724 
4725   if (!mat->assembled) {
4726     SETERRQ(1,"Matrix must be already assembled");
4727   }
4728   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
4729   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4730   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
4731   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
4732   ierr = MatView_Private(mat);CHKERRQ(ierr);
4733   PetscFunctionReturn(0);
4734 }
4735 
4736 
4737 #undef __FUNCT__
4738 #define __FUNCT__ "MatSetColoring"
4739 /*@
4740    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
4741 
4742    Not Collective
4743 
4744    Input Parameters:
4745 +  mat - the matrix
4746 -  coloring - the coloring
4747 
4748    Level: developer
4749 
4750 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
4751           MatSetValues(), MatSetValuesAdic()
4752 @*/
4753 int MatSetColoring(Mat mat,ISColoring coloring)
4754 {
4755   int ierr;
4756 
4757   PetscFunctionBegin;
4758   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4759   PetscValidType(mat);
4760 
4761   if (!mat->assembled) {
4762     SETERRQ(1,"Matrix must be already assembled");
4763   }
4764   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4765   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
4766   PetscFunctionReturn(0);
4767 }
4768 
4769 #undef __FUNCT__
4770 #define __FUNCT__ "MatSetValuesAdifor"
4771 /*@
4772    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
4773 
4774    Not Collective
4775 
4776    Input Parameters:
4777 +  mat - the matrix
4778 .  nl - leading dimension of v
4779 -  v - the values compute with ADIFOR
4780 
4781    Level: developer
4782 
4783    Notes:
4784      Must call MatSetColoring() before using this routine. Also this matrix must already
4785      have its nonzero pattern determined.
4786 
4787 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
4788           MatSetValues(), MatSetColoring()
4789 @*/
4790 int MatSetValuesAdifor(Mat mat,int nl,void *v)
4791 {
4792   int ierr;
4793 
4794   PetscFunctionBegin;
4795   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4796   PetscValidType(mat);
4797 
4798   if (!mat->assembled) {
4799     SETERRQ(1,"Matrix must be already assembled");
4800   }
4801   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
4802   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4803   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
4804   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
4805   PetscFunctionReturn(0);
4806 }
4807