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