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