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