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