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