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