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