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