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