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