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