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